diff options
Diffstat (limited to 'security/nss/cmd/lib/secpwd.c')
-rw-r--r-- | security/nss/cmd/lib/secpwd.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/security/nss/cmd/lib/secpwd.c b/security/nss/cmd/lib/secpwd.c new file mode 100644 index 0000000000..472bc2615b --- /dev/null +++ b/security/nss/cmd/lib/secpwd.c @@ -0,0 +1,163 @@ +/* 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> +#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 + +#if !defined(_WINDOWS) +static void +echoOff(int fd) +{ + if (isatty(fd)) { + struct termios tio; + tcgetattr(fd, &tio); + tio.c_lflag &= ~ECHO; + tcsetattr(fd, TCSAFLUSH, &tio); + } +} + +static void +echoOn(int fd) +{ + 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 |