tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

secpwd.c (3601B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 #include "secutil.h"
      5 
      6 /*
      7 * NOTE:  The contents of this file are NOT used by the client.
      8 * (They are part of the security library as a whole, but they are
      9 * NOT USED BY THE CLIENT.)  Do not change things on behalf of the
     10 * client (like localizing strings), or add things that are only
     11 * for the client (put them elsewhere).
     12 */
     13 
     14 #ifdef XP_UNIX
     15 #include <termios.h>
     16 #include <unistd.h> /* for isatty() */
     17 #endif
     18 
     19 #if defined(_WINDOWS)
     20 #include <conio.h>
     21 #include <io.h>
     22 #define QUIET_FGETS quiet_fgets
     23 static char *quiet_fgets(char *buf, int length, FILE *input);
     24 #else
     25 #define QUIET_FGETS fgets
     26 #endif
     27 
     28 #if !defined(_WINDOWS)
     29 static void
     30 echoOff(int fd)
     31 {
     32    if (isatty(fd)) {
     33        struct termios tio;
     34        tcgetattr(fd, &tio);
     35        tio.c_lflag &= ~ECHO;
     36        tcsetattr(fd, TCSAFLUSH, &tio);
     37    }
     38 }
     39 
     40 static void
     41 echoOn(int fd)
     42 {
     43    if (isatty(fd)) {
     44        struct termios tio;
     45        tcgetattr(fd, &tio);
     46        tio.c_lflag |= ECHO;
     47        tcsetattr(fd, TCSAFLUSH, &tio);
     48    }
     49 }
     50 #endif
     51 
     52 char *
     53 SEC_GetPassword(FILE *input, FILE *output, char *prompt,
     54                PRBool (*ok)(char *))
     55 {
     56 #if defined(_WINDOWS)
     57    int isTTY = (input == stdin);
     58 #define echoOn(x)
     59 #define echoOff(x)
     60 #else
     61    int infd = fileno(input);
     62    int isTTY = isatty(infd);
     63 #endif
     64    char phrase[500] = { '\0' }; /* ensure EOF doesn't return junk */
     65 
     66    for (;;) {
     67        /* Prompt for password */
     68        if (isTTY) {
     69            fprintf(output, "%s", prompt);
     70            fflush(output);
     71            echoOff(infd);
     72        }
     73 
     74        if (QUIET_FGETS(phrase, sizeof(phrase), input) == NULL) {
     75            return NULL;
     76        }
     77 
     78        if (isTTY) {
     79            fprintf(output, "\n");
     80            echoOn(infd);
     81        }
     82 
     83        /* stomp on newline */
     84        phrase[PORT_Strlen(phrase) - 1] = 0;
     85 
     86        /* Validate password */
     87        if (!(*ok)(phrase)) {
     88            /* Not weird enough */
     89            if (!isTTY)
     90                return NULL;
     91            fprintf(output, "Password must be at least 8 characters long with one or more\n");
     92            fprintf(output, "non-alphabetic characters\n");
     93            continue;
     94        }
     95        return (char *)PORT_Strdup(phrase);
     96    }
     97 }
     98 
     99 PRBool
    100 SEC_CheckPassword(char *cp)
    101 {
    102    int len;
    103    char *end;
    104 
    105    len = PORT_Strlen(cp);
    106    if (len < 8) {
    107        return PR_FALSE;
    108    }
    109    end = cp + len;
    110    while (cp < end) {
    111        unsigned char ch = *cp++;
    112        if (!((ch >= 'A') && (ch <= 'Z')) &&
    113            !((ch >= 'a') && (ch <= 'z'))) {
    114            /* pass phrase has at least one non alphabetic in it */
    115            return PR_TRUE;
    116        }
    117    }
    118    return PR_FALSE;
    119 }
    120 
    121 PRBool
    122 SEC_BlindCheckPassword(char *cp)
    123 {
    124    if (cp != NULL) {
    125        return PR_TRUE;
    126    }
    127    return PR_FALSE;
    128 }
    129 
    130 /* Get a password from the input terminal, without echoing */
    131 
    132 #if defined(_WINDOWS)
    133 static char *
    134 quiet_fgets(char *buf, int length, FILE *input)
    135 {
    136    int c;
    137    char *end = buf;
    138 
    139    /* fflush (input); */
    140    memset(buf, 0, length);
    141 
    142    if (!isatty(fileno(input))) {
    143        return fgets(buf, length, input);
    144    }
    145 
    146    while (1) {
    147        c = getch(); /* getch gets a character from the console */
    148 
    149        if (c == '\b') {
    150            if (end > buf)
    151                end--;
    152        }
    153 
    154        else if (--length > 0)
    155            *end++ = c;
    156 
    157        if (!c || c == '\n' || c == '\r')
    158            break;
    159    }
    160 
    161    return buf;
    162 }
    163 #endif