modules/libmar/sign/nss_secutil.c

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

mercurial