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