modules/libmar/sign/nss_secutil.c

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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
michael@0 5 /* With the exception of GetPasswordString, this file was
michael@0 6 copied from NSS's cmd/lib/secutil.c hg revision 8f011395145e */
michael@0 7
michael@0 8 #include "nss_secutil.h"
michael@0 9
michael@0 10 #include "prprf.h"
michael@0 11 #ifdef XP_WIN
michael@0 12 #include <io.h>
michael@0 13 #else
michael@0 14 #include <unistd.h>
michael@0 15 #endif
michael@0 16
michael@0 17 static char consoleName[] = {
michael@0 18 #ifdef XP_UNIX
michael@0 19 "/dev/tty"
michael@0 20 #else
michael@0 21 "CON:"
michael@0 22 #endif
michael@0 23 };
michael@0 24
michael@0 25 #if defined(_WINDOWS)
michael@0 26 static char * quiet_fgets (char *buf, int length, FILE *input)
michael@0 27 {
michael@0 28 int c;
michael@0 29 char *end = buf;
michael@0 30
michael@0 31 /* fflush (input); */
michael@0 32 memset (buf, 0, length);
michael@0 33
michael@0 34 if (!isatty(fileno(input))) {
michael@0 35 return fgets(buf,length,input);
michael@0 36 }
michael@0 37
michael@0 38 while (1)
michael@0 39 {
michael@0 40 #if defined (_WIN32_WCE)
michael@0 41 c = getchar(); /* gets a character from stdin */
michael@0 42 #else
michael@0 43 c = getch(); /* getch gets a character from the console */
michael@0 44 #endif
michael@0 45 if (c == '\b')
michael@0 46 {
michael@0 47 if (end > buf)
michael@0 48 end--;
michael@0 49 }
michael@0 50
michael@0 51 else if (--length > 0)
michael@0 52 *end++ = c;
michael@0 53
michael@0 54 if (!c || c == '\n' || c == '\r')
michael@0 55 break;
michael@0 56 }
michael@0 57
michael@0 58 return buf;
michael@0 59 }
michael@0 60 #endif
michael@0 61
michael@0 62 char *
michael@0 63 GetPasswordString(void *arg, char *prompt)
michael@0 64 {
michael@0 65 FILE *input = stdin;
michael@0 66 char phrase[200] = {'\0'};
michael@0 67 int isInputTerminal = isatty(fileno(stdin));
michael@0 68
michael@0 69 #ifndef _WINDOWS
michael@0 70 if (isInputTerminal) {
michael@0 71 input = fopen(consoleName, "r");
michael@0 72 if (input == NULL) {
michael@0 73 fprintf(stderr, "Error opening input terminal for read\n");
michael@0 74 return NULL;
michael@0 75 }
michael@0 76 }
michael@0 77 #endif
michael@0 78
michael@0 79 if (isInputTerminal) {
michael@0 80 fprintf(stdout, "Please enter your password:\n");
michael@0 81 fflush(stdout);
michael@0 82 }
michael@0 83
michael@0 84 QUIET_FGETS (phrase, sizeof(phrase), input);
michael@0 85
michael@0 86 if (isInputTerminal) {
michael@0 87 fprintf(stdout, "\n");
michael@0 88 }
michael@0 89
michael@0 90 #ifndef _WINDOWS
michael@0 91 if (isInputTerminal) {
michael@0 92 fclose(input);
michael@0 93 }
michael@0 94 #endif
michael@0 95
michael@0 96 /* Strip off the newlines if present */
michael@0 97 if (phrase[PORT_Strlen(phrase)-1] == '\n' ||
michael@0 98 phrase[PORT_Strlen(phrase)-1] == '\r') {
michael@0 99 phrase[PORT_Strlen(phrase)-1] = 0;
michael@0 100 }
michael@0 101 return (char*) PORT_Strdup(phrase);
michael@0 102 }
michael@0 103
michael@0 104 char *
michael@0 105 SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
michael@0 106 {
michael@0 107 char* phrases, *phrase;
michael@0 108 PRFileDesc *fd;
michael@0 109 int32_t nb;
michael@0 110 char *pwFile = arg;
michael@0 111 int i;
michael@0 112 const long maxPwdFileSize = 4096;
michael@0 113 char* tokenName = NULL;
michael@0 114 int tokenLen = 0;
michael@0 115
michael@0 116 if (!pwFile)
michael@0 117 return 0;
michael@0 118
michael@0 119 if (retry) {
michael@0 120 return 0; /* no good retrying - the files contents will be the same */
michael@0 121 }
michael@0 122
michael@0 123 phrases = PORT_ZAlloc(maxPwdFileSize);
michael@0 124
michael@0 125 if (!phrases) {
michael@0 126 return 0; /* out of memory */
michael@0 127 }
michael@0 128
michael@0 129 fd = PR_Open(pwFile, PR_RDONLY, 0);
michael@0 130 if (!fd) {
michael@0 131 fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
michael@0 132 PORT_Free(phrases);
michael@0 133 return NULL;
michael@0 134 }
michael@0 135
michael@0 136 nb = PR_Read(fd, phrases, maxPwdFileSize);
michael@0 137
michael@0 138 PR_Close(fd);
michael@0 139
michael@0 140 if (nb == 0) {
michael@0 141 fprintf(stderr,"password file contains no data\n");
michael@0 142 PORT_Free(phrases);
michael@0 143 return NULL;
michael@0 144 }
michael@0 145
michael@0 146 if (slot) {
michael@0 147 tokenName = PK11_GetTokenName(slot);
michael@0 148 if (tokenName) {
michael@0 149 tokenLen = PORT_Strlen(tokenName);
michael@0 150 }
michael@0 151 }
michael@0 152 i = 0;
michael@0 153 do
michael@0 154 {
michael@0 155 int startphrase = i;
michael@0 156 int phraseLen;
michael@0 157
michael@0 158 /* handle the Windows EOL case */
michael@0 159 while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++;
michael@0 160 /* terminate passphrase */
michael@0 161 phrases[i++] = '\0';
michael@0 162 /* clean up any EOL before the start of the next passphrase */
michael@0 163 while ( (i<nb) && (phrases[i] == '\r' || phrases[i] == '\n')) {
michael@0 164 phrases[i++] = '\0';
michael@0 165 }
michael@0 166 /* now analyze the current passphrase */
michael@0 167 phrase = &phrases[startphrase];
michael@0 168 if (!tokenName)
michael@0 169 break;
michael@0 170 if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue;
michael@0 171 phraseLen = PORT_Strlen(phrase);
michael@0 172 if (phraseLen < (tokenLen+1)) continue;
michael@0 173 if (phrase[tokenLen] != ':') continue;
michael@0 174 phrase = &phrase[tokenLen+1];
michael@0 175 break;
michael@0 176
michael@0 177 } while (i<nb);
michael@0 178
michael@0 179 phrase = PORT_Strdup((char*)phrase);
michael@0 180 PORT_Free(phrases);
michael@0 181 return phrase;
michael@0 182 }
michael@0 183
michael@0 184 char *
michael@0 185 SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)
michael@0 186 {
michael@0 187 char prompt[255];
michael@0 188 secuPWData *pwdata = (secuPWData *)arg;
michael@0 189 secuPWData pwnull = { PW_NONE, 0 };
michael@0 190 secuPWData pwxtrn = { PW_EXTERNAL, "external" };
michael@0 191 char *pw;
michael@0 192
michael@0 193 if (pwdata == NULL)
michael@0 194 pwdata = &pwnull;
michael@0 195
michael@0 196 if (PK11_ProtectedAuthenticationPath(slot)) {
michael@0 197 pwdata = &pwxtrn;
michael@0 198 }
michael@0 199 if (retry && pwdata->source != PW_NONE) {
michael@0 200 PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
michael@0 201 return NULL;
michael@0 202 }
michael@0 203
michael@0 204 switch (pwdata->source) {
michael@0 205 case PW_NONE:
michael@0 206 sprintf(prompt, "Enter Password or Pin for \"%s\":",
michael@0 207 PK11_GetTokenName(slot));
michael@0 208 return GetPasswordString(NULL, prompt);
michael@0 209 case PW_FROMFILE:
michael@0 210 /* Instead of opening and closing the file every time, get the pw
michael@0 211 * once, then keep it in memory (duh).
michael@0 212 */
michael@0 213 pw = SECU_FilePasswd(slot, retry, pwdata->data);
michael@0 214 pwdata->source = PW_PLAINTEXT;
michael@0 215 pwdata->data = PL_strdup(pw);
michael@0 216 /* it's already been dup'ed */
michael@0 217 return pw;
michael@0 218 case PW_EXTERNAL:
michael@0 219 sprintf(prompt,
michael@0 220 "Press Enter, then enter PIN for \"%s\" on external device.\n",
michael@0 221 PK11_GetTokenName(slot));
michael@0 222 (void) GetPasswordString(NULL, prompt);
michael@0 223 /* Fall Through */
michael@0 224 case PW_PLAINTEXT:
michael@0 225 return PL_strdup(pwdata->data);
michael@0 226 default:
michael@0 227 break;
michael@0 228 }
michael@0 229
michael@0 230 PR_fprintf(PR_STDERR, "Password check failed: No password found.\n");
michael@0 231 return NULL;
michael@0 232 }

mercurial