1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/libmar/sign/nss_secutil.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,232 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* With the exception of GetPasswordString, this file was 1.9 + copied from NSS's cmd/lib/secutil.c hg revision 8f011395145e */ 1.10 + 1.11 +#include "nss_secutil.h" 1.12 + 1.13 +#include "prprf.h" 1.14 +#ifdef XP_WIN 1.15 +#include <io.h> 1.16 +#else 1.17 +#include <unistd.h> 1.18 +#endif 1.19 + 1.20 +static char consoleName[] = { 1.21 +#ifdef XP_UNIX 1.22 + "/dev/tty" 1.23 +#else 1.24 + "CON:" 1.25 +#endif 1.26 +}; 1.27 + 1.28 +#if defined(_WINDOWS) 1.29 +static char * quiet_fgets (char *buf, int length, FILE *input) 1.30 +{ 1.31 + int c; 1.32 + char *end = buf; 1.33 + 1.34 + /* fflush (input); */ 1.35 + memset (buf, 0, length); 1.36 + 1.37 + if (!isatty(fileno(input))) { 1.38 + return fgets(buf,length,input); 1.39 + } 1.40 + 1.41 + while (1) 1.42 + { 1.43 +#if defined (_WIN32_WCE) 1.44 + c = getchar(); /* gets a character from stdin */ 1.45 +#else 1.46 + c = getch(); /* getch gets a character from the console */ 1.47 +#endif 1.48 + if (c == '\b') 1.49 + { 1.50 + if (end > buf) 1.51 + end--; 1.52 + } 1.53 + 1.54 + else if (--length > 0) 1.55 + *end++ = c; 1.56 + 1.57 + if (!c || c == '\n' || c == '\r') 1.58 + break; 1.59 + } 1.60 + 1.61 + return buf; 1.62 +} 1.63 +#endif 1.64 + 1.65 +char * 1.66 +GetPasswordString(void *arg, char *prompt) 1.67 +{ 1.68 + FILE *input = stdin; 1.69 + char phrase[200] = {'\0'}; 1.70 + int isInputTerminal = isatty(fileno(stdin)); 1.71 + 1.72 +#ifndef _WINDOWS 1.73 + if (isInputTerminal) { 1.74 + input = fopen(consoleName, "r"); 1.75 + if (input == NULL) { 1.76 + fprintf(stderr, "Error opening input terminal for read\n"); 1.77 + return NULL; 1.78 + } 1.79 + } 1.80 +#endif 1.81 + 1.82 + if (isInputTerminal) { 1.83 + fprintf(stdout, "Please enter your password:\n"); 1.84 + fflush(stdout); 1.85 + } 1.86 + 1.87 + QUIET_FGETS (phrase, sizeof(phrase), input); 1.88 + 1.89 + if (isInputTerminal) { 1.90 + fprintf(stdout, "\n"); 1.91 + } 1.92 + 1.93 +#ifndef _WINDOWS 1.94 + if (isInputTerminal) { 1.95 + fclose(input); 1.96 + } 1.97 +#endif 1.98 + 1.99 + /* Strip off the newlines if present */ 1.100 + if (phrase[PORT_Strlen(phrase)-1] == '\n' || 1.101 + phrase[PORT_Strlen(phrase)-1] == '\r') { 1.102 + phrase[PORT_Strlen(phrase)-1] = 0; 1.103 + } 1.104 + return (char*) PORT_Strdup(phrase); 1.105 +} 1.106 + 1.107 +char * 1.108 +SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) 1.109 +{ 1.110 + char* phrases, *phrase; 1.111 + PRFileDesc *fd; 1.112 + int32_t nb; 1.113 + char *pwFile = arg; 1.114 + int i; 1.115 + const long maxPwdFileSize = 4096; 1.116 + char* tokenName = NULL; 1.117 + int tokenLen = 0; 1.118 + 1.119 + if (!pwFile) 1.120 + return 0; 1.121 + 1.122 + if (retry) { 1.123 + return 0; /* no good retrying - the files contents will be the same */ 1.124 + } 1.125 + 1.126 + phrases = PORT_ZAlloc(maxPwdFileSize); 1.127 + 1.128 + if (!phrases) { 1.129 + return 0; /* out of memory */ 1.130 + } 1.131 + 1.132 + fd = PR_Open(pwFile, PR_RDONLY, 0); 1.133 + if (!fd) { 1.134 + fprintf(stderr, "No password file \"%s\" exists.\n", pwFile); 1.135 + PORT_Free(phrases); 1.136 + return NULL; 1.137 + } 1.138 + 1.139 + nb = PR_Read(fd, phrases, maxPwdFileSize); 1.140 + 1.141 + PR_Close(fd); 1.142 + 1.143 + if (nb == 0) { 1.144 + fprintf(stderr,"password file contains no data\n"); 1.145 + PORT_Free(phrases); 1.146 + return NULL; 1.147 + } 1.148 + 1.149 + if (slot) { 1.150 + tokenName = PK11_GetTokenName(slot); 1.151 + if (tokenName) { 1.152 + tokenLen = PORT_Strlen(tokenName); 1.153 + } 1.154 + } 1.155 + i = 0; 1.156 + do 1.157 + { 1.158 + int startphrase = i; 1.159 + int phraseLen; 1.160 + 1.161 + /* handle the Windows EOL case */ 1.162 + while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++; 1.163 + /* terminate passphrase */ 1.164 + phrases[i++] = '\0'; 1.165 + /* clean up any EOL before the start of the next passphrase */ 1.166 + while ( (i<nb) && (phrases[i] == '\r' || phrases[i] == '\n')) { 1.167 + phrases[i++] = '\0'; 1.168 + } 1.169 + /* now analyze the current passphrase */ 1.170 + phrase = &phrases[startphrase]; 1.171 + if (!tokenName) 1.172 + break; 1.173 + if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue; 1.174 + phraseLen = PORT_Strlen(phrase); 1.175 + if (phraseLen < (tokenLen+1)) continue; 1.176 + if (phrase[tokenLen] != ':') continue; 1.177 + phrase = &phrase[tokenLen+1]; 1.178 + break; 1.179 + 1.180 + } while (i<nb); 1.181 + 1.182 + phrase = PORT_Strdup((char*)phrase); 1.183 + PORT_Free(phrases); 1.184 + return phrase; 1.185 +} 1.186 + 1.187 +char * 1.188 +SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) 1.189 +{ 1.190 + char prompt[255]; 1.191 + secuPWData *pwdata = (secuPWData *)arg; 1.192 + secuPWData pwnull = { PW_NONE, 0 }; 1.193 + secuPWData pwxtrn = { PW_EXTERNAL, "external" }; 1.194 + char *pw; 1.195 + 1.196 + if (pwdata == NULL) 1.197 + pwdata = &pwnull; 1.198 + 1.199 + if (PK11_ProtectedAuthenticationPath(slot)) { 1.200 + pwdata = &pwxtrn; 1.201 + } 1.202 + if (retry && pwdata->source != PW_NONE) { 1.203 + PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n"); 1.204 + return NULL; 1.205 + } 1.206 + 1.207 + switch (pwdata->source) { 1.208 + case PW_NONE: 1.209 + sprintf(prompt, "Enter Password or Pin for \"%s\":", 1.210 + PK11_GetTokenName(slot)); 1.211 + return GetPasswordString(NULL, prompt); 1.212 + case PW_FROMFILE: 1.213 + /* Instead of opening and closing the file every time, get the pw 1.214 + * once, then keep it in memory (duh). 1.215 + */ 1.216 + pw = SECU_FilePasswd(slot, retry, pwdata->data); 1.217 + pwdata->source = PW_PLAINTEXT; 1.218 + pwdata->data = PL_strdup(pw); 1.219 + /* it's already been dup'ed */ 1.220 + return pw; 1.221 + case PW_EXTERNAL: 1.222 + sprintf(prompt, 1.223 + "Press Enter, then enter PIN for \"%s\" on external device.\n", 1.224 + PK11_GetTokenName(slot)); 1.225 + (void) GetPasswordString(NULL, prompt); 1.226 + /* Fall Through */ 1.227 + case PW_PLAINTEXT: 1.228 + return PL_strdup(pwdata->data); 1.229 + default: 1.230 + break; 1.231 + } 1.232 + 1.233 + PR_fprintf(PR_STDERR, "Password check failed: No password found.\n"); 1.234 + return NULL; 1.235 +}