security/nss/cmd/lib/secpwd.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial