File: | s/cmd/modutil/pk11.c |
Warning: | line 207, column 5 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | /* To edit this file, set TABSTOPS to 4 spaces. | |||
6 | * This is not the normal NSS convention. | |||
7 | */ | |||
8 | ||||
9 | #include "modutil.h" | |||
10 | #include "pk11func.h" | |||
11 | ||||
12 | /************************************************************************* | |||
13 | * | |||
14 | * F i p s M o d e | |||
15 | * If arg=="true", enable FIPS mode on the internal module. If arg=="false", | |||
16 | * disable FIPS mode on the internal module. | |||
17 | */ | |||
18 | Error | |||
19 | FipsMode(char *arg) | |||
20 | { | |||
21 | char *internal_name; | |||
22 | ||||
23 | if (!PORT_StrcasecmpPL_strcasecmp(arg, "true")) { | |||
24 | if (!PK11_IsFIPS()) { | |||
25 | internal_name = PR_smprintf("%s", | |||
26 | SECMOD_GetInternalModule()->commonName); | |||
27 | if (SECMOD_DeleteInternalModule(internal_name) != SECSuccess) { | |||
28 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s\n", SECU_Strerror(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0)); | |||
29 | PR_smprintf_free(internal_name); | |||
30 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[FIPS_SWITCH_FAILED_ERR]); | |||
31 | return FIPS_SWITCH_FAILED_ERR; | |||
32 | } | |||
33 | PR_smprintf_free(internal_name); | |||
34 | if (!PK11_IsFIPS()) { | |||
35 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[FIPS_SWITCH_FAILED_ERR]); | |||
36 | return FIPS_SWITCH_FAILED_ERR; | |||
37 | } | |||
38 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[FIPS_ENABLED_MSG]); | |||
39 | } else { | |||
40 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[FIPS_ALREADY_ON_ERR]); | |||
41 | return FIPS_ALREADY_ON_ERR; | |||
42 | } | |||
43 | } else if (!PORT_StrcasecmpPL_strcasecmp(arg, "false")) { | |||
44 | if (PK11_IsFIPS()) { | |||
45 | internal_name = PR_smprintf("%s", | |||
46 | SECMOD_GetInternalModule()->commonName); | |||
47 | if (SECMOD_DeleteInternalModule(internal_name) != SECSuccess) { | |||
48 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s\n", SECU_Strerror(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0)); | |||
49 | PR_smprintf_free(internal_name); | |||
50 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[FIPS_SWITCH_FAILED_ERR]); | |||
51 | return FIPS_SWITCH_FAILED_ERR; | |||
52 | } | |||
53 | PR_smprintf_free(internal_name); | |||
54 | if (PK11_IsFIPS()) { | |||
55 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[FIPS_SWITCH_FAILED_ERR]); | |||
56 | return FIPS_SWITCH_FAILED_ERR; | |||
57 | } | |||
58 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[FIPS_DISABLED_MSG]); | |||
59 | } else { | |||
60 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[FIPS_ALREADY_OFF_ERR]); | |||
61 | return FIPS_ALREADY_OFF_ERR; | |||
62 | } | |||
63 | } else { | |||
64 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[INVALID_FIPS_ARG]); | |||
65 | return INVALID_FIPS_ARG; | |||
66 | } | |||
67 | ||||
68 | return SUCCESSNO_ERR; | |||
69 | } | |||
70 | ||||
71 | /************************************************************************* | |||
72 | * | |||
73 | * C h k F i p s M o d e | |||
74 | * If arg=="true", verify FIPS mode is enabled on the internal module. | |||
75 | * If arg=="false", verify FIPS mode is disabled on the internal module. | |||
76 | */ | |||
77 | Error | |||
78 | ChkFipsMode(char *arg) | |||
79 | { | |||
80 | if (!PORT_StrcasecmpPL_strcasecmp(arg, "true")) { | |||
81 | if (PK11_IsFIPS()) { | |||
82 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[FIPS_ENABLED_MSG]); | |||
83 | } else { | |||
84 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[FIPS_DISABLED_MSG]); | |||
85 | return FIPS_SWITCH_FAILED_ERR; | |||
86 | } | |||
87 | ||||
88 | } else if (!PORT_StrcasecmpPL_strcasecmp(arg, "false")) { | |||
89 | if (!PK11_IsFIPS()) { | |||
90 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[FIPS_DISABLED_MSG]); | |||
91 | } else { | |||
92 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[FIPS_ENABLED_MSG]); | |||
93 | return FIPS_SWITCH_FAILED_ERR; | |||
94 | } | |||
95 | } else { | |||
96 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[INVALID_FIPS_ARG]); | |||
97 | return INVALID_FIPS_ARG; | |||
98 | } | |||
99 | ||||
100 | return SUCCESSNO_ERR; | |||
101 | } | |||
102 | ||||
103 | /************************************************************************ | |||
104 | * Cipher and Mechanism name-bitmask translation tables | |||
105 | */ | |||
106 | ||||
107 | typedef struct { | |||
108 | const char *name; | |||
109 | unsigned long mask; | |||
110 | } MaskString; | |||
111 | ||||
112 | static const MaskString cipherStrings[] = { | |||
113 | { "FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG0x00000001ul } | |||
114 | }; | |||
115 | static const int numCipherStrings = | |||
116 | sizeof(cipherStrings) / sizeof(cipherStrings[0]); | |||
117 | ||||
118 | /* Initialized by LoadMechanismList */ | |||
119 | static MaskString *mechanismStrings = NULL((void*)0); | |||
120 | static int numMechanismStrings = 0; | |||
121 | const static PK11DefaultArrayEntry *pk11_DefaultArray = NULL((void*)0); | |||
122 | static int pk11_DefaultArraySize = 0; | |||
123 | ||||
124 | /* Maximum length of a colon-separated list of all the strings in an | |||
125 | * array. */ | |||
126 | #define MAX_STRING_LIST_LEN240 240 /* or less */ | |||
127 | ||||
128 | Error | |||
129 | LoadMechanismList(void) | |||
130 | { | |||
131 | int i; | |||
132 | ||||
133 | if (pk11_DefaultArray == NULL((void*)0)) { | |||
134 | pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize); | |||
135 | if (pk11_DefaultArray == NULL((void*)0)) { | |||
136 | /* should assert. This shouldn't happen */ | |||
137 | return UNSPECIFIED_ERR; | |||
138 | } | |||
139 | } | |||
140 | if (mechanismStrings != NULL((void*)0)) { | |||
141 | return SUCCESSNO_ERR; | |||
142 | } | |||
143 | ||||
144 | /* build the mechanismStrings array */ | |||
145 | mechanismStrings = PORT_NewArray(MaskString, pk11_DefaultArraySize)(MaskString *)PORT_Alloc_Util(sizeof(MaskString) * (pk11_DefaultArraySize )); | |||
146 | if (mechanismStrings == NULL((void*)0)) { | |||
147 | return OUT_OF_MEM_ERR; | |||
148 | } | |||
149 | numMechanismStrings = pk11_DefaultArraySize; | |||
150 | for (i = 0; i < numMechanismStrings; i++) { | |||
151 | const char *name = pk11_DefaultArray[i].name; | |||
152 | unsigned long flag = pk11_DefaultArray[i].flag; | |||
153 | /* map new name to old */ | |||
154 | switch (flag) { | |||
155 | case SECMOD_FORTEZZA_FLAG0x00000040L: | |||
156 | name = "FORTEZZA"; | |||
157 | break; | |||
158 | case SECMOD_SHA1_FLAG0x00000100L: | |||
159 | name = "SHA1"; | |||
160 | break; | |||
161 | case SECMOD_CAMELLIA_FLAG0x00010000L: | |||
162 | name = "CAMELLIA"; | |||
163 | break; | |||
164 | case SECMOD_RANDOM_FLAG0x80000000L: | |||
165 | name = "RANDOM"; | |||
166 | break; | |||
167 | case SECMOD_FRIENDLY_FLAG0x10000000L: | |||
168 | name = "FRIENDLY"; | |||
169 | break; | |||
170 | default: | |||
171 | break; | |||
172 | } | |||
173 | mechanismStrings[i].name = name; | |||
174 | mechanismStrings[i].mask = SECMOD_InternaltoPubMechFlags(flag); | |||
175 | } | |||
176 | return SUCCESSNO_ERR; | |||
177 | } | |||
178 | ||||
179 | /************************************************************************ | |||
180 | * | |||
181 | * g e t F l a g s F r o m S t r i n g | |||
182 | * | |||
183 | * Parses a mechanism list passed on the command line and converts it | |||
184 | * to an unsigned long bitmask. | |||
185 | * string is a colon-separated string of constants | |||
186 | * array is an array of MaskStrings. | |||
187 | * elements is the number of elements in array. | |||
188 | */ | |||
189 | static unsigned long | |||
190 | getFlagsFromString(char *string, const MaskString array[], int elements) | |||
191 | { | |||
192 | unsigned long ret = 0; | |||
193 | short i = 0; | |||
194 | char *cp; | |||
195 | char *buf; | |||
196 | char *end; | |||
197 | ||||
198 | if (!string || !string[0]) { | |||
199 | return ret; | |||
200 | } | |||
201 | ||||
202 | /* Make a temporary copy of the string */ | |||
203 | buf = PR_Malloc(strlen(string) + 1); | |||
204 | if (!buf) { | |||
205 | out_of_memory(); | |||
206 | } | |||
207 | strcpy(buf, string); | |||
| ||||
208 | ||||
209 | /* Look at each element of the list passed in */ | |||
210 | for (cp = buf; cp && *cp; cp = (end ? end + 1 : NULL((void*)0))) { | |||
211 | /* Look at the string up to the next colon */ | |||
212 | end = strchr(cp, ':'); | |||
213 | if (end) { | |||
214 | *end = '\0'; | |||
215 | } | |||
216 | ||||
217 | /* Find which element this is */ | |||
218 | for (i = 0; i < elements; i++) { | |||
219 | if (!PORT_StrcasecmpPL_strcasecmp(cp, array[i].name)) { | |||
220 | break; | |||
221 | } | |||
222 | } | |||
223 | if (i == elements) { | |||
224 | /* Skip a bogus string, but print a warning message */ | |||
225 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[INVALID_CONSTANT_ERR], cp); | |||
226 | continue; | |||
227 | } | |||
228 | ret |= array[i].mask; | |||
229 | } | |||
230 | ||||
231 | PR_Free(buf); | |||
232 | return ret; | |||
233 | } | |||
234 | ||||
235 | /********************************************************************** | |||
236 | * | |||
237 | * g e t S t r i n g F r o m F l a g s | |||
238 | * | |||
239 | * The return string's memory is owned by this function. Copy it | |||
240 | * if you need it permanently or you want to change it. | |||
241 | */ | |||
242 | static char * | |||
243 | getStringFromFlags(unsigned long flags, const MaskString array[], int elements) | |||
244 | { | |||
245 | static char buf[MAX_STRING_LIST_LEN240]; | |||
246 | int i; | |||
247 | int count = 0; | |||
248 | ||||
249 | buf[0] = '\0'; | |||
250 | for (i = 0; i < elements; i++) { | |||
251 | if (flags & array[i].mask) { | |||
252 | ++count; | |||
253 | if (count != 1) { | |||
254 | strcat(buf, ":"); | |||
255 | } | |||
256 | strcat(buf, array[i].name); | |||
257 | } | |||
258 | } | |||
259 | return buf; | |||
260 | } | |||
261 | ||||
262 | static PRBool | |||
263 | IsP11KitProxyModule(SECMODModule *module) | |||
264 | { | |||
265 | CK_INFO modinfo; | |||
266 | static const char p11KitManufacturerID[33] = | |||
267 | "PKCS#11 Kit "; | |||
268 | static const char p11KitLibraryDescription[33] = | |||
269 | "PKCS#11 Kit Proxy Module "; | |||
270 | ||||
271 | if (PK11_GetModInfo(module, &modinfo) == SECSuccess && | |||
272 | PORT_Memcmpmemcmp(modinfo.manufacturerID, | |||
273 | p11KitManufacturerID, | |||
274 | sizeof(modinfo.manufacturerID)) == 0 && | |||
275 | PORT_Memcmpmemcmp(modinfo.libraryDescription, | |||
276 | p11KitLibraryDescription, | |||
277 | sizeof(modinfo.libraryDescription)) == 0) { | |||
278 | return PR_TRUE1; | |||
279 | } | |||
280 | ||||
281 | return PR_FALSE0; | |||
282 | } | |||
283 | ||||
284 | PRBool | |||
285 | IsP11KitEnabled(void) | |||
286 | { | |||
287 | SECMODListLock *lock; | |||
288 | SECMODModuleList *mlp; | |||
289 | PRBool found = PR_FALSE0; | |||
290 | ||||
291 | lock = SECMOD_GetDefaultModuleListLock(); | |||
292 | if (!lock) { | |||
293 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_LIST_LOCK_ERR]); | |||
294 | return found; | |||
295 | } | |||
296 | ||||
297 | SECMOD_GetReadLock(lock); | |||
298 | ||||
299 | mlp = SECMOD_GetDefaultModuleList(); | |||
300 | for (; mlp != NULL((void*)0); mlp = mlp->next) { | |||
301 | if (IsP11KitProxyModule(mlp->module)) { | |||
302 | found = PR_TRUE1; | |||
303 | break; | |||
304 | } | |||
305 | } | |||
306 | ||||
307 | SECMOD_ReleaseReadLock(lock); | |||
308 | return found; | |||
309 | } | |||
310 | ||||
311 | /********************************************************************** | |||
312 | * | |||
313 | * A d d M o d u l e | |||
314 | * | |||
315 | * Add the named module, with the given library file, ciphers, and | |||
316 | * default mechanism flags | |||
317 | */ | |||
318 | Error | |||
319 | AddModule(char *moduleName, char *libFile, char *cipherString, | |||
320 | char *mechanismString, char *modparms) | |||
321 | { | |||
322 | unsigned long ciphers; | |||
323 | unsigned long mechanisms; | |||
324 | SECStatus status; | |||
325 | ||||
326 | mechanisms = | |||
327 | getFlagsFromString(mechanismString, mechanismStrings, | |||
328 | numMechanismStrings); | |||
329 | ciphers = | |||
330 | getFlagsFromString(cipherString, cipherStrings, numCipherStrings); | |||
331 | ||||
332 | status = | |||
333 | SECMOD_AddNewModuleEx(moduleName, libFile, | |||
334 | SECMOD_PubMechFlagstoInternal(mechanisms), | |||
335 | SECMOD_PubCipherFlagstoInternal(ciphers), | |||
336 | modparms, NULL((void*)0)); | |||
337 | ||||
338 | if (status != SECSuccess) { | |||
339 | char *errtxt = NULL((void*)0); | |||
340 | PRInt32 copied = 0; | |||
341 | if (PR_GetErrorTextLength()) { | |||
342 | errtxt = PR_Malloc(PR_GetErrorTextLength() + 1); | |||
343 | copied = PR_GetErrorText(errtxt); | |||
344 | } | |||
345 | if (copied && errtxt) { | |||
346 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[ADD_MODULE_FAILED_ERR], | |||
347 | moduleName, errtxt); | |||
348 | PR_Free(errtxt); | |||
349 | } else { | |||
350 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[ADD_MODULE_FAILED_ERR], | |||
351 | moduleName, SECU_Strerror(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0)); | |||
352 | } | |||
353 | return ADD_MODULE_FAILED_ERR; | |||
354 | } else { | |||
355 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[ADD_MODULE_SUCCESS_MSG], moduleName); | |||
356 | return SUCCESSNO_ERR; | |||
357 | } | |||
358 | } | |||
359 | ||||
360 | /*********************************************************************** | |||
361 | * | |||
362 | * D e l e t e M o d u l e | |||
363 | * | |||
364 | * Deletes the named module from the database. | |||
365 | */ | |||
366 | Error | |||
367 | DeleteModule(char *moduleName) | |||
368 | { | |||
369 | SECStatus status; | |||
370 | int type; | |||
371 | ||||
372 | status = SECMOD_DeleteModule(moduleName, &type); | |||
373 | ||||
374 | if (status != SECSuccess) { | |||
375 | if (type == SECMOD_FIPS2 || type == SECMOD_INTERNAL1) { | |||
376 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[DELETE_INTERNAL_ERR]); | |||
377 | return DELETE_INTERNAL_ERR; | |||
378 | } else { | |||
379 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[DELETE_FAILED_ERR], moduleName); | |||
380 | return DELETE_FAILED_ERR; | |||
381 | } | |||
382 | } | |||
383 | ||||
384 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[DELETE_SUCCESS_MSG], moduleName); | |||
385 | return SUCCESSNO_ERR; | |||
386 | } | |||
387 | ||||
388 | /************************************************************************ | |||
389 | * | |||
390 | * R a w L i s t M o d u l e s | |||
391 | * | |||
392 | * Lists all the modules in the database, along with their slots and tokens. | |||
393 | */ | |||
394 | Error | |||
395 | RawListModule(char *modulespec) | |||
396 | { | |||
397 | SECMODModule *module; | |||
398 | char **moduleSpecList; | |||
399 | ||||
400 | module = SECMOD_LoadModule(modulespec, NULL((void*)0), PR_FALSE0); | |||
401 | if (module == NULL((void*)0)) { | |||
402 | /* handle error */ | |||
403 | return NO_SUCH_MODULE_ERR; | |||
404 | } | |||
405 | ||||
406 | moduleSpecList = SECMOD_GetModuleSpecList(module); | |||
407 | if (!moduleSpecList || !moduleSpecList[0]) { | |||
408 | SECU_PrintError("modutil", | |||
409 | "no specs in secmod DB"); | |||
410 | return NO_SUCH_MODULE_ERR; | |||
411 | } | |||
412 | ||||
413 | for (; *moduleSpecList; moduleSpecList++) { | |||
414 | printf("%s\n\n", *moduleSpecList); | |||
415 | } | |||
416 | ||||
417 | return SUCCESSNO_ERR; | |||
418 | } | |||
419 | ||||
420 | Error | |||
421 | RawAddModule(char *dbmodulespec, char *modulespec) | |||
422 | { | |||
423 | SECMODModule *module; | |||
424 | SECMODModule *dbmodule; | |||
425 | ||||
426 | dbmodule = SECMOD_LoadModule(dbmodulespec, NULL((void*)0), PR_TRUE1); | |||
427 | if (dbmodule == NULL((void*)0)) { | |||
428 | /* handle error */ | |||
429 | return NO_SUCH_MODULE_ERR; | |||
430 | } | |||
431 | ||||
432 | module = SECMOD_LoadModule(modulespec, dbmodule, PR_FALSE0); | |||
433 | if (module == NULL((void*)0)) { | |||
434 | /* handle error */ | |||
435 | return NO_SUCH_MODULE_ERR; | |||
436 | } | |||
437 | ||||
438 | if (SECMOD_UpdateModule(module) != SECSuccess) { | |||
439 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[UPDATE_MOD_FAILED_ERR], modulespec); | |||
440 | return UPDATE_MOD_FAILED_ERR; | |||
441 | } | |||
442 | return SUCCESSNO_ERR; | |||
443 | } | |||
444 | ||||
445 | static void | |||
446 | printModule(SECMODModule *module, int *count) | |||
447 | { | |||
448 | int slotCount = module->loaded ? module->slotCount : 0; | |||
449 | char *modUri; | |||
450 | int i; | |||
451 | ||||
452 | if ((*count)++) { | |||
453 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\n"); | |||
454 | } | |||
455 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "%3d. %s\n", *count, module->commonName); | |||
456 | ||||
457 | if (module->dllName) { | |||
458 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\tlibrary name: %s\n", module->dllName); | |||
459 | } | |||
460 | ||||
461 | modUri = PK11_GetModuleURI(module); | |||
462 | if (modUri) { | |||
463 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\t uri: %s\n", modUri); | |||
464 | PORT_FreePORT_Free_Util(modUri); | |||
465 | } | |||
466 | if (slotCount == 0) { | |||
467 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), | |||
468 | "\t slots: There are no slots attached to this module\n"); | |||
469 | } else { | |||
470 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\t slots: %d slot%s attached\n", | |||
471 | slotCount, (slotCount == 1 ? "" : "s")); | |||
472 | } | |||
473 | ||||
474 | if (module->loaded == 0) { | |||
475 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\tstatus: Not loaded\n"); | |||
476 | } else { | |||
477 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\tstatus: loaded\n"); | |||
478 | } | |||
479 | ||||
480 | /* Print slot and token names */ | |||
481 | for (i = 0; i < slotCount; i++) { | |||
482 | PK11SlotInfo *slot = module->slots[i]; | |||
483 | char *tokenUri = PK11_GetTokenURI(slot); | |||
484 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\n"); | |||
485 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\t slot: %s\n", PK11_GetSlotName(slot)); | |||
486 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\ttoken: %s\n", PK11_GetTokenName(slot)); | |||
487 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\t uri: %s\n", tokenUri); | |||
488 | PORT_FreePORT_Free_Util(tokenUri); | |||
489 | } | |||
490 | return; | |||
491 | } | |||
492 | ||||
493 | /************************************************************************ | |||
494 | * | |||
495 | * L i s t M o d u l e s | |||
496 | * | |||
497 | * Lists all the modules in the database, along with their slots and tokens. | |||
498 | */ | |||
499 | Error | |||
500 | ListModules() | |||
501 | { | |||
502 | SECMODListLock *lock; | |||
503 | SECMODModuleList *list; | |||
504 | SECMODModuleList *deadlist; | |||
505 | SECMODModuleList *mlp; | |||
506 | Error ret = UNSPECIFIED_ERR; | |||
507 | int count = 0; | |||
508 | ||||
509 | lock = SECMOD_GetDefaultModuleListLock(); | |||
510 | if (!lock) { | |||
511 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_LIST_LOCK_ERR]); | |||
512 | return NO_LIST_LOCK_ERR; | |||
513 | } | |||
514 | ||||
515 | SECMOD_GetReadLock(lock); | |||
516 | ||||
517 | list = SECMOD_GetDefaultModuleList(); | |||
518 | deadlist = SECMOD_GetDeadModuleList(); | |||
519 | if (!list && !deadlist) { | |||
520 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_MODULE_LIST_ERR]); | |||
521 | ret = NO_MODULE_LIST_ERR; | |||
522 | goto loser; | |||
523 | } | |||
524 | ||||
525 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), | |||
526 | "\nListing of PKCS #11 Modules\n" | |||
527 | "-----------------------------------------------------------\n"); | |||
528 | ||||
529 | for (mlp = list; mlp != NULL((void*)0); mlp = mlp->next) { | |||
530 | printModule(mlp->module, &count); | |||
531 | } | |||
532 | for (mlp = deadlist; mlp != NULL((void*)0); mlp = mlp->next) { | |||
533 | printModule(mlp->module, &count); | |||
534 | } | |||
535 | ||||
536 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), | |||
537 | "-----------------------------------------------------------\n"); | |||
538 | ||||
539 | ret = SUCCESSNO_ERR; | |||
540 | ||||
541 | loser: | |||
542 | SECMOD_ReleaseReadLock(lock); | |||
543 | return ret; | |||
544 | } | |||
545 | ||||
546 | /* Strings describing PK11DisableReasons */ | |||
547 | static char *disableReasonStr[] = { | |||
548 | "no reason", | |||
549 | "user disabled", | |||
550 | "could not initialize token", | |||
551 | "could not verify token", | |||
552 | "token not present" | |||
553 | }; | |||
554 | static size_t numDisableReasonStr = | |||
555 | sizeof(disableReasonStr) / sizeof(disableReasonStr[0]); | |||
556 | ||||
557 | /*********************************************************************** | |||
558 | * | |||
559 | * L i s t M o d u l e | |||
560 | * | |||
561 | * Lists detailed information about the named module. | |||
562 | */ | |||
563 | Error | |||
564 | ListModule(char *moduleName) | |||
565 | { | |||
566 | SECMODModule *module = NULL((void*)0); | |||
567 | PK11SlotInfo *slot; | |||
568 | int slotnum; | |||
569 | CK_INFO modinfo; | |||
570 | CK_SLOT_INFO slotinfo; | |||
571 | CK_TOKEN_INFO tokeninfo; | |||
572 | char *ciphers, *mechanisms; | |||
573 | size_t reasonIdx; | |||
574 | Error rv = SUCCESSNO_ERR; | |||
575 | ||||
576 | if (!moduleName) { | |||
577 | return SUCCESSNO_ERR; | |||
578 | } | |||
579 | ||||
580 | module = SECMOD_FindModule(moduleName); | |||
581 | if (!module) { | |||
582 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_MODULE_ERR], moduleName); | |||
583 | rv = NO_SUCH_MODULE_ERR; | |||
584 | goto loser; | |||
585 | } | |||
586 | ||||
587 | if ((module->loaded) && | |||
588 | (PK11_GetModInfo(module, &modinfo) != SECSuccess)) { | |||
589 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[MOD_INFO_ERR], moduleName); | |||
590 | rv = MOD_INFO_ERR; | |||
591 | goto loser; | |||
592 | } | |||
593 | ||||
594 | /* Module info */ | |||
595 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), | |||
596 | "\n-----------------------------------------------------------\n"); | |||
597 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Name: %s\n", module->commonName); | |||
598 | if (module->internal || !module->dllName) { | |||
599 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Library file: **Internal ONLY module**\n"); | |||
600 | } else { | |||
601 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Library file: %s\n", module->dllName); | |||
602 | } | |||
603 | ||||
604 | if (module->loaded) { | |||
605 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Manufacturer: %.32s\n", modinfo.manufacturerID); | |||
606 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Description: %.32s\n", modinfo.libraryDescription); | |||
607 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "PKCS #11 Version %d.%d\n", | |||
608 | modinfo.cryptokiVersion.major, modinfo.cryptokiVersion.minor); | |||
609 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Library Version: %d.%d\n", | |||
610 | modinfo.libraryVersion.major, modinfo.libraryVersion.minor); | |||
611 | } else { | |||
612 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "* Module not loaded\n"); | |||
613 | } | |||
614 | /* Get cipher and mechanism flags */ | |||
615 | ciphers = getStringFromFlags(module->ssl[0], cipherStrings, | |||
616 | numCipherStrings); | |||
617 | if (ciphers[0] == '\0') { | |||
618 | ciphers = "None"; | |||
619 | } | |||
620 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Cipher Enable Flags: %s\n", ciphers); | |||
621 | mechanisms = NULL((void*)0); | |||
622 | if (module->slotCount > 0) { | |||
623 | mechanisms = getStringFromFlags( | |||
624 | PK11_GetDefaultFlags(module->slots[0]), | |||
625 | mechanismStrings, numMechanismStrings); | |||
626 | } | |||
627 | if ((mechanisms == NULL((void*)0)) || (mechanisms[0] == '\0')) { | |||
628 | mechanisms = "None"; | |||
629 | } | |||
630 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Default Mechanism Flags: %s\n", mechanisms); | |||
631 | ||||
632 | #define PAD" " " " | |||
633 | ||||
634 | /* Loop over each slot */ | |||
635 | for (slotnum = 0; slotnum < module->slotCount; slotnum++) { | |||
636 | slot = module->slots[slotnum]; | |||
637 | if (PK11_GetSlotInfo(slot, &slotinfo) != SECSuccess) { | |||
638 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[SLOT_INFO_ERR], | |||
639 | PK11_GetSlotName(slot)); | |||
640 | rv = SLOT_INFO_ERR; | |||
641 | continue; | |||
642 | } | |||
643 | ||||
644 | /* Slot Info */ | |||
645 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\n" PAD" " "Slot: %s\n", PK11_GetSlotName(slot)); | |||
646 | mechanisms = getStringFromFlags(PK11_GetDefaultFlags(slot), | |||
647 | mechanismStrings, numMechanismStrings); | |||
648 | if (mechanisms[0] == '\0') { | |||
649 | mechanisms = "None"; | |||
650 | } | |||
651 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Slot Mechanism Flags: %s\n", mechanisms); | |||
652 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Manufacturer: %.32s\n", | |||
653 | slotinfo.manufacturerID); | |||
654 | if (PK11_IsHW(slot)) { | |||
655 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Type: Hardware\n"); | |||
656 | } else { | |||
657 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Type: Software\n"); | |||
658 | } | |||
659 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Version Number: %d.%d\n", | |||
660 | slotinfo.hardwareVersion.major, slotinfo.hardwareVersion.minor); | |||
661 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Firmware Version: %d.%d\n", | |||
662 | slotinfo.firmwareVersion.major, slotinfo.firmwareVersion.minor); | |||
663 | if (PK11_IsDisabled(slot)) { | |||
664 | reasonIdx = PK11_GetDisabledReason(slot); | |||
665 | if (reasonIdx < numDisableReasonStr) { | |||
666 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Status: DISABLED (%s)\n", | |||
667 | disableReasonStr[reasonIdx]); | |||
668 | } else { | |||
669 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Status: DISABLED\n"); | |||
670 | } | |||
671 | } else { | |||
672 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Status: Enabled\n"); | |||
673 | } | |||
674 | ||||
675 | if (PK11_GetTokenInfo(slot, &tokeninfo) != SECSuccess) { | |||
676 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[TOKEN_INFO_ERR], | |||
677 | PK11_GetTokenName(slot)); | |||
678 | rv = TOKEN_INFO_ERR; | |||
679 | continue; | |||
680 | } | |||
681 | ||||
682 | /* Token Info */ | |||
683 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Token Name: %.32s\n", | |||
684 | tokeninfo.label); | |||
685 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Token Manufacturer: %.32s\n", | |||
686 | tokeninfo.manufacturerID); | |||
687 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Token Model: %.16s\n", tokeninfo.model); | |||
688 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Token Serial Number: %.16s\n", | |||
689 | tokeninfo.serialNumber); | |||
690 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Token Version: %d.%d\n", | |||
691 | tokeninfo.hardwareVersion.major, tokeninfo.hardwareVersion.minor); | |||
692 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Token Firmware Version: %d.%d\n", | |||
693 | tokeninfo.firmwareVersion.major, tokeninfo.firmwareVersion.minor); | |||
694 | if (tokeninfo.flags & CKF_WRITE_PROTECTED0x00000002UL) { | |||
695 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Access: Write Protected\n"); | |||
696 | } else { | |||
697 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Access: NOT Write Protected\n"); | |||
698 | } | |||
699 | if (tokeninfo.flags & CKF_LOGIN_REQUIRED0x00000004UL) { | |||
700 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "Login Type: Login required\n"); | |||
701 | } else { | |||
702 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " | |||
703 | "Login Type: Public (no login required)\n"); | |||
704 | } | |||
705 | if (tokeninfo.flags & CKF_USER_PIN_INITIALIZED0x00000008UL) { | |||
706 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "User Pin: Initialized\n"); | |||
707 | } else { | |||
708 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), PAD" " "User Pin: NOT Initialized\n"); | |||
709 | } | |||
710 | } | |||
711 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), | |||
712 | "\n-----------------------------------------------------------\n"); | |||
713 | loser: | |||
714 | if (module) { | |||
715 | SECMOD_DestroyModule(module); | |||
716 | } | |||
717 | return rv; | |||
718 | } | |||
719 | ||||
720 | /************************************************************************ | |||
721 | * | |||
722 | * I n i t P W | |||
723 | */ | |||
724 | Error | |||
725 | InitPW(void) | |||
726 | { | |||
727 | PK11SlotInfo *slot; | |||
728 | Error ret = UNSPECIFIED_ERR; | |||
729 | ||||
730 | slot = PK11_GetInternalKeySlot(); | |||
731 | if (!slot) { | |||
732 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_TOKEN_ERR], "internal"); | |||
733 | return NO_SUCH_TOKEN_ERR; | |||
734 | } | |||
735 | ||||
736 | /* Set the initial password to empty */ | |||
737 | if (PK11_NeedUserInit(slot)) { | |||
738 | if (PK11_InitPin(slot, NULL((void*)0), "") != SECSuccess) { | |||
739 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[INITPW_FAILED_ERR]); | |||
740 | ret = INITPW_FAILED_ERR; | |||
741 | goto loser; | |||
742 | } | |||
743 | } | |||
744 | ||||
745 | ret = SUCCESSNO_ERR; | |||
746 | ||||
747 | loser: | |||
748 | PK11_FreeSlot(slot); | |||
749 | ||||
750 | return ret; | |||
751 | } | |||
752 | ||||
753 | /************************************************************************ | |||
754 | * | |||
755 | * C h a n g e P W | |||
756 | */ | |||
757 | Error | |||
758 | ChangePW(char *tokenName, char *pwFile, char *newpwFile) | |||
759 | { | |||
760 | char *oldpw = NULL((void*)0), *newpw = NULL((void*)0), *newpw2 = NULL((void*)0); | |||
761 | PK11SlotInfo *slot; | |||
762 | Error ret = UNSPECIFIED_ERR; | |||
763 | PRBool matching; | |||
764 | ||||
765 | slot = PK11_FindSlotByName(tokenName); | |||
766 | if (!slot) { | |||
767 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_TOKEN_ERR], tokenName); | |||
768 | return NO_SUCH_TOKEN_ERR; | |||
769 | } | |||
770 | ||||
771 | /* Get old password */ | |||
772 | if (!PK11_NeedUserInit(slot)) { | |||
773 | if (pwFile) { | |||
774 | oldpw = SECU_FilePasswd(NULL((void*)0), PR_FALSE0, pwFile); | |||
775 | if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) { | |||
776 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[BAD_PW_ERR]); | |||
777 | ret = BAD_PW_ERR; | |||
778 | goto loser; | |||
779 | } | |||
780 | } else if (PK11_NeedLogin(slot)) { | |||
781 | for (matching = PR_FALSE0; !matching;) { | |||
782 | oldpw = SECU_GetPasswordString(NULL((void*)0), "Enter old password: "); | |||
783 | if (PK11_CheckUserPassword(slot, oldpw) == SECSuccess) { | |||
784 | matching = PR_TRUE1; | |||
785 | } else { | |||
786 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[BAD_PW_MSG]); | |||
787 | } | |||
788 | } | |||
789 | } | |||
790 | } | |||
791 | ||||
792 | /* Get new password */ | |||
793 | if (newpwFile) { | |||
794 | newpw = SECU_FilePasswd(NULL((void*)0), PR_FALSE0, newpwFile); | |||
795 | } else { | |||
796 | for (matching = PR_FALSE0; !matching;) { | |||
797 | newpw = SECU_GetPasswordString(NULL((void*)0), "Enter new password: "); | |||
798 | newpw2 = SECU_GetPasswordString(NULL((void*)0), "Re-enter new password: "); | |||
799 | if (strcmp(newpw, newpw2)) { | |||
800 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[PW_MATCH_MSG]); | |||
801 | PORT_ZFreePORT_ZFree_Util(newpw, strlen(newpw)); | |||
802 | PORT_ZFreePORT_ZFree_Util(newpw2, strlen(newpw2)); | |||
803 | } else { | |||
804 | matching = PR_TRUE1; | |||
805 | } | |||
806 | } | |||
807 | } | |||
808 | ||||
809 | /* Change the password */ | |||
810 | if (PK11_NeedUserInit(slot)) { | |||
811 | if (PK11_InitPin(slot, NULL((void*)0) /*ssopw*/, newpw) != SECSuccess) { | |||
812 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[CHANGEPW_FAILED_ERR], tokenName); | |||
813 | ret = CHANGEPW_FAILED_ERR; | |||
814 | goto loser; | |||
815 | } | |||
816 | } else { | |||
817 | if (PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) { | |||
818 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[CHANGEPW_FAILED_ERR], tokenName); | |||
819 | ret = CHANGEPW_FAILED_ERR; | |||
820 | goto loser; | |||
821 | } | |||
822 | } | |||
823 | ||||
824 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[CHANGEPW_SUCCESS_MSG], tokenName); | |||
825 | ret = SUCCESSNO_ERR; | |||
826 | ||||
827 | loser: | |||
828 | if (oldpw) { | |||
829 | PORT_ZFreePORT_ZFree_Util(oldpw, strlen(oldpw)); | |||
830 | } | |||
831 | if (newpw) { | |||
832 | PORT_ZFreePORT_ZFree_Util(newpw, strlen(newpw)); | |||
833 | } | |||
834 | if (newpw2) { | |||
835 | PORT_ZFreePORT_ZFree_Util(newpw2, strlen(newpw2)); | |||
836 | } | |||
837 | PK11_FreeSlot(slot); | |||
838 | ||||
839 | return ret; | |||
840 | } | |||
841 | ||||
842 | /*********************************************************************** | |||
843 | * | |||
844 | * E n a b l e M o d u l e | |||
845 | * | |||
846 | * If enable==PR_TRUE, enables the module or slot. | |||
847 | * If enable==PR_FALSE, disables the module or slot. | |||
848 | * moduleName is the name of the module. | |||
849 | * slotName is the name of the slot. It is optional. | |||
850 | */ | |||
851 | Error | |||
852 | EnableModule(char *moduleName, char *slotName, PRBool enable) | |||
853 | { | |||
854 | int i; | |||
855 | SECMODModule *module = NULL((void*)0); | |||
856 | PK11SlotInfo *slot = NULL((void*)0); | |||
857 | PRBool found = PR_FALSE0; | |||
858 | Error rv; | |||
859 | ||||
860 | module = SECMOD_FindModule(moduleName); | |||
861 | if (!module) { | |||
862 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_MODULE_ERR], moduleName); | |||
863 | rv = NO_SUCH_MODULE_ERR; | |||
864 | goto loser; | |||
865 | } | |||
866 | ||||
867 | for (i = 0; i < module->slotCount; i++) { | |||
868 | slot = module->slots[i]; | |||
869 | if (slotName && strcmp(PK11_GetSlotName(slot), slotName)) { | |||
870 | /* Not the right slot */ | |||
871 | continue; | |||
872 | } | |||
873 | if (enable) { | |||
874 | if (!PK11_UserEnableSlot(slot)) { | |||
875 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[ENABLE_FAILED_ERR], | |||
876 | "enable", PK11_GetSlotName(slot)); | |||
877 | rv = ENABLE_FAILED_ERR; | |||
878 | goto loser; | |||
879 | } else { | |||
880 | found = PR_TRUE1; | |||
881 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[ENABLE_SUCCESS_MSG], | |||
882 | PK11_GetSlotName(slot), "enabled"); | |||
883 | } | |||
884 | } else { | |||
885 | if (!PK11_UserDisableSlot(slot)) { | |||
886 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[ENABLE_FAILED_ERR], | |||
887 | "disable", PK11_GetSlotName(slot)); | |||
888 | rv = ENABLE_FAILED_ERR; | |||
889 | goto loser; | |||
890 | } else { | |||
891 | found = PR_TRUE1; | |||
892 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[ENABLE_SUCCESS_MSG], | |||
893 | PK11_GetSlotName(slot), "disabled"); | |||
894 | } | |||
895 | } | |||
896 | } | |||
897 | ||||
898 | if (slotName && !found) { | |||
899 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_SLOT_ERR], slotName); | |||
900 | rv = NO_SUCH_SLOT_ERR; | |||
901 | goto loser; | |||
902 | } | |||
903 | ||||
904 | /* Delete and re-add module to save changes */ | |||
905 | if (SECMOD_UpdateModule(module) != SECSuccess) { | |||
906 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[UPDATE_MOD_FAILED_ERR], moduleName); | |||
907 | rv = UPDATE_MOD_FAILED_ERR; | |||
908 | goto loser; | |||
909 | } | |||
910 | ||||
911 | rv = SUCCESSNO_ERR; | |||
912 | loser: | |||
913 | if (module) { | |||
914 | SECMOD_DestroyModule(module); | |||
915 | } | |||
916 | return rv; | |||
917 | } | |||
918 | ||||
919 | /************************************************************************* | |||
920 | * | |||
921 | * S e t D e f a u l t M o d u l e | |||
922 | * | |||
923 | */ | |||
924 | Error | |||
925 | SetDefaultModule(char *moduleName, char *slotName, char *mechanisms) | |||
926 | { | |||
927 | SECMODModule *module = NULL((void*)0); | |||
928 | PK11SlotInfo *slot; | |||
929 | int s, i; | |||
930 | unsigned long mechFlags = getFlagsFromString(mechanisms, mechanismStrings, | |||
931 | numMechanismStrings); | |||
932 | PRBool found = PR_FALSE0; | |||
933 | Error errcode = UNSPECIFIED_ERR; | |||
934 | ||||
935 | mechFlags = SECMOD_PubMechFlagstoInternal(mechFlags); | |||
936 | ||||
937 | module = SECMOD_FindModule(moduleName); | |||
938 | if (!module) { | |||
939 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_MODULE_ERR], moduleName); | |||
940 | errcode = NO_SUCH_MODULE_ERR; | |||
941 | goto loser; | |||
942 | } | |||
943 | ||||
944 | /* Go through each slot */ | |||
945 | for (s = 0; s < module->slotCount; s++) { | |||
946 | slot = module->slots[s]; | |||
947 | ||||
948 | if ((slotName != NULL((void*)0)) && | |||
949 | !((strcmp(PK11_GetSlotName(slot), slotName) == 0) || | |||
950 | (strcmp(PK11_GetTokenName(slot), slotName) == 0))) { | |||
951 | /* we are only interested in changing the one slot */ | |||
952 | continue; | |||
953 | } | |||
954 | ||||
955 | found = PR_TRUE1; | |||
956 | ||||
957 | /* Go through each mechanism */ | |||
958 | for (i = 0; i < pk11_DefaultArraySize; i++) { | |||
959 | if (pk11_DefaultArray[i].flag & mechFlags) { | |||
960 | /* Enable this default mechanism */ | |||
961 | PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]), | |||
962 | PR_TRUE1); | |||
963 | } | |||
964 | } | |||
965 | } | |||
966 | if (slotName && !found) { | |||
967 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_SLOT_ERR], slotName); | |||
968 | errcode = NO_SUCH_SLOT_ERR; | |||
969 | goto loser; | |||
970 | } | |||
971 | ||||
972 | /* Delete and re-add module to save changes */ | |||
973 | if (SECMOD_UpdateModule(module) != SECSuccess) { | |||
974 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[DEFAULT_FAILED_ERR], | |||
975 | moduleName); | |||
976 | errcode = DEFAULT_FAILED_ERR; | |||
977 | goto loser; | |||
978 | } | |||
979 | ||||
980 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[DEFAULT_SUCCESS_MSG]); | |||
981 | ||||
982 | errcode = SUCCESSNO_ERR; | |||
983 | loser: | |||
984 | if (module) { | |||
985 | SECMOD_DestroyModule(module); | |||
986 | } | |||
987 | return errcode; | |||
988 | } | |||
989 | ||||
990 | /************************************************************************ | |||
991 | * | |||
992 | * U n s e t D e f a u l t M o d u l e | |||
993 | */ | |||
994 | Error | |||
995 | UnsetDefaultModule(char *moduleName, char *slotName, char *mechanisms) | |||
996 | { | |||
997 | SECMODModule *module = NULL((void*)0); | |||
998 | PK11SlotInfo *slot; | |||
999 | int s, i; | |||
1000 | unsigned long mechFlags = getFlagsFromString(mechanisms, | |||
| ||||
1001 | mechanismStrings, numMechanismStrings); | |||
1002 | PRBool found = PR_FALSE0; | |||
1003 | Error rv; | |||
1004 | ||||
1005 | mechFlags = SECMOD_PubMechFlagstoInternal(mechFlags); | |||
1006 | ||||
1007 | module = SECMOD_FindModule(moduleName); | |||
1008 | if (!module) { | |||
1009 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_MODULE_ERR], moduleName); | |||
1010 | rv = NO_SUCH_MODULE_ERR; | |||
1011 | goto loser; | |||
1012 | } | |||
1013 | ||||
1014 | for (s = 0; s < module->slotCount; s++) { | |||
1015 | slot = module->slots[s]; | |||
1016 | if ((slotName != NULL((void*)0)) && | |||
1017 | !((strcmp(PK11_GetSlotName(slot), slotName) == 0) || | |||
1018 | (strcmp(PK11_GetTokenName(slot), slotName) == 0))) { | |||
1019 | /* we are only interested in changing the one slot */ | |||
1020 | continue; | |||
1021 | } | |||
1022 | for (i = 0; i < pk11_DefaultArraySize; i++) { | |||
1023 | if (pk11_DefaultArray[i].flag & mechFlags) { | |||
1024 | PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]), | |||
1025 | PR_FALSE0); | |||
1026 | } | |||
1027 | } | |||
1028 | } | |||
1029 | if (slotName && !found) { | |||
1030 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[NO_SUCH_SLOT_ERR], slotName); | |||
1031 | rv = NO_SUCH_SLOT_ERR; | |||
1032 | goto loser; | |||
1033 | } | |||
1034 | ||||
1035 | /* Delete and re-add module to save changes */ | |||
1036 | if (SECMOD_UpdateModule(module) != SECSuccess) { | |||
1037 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), errStrings[UNDEFAULT_FAILED_ERR], | |||
1038 | moduleName); | |||
1039 | rv = UNDEFAULT_FAILED_ERR; | |||
1040 | goto loser; | |||
1041 | } | |||
1042 | ||||
1043 | PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), msgStrings[UNDEFAULT_SUCCESS_MSG]); | |||
1044 | rv = SUCCESSNO_ERR; | |||
1045 | loser: | |||
1046 | if (module) { | |||
1047 | SECMOD_DestroyModule(module); | |||
1048 | } | |||
1049 | return rv; | |||
1050 | } |