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