| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| #include "secutil.h" |
| |
| /* |
| * NOTE: The contents of this file are NOT used by the client. |
| * (They are part of the security library as a whole, but they are |
| * NOT USED BY THE CLIENT.) Do not change things on behalf of the |
| * client (like localizing strings), or add things that are only |
| * for the client (put them elsewhere). |
| */ |
| |
| #ifdef XP_UNIX |
| #include <termios.h> |
| #endif |
| |
| #if defined(XP_UNIX) || defined(XP_BEOS) |
| #include <unistd.h> /* for isatty() */ |
| #endif |
| |
| #if defined(_WINDOWS) |
| #include <conio.h> |
| #include <io.h> |
| #define QUIET_FGETS quiet_fgets |
| static char *quiet_fgets(char *buf, int length, FILE *input); |
| #else |
| #define QUIET_FGETS fgets |
| #endif |
| |
| static void |
| echoOff(int fd) |
| { |
| #if defined(XP_UNIX) |
| if (isatty(fd)) { |
| struct termios tio; |
| tcgetattr(fd, &tio); |
| tio.c_lflag &= ~ECHO; |
| tcsetattr(fd, TCSAFLUSH, &tio); |
| } |
| #endif |
| } |
| |
| static void |
| echoOn(int fd) |
| { |
| #if defined(XP_UNIX) |
| if (isatty(fd)) { |
| struct termios tio; |
| tcgetattr(fd, &tio); |
| tio.c_lflag |= ECHO; |
| tcsetattr(fd, TCSAFLUSH, &tio); |
| } |
| #endif |
| } |
| |
| char * |
| SEC_GetPassword(FILE *input, FILE *output, char *prompt, |
| PRBool (*ok)(char *)) |
| { |
| #if defined(_WINDOWS) |
| int isTTY = (input == stdin); |
| #define echoOn(x) |
| #define echoOff(x) |
| #else |
| int infd = fileno(input); |
| int isTTY = isatty(infd); |
| #endif |
| char phrase[500] = { '\0' }; /* ensure EOF doesn't return junk */ |
| |
| for (;;) { |
| /* Prompt for password */ |
| if (isTTY) { |
| fprintf(output, "%s", prompt); |
| fflush(output); |
| echoOff(infd); |
| } |
| |
| if (QUIET_FGETS(phrase, sizeof(phrase), input) == NULL) { |
| return NULL; |
| } |
| |
| if (isTTY) { |
| fprintf(output, "\n"); |
| echoOn(infd); |
| } |
| |
| /* stomp on newline */ |
| phrase[PORT_Strlen(phrase) - 1] = 0; |
| |
| /* Validate password */ |
| if (!(*ok)(phrase)) { |
| /* Not weird enough */ |
| if (!isTTY) |
| return NULL; |
| fprintf(output, "Password must be at least 8 characters long with one or more\n"); |
| fprintf(output, "non-alphabetic characters\n"); |
| continue; |
| } |
| return (char *)PORT_Strdup(phrase); |
| } |
| } |
| |
| PRBool |
| SEC_CheckPassword(char *cp) |
| { |
| int len; |
| char *end; |
| |
| len = PORT_Strlen(cp); |
| if (len < 8) { |
| return PR_FALSE; |
| } |
| end = cp + len; |
| while (cp < end) { |
| unsigned char ch = *cp++; |
| if (!((ch >= 'A') && (ch <= 'Z')) && |
| !((ch >= 'a') && (ch <= 'z'))) { |
| /* pass phrase has at least one non alphabetic in it */ |
| return PR_TRUE; |
| } |
| } |
| return PR_FALSE; |
| } |
| |
| PRBool |
| SEC_BlindCheckPassword(char *cp) |
| { |
| if (cp != NULL) { |
| return PR_TRUE; |
| } |
| return PR_FALSE; |
| } |
| |
| /* Get a password from the input terminal, without echoing */ |
| |
| #if defined(_WINDOWS) |
| static char * |
| quiet_fgets(char *buf, int length, FILE *input) |
| { |
| int c; |
| char *end = buf; |
| |
| /* fflush (input); */ |
| memset(buf, 0, length); |
| |
| if (!isatty(fileno(input))) { |
| return fgets(buf, length, input); |
| } |
| |
| while (1) { |
| c = getch(); /* getch gets a character from the console */ |
| |
| if (c == '\b') { |
| if (end > buf) |
| end--; |
| } |
| |
| else if (--length > 0) |
| *end++ = c; |
| |
| if (!c || c == '\n' || c == '\r') |
| break; |
| } |
| |
| return buf; |
| } |
| #endif |