utilpars.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  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. * The following code handles the storage of PKCS 11 modules used by the
  6. * NSS. This file is written to abstract away how the modules are
  7. * stored so we can decide that later.
  8. */
  9. #include "secport.h"
  10. #include "prprf.h"
  11. #include "prenv.h"
  12. #include "utilpars.h"
  13. #include "utilmodt.h"
  14. /*
  15. * return the expected matching quote value for the one specified
  16. */
  17. PRBool
  18. NSSUTIL_ArgGetPair(char c)
  19. {
  20. switch (c) {
  21. case '\'':
  22. return c;
  23. case '\"':
  24. return c;
  25. case '<':
  26. return '>';
  27. case '{':
  28. return '}';
  29. case '[':
  30. return ']';
  31. case '(':
  32. return ')';
  33. default:
  34. break;
  35. }
  36. return ' ';
  37. }
  38. PRBool
  39. NSSUTIL_ArgIsBlank(char c)
  40. {
  41. return isspace((unsigned char)c);
  42. }
  43. PRBool
  44. NSSUTIL_ArgIsEscape(char c)
  45. {
  46. return c == '\\';
  47. }
  48. PRBool
  49. NSSUTIL_ArgIsQuote(char c)
  50. {
  51. switch (c) {
  52. case '\'':
  53. case '\"':
  54. case '<':
  55. case '{': /* } end curly to keep vi bracket matching working */
  56. case '(': /* ) */
  57. case '[': /* ] */
  58. return PR_TRUE;
  59. default:
  60. break;
  61. }
  62. return PR_FALSE;
  63. }
  64. const char *
  65. NSSUTIL_ArgStrip(const char *c)
  66. {
  67. while (*c && NSSUTIL_ArgIsBlank(*c))
  68. c++;
  69. return c;
  70. }
  71. /*
  72. * find the end of the current tag/value pair. string should be pointing just
  73. * after the equal sign. Handles quoted characters.
  74. */
  75. const char *
  76. NSSUTIL_ArgFindEnd(const char *string)
  77. {
  78. char endChar = ' ';
  79. PRBool lastEscape = PR_FALSE;
  80. if (NSSUTIL_ArgIsQuote(*string)) {
  81. endChar = NSSUTIL_ArgGetPair(*string);
  82. string++;
  83. }
  84. for (; *string; string++) {
  85. if (lastEscape) {
  86. lastEscape = PR_FALSE;
  87. continue;
  88. }
  89. if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
  90. lastEscape = PR_TRUE;
  91. continue;
  92. }
  93. if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string))
  94. break;
  95. if (*string == endChar) {
  96. break;
  97. }
  98. }
  99. return string;
  100. }
  101. /*
  102. * get the value pointed to by string. string should be pointing just beyond
  103. * the equal sign.
  104. */
  105. char *
  106. NSSUTIL_ArgFetchValue(const char *string, int *pcount)
  107. {
  108. const char *end = NSSUTIL_ArgFindEnd(string);
  109. char *retString, *copyString;
  110. PRBool lastEscape = PR_FALSE;
  111. int len;
  112. len = end - string;
  113. if (len == 0) {
  114. *pcount = 0;
  115. return NULL;
  116. }
  117. copyString = retString = (char *)PORT_Alloc(len + 1);
  118. if (*end)
  119. len++;
  120. *pcount = len;
  121. if (retString == NULL)
  122. return NULL;
  123. if (NSSUTIL_ArgIsQuote(*string))
  124. string++;
  125. for (; string < end; string++) {
  126. if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
  127. lastEscape = PR_TRUE;
  128. continue;
  129. }
  130. lastEscape = PR_FALSE;
  131. *copyString++ = *string;
  132. }
  133. *copyString = 0;
  134. return retString;
  135. }
  136. /*
  137. * point to the next parameter in string
  138. */
  139. const char *
  140. NSSUTIL_ArgSkipParameter(const char *string)
  141. {
  142. const char *end;
  143. /* look for the end of the <name>= */
  144. for (; *string; string++) {
  145. if (*string == '=') {
  146. string++;
  147. break;
  148. }
  149. if (NSSUTIL_ArgIsBlank(*string))
  150. return (string);
  151. }
  152. end = NSSUTIL_ArgFindEnd(string);
  153. if (*end)
  154. end++;
  155. return end;
  156. }
  157. /*
  158. * get the value from that tag value pair.
  159. */
  160. char *
  161. NSSUTIL_ArgGetParamValue(const char *paramName, const char *parameters)
  162. {
  163. char searchValue[256];
  164. int paramLen = strlen(paramName);
  165. char *returnValue = NULL;
  166. int next;
  167. if ((parameters == NULL) || (*parameters == 0))
  168. return NULL;
  169. PORT_Assert(paramLen + 2 < sizeof(searchValue));
  170. PORT_Strcpy(searchValue, paramName);
  171. PORT_Strcat(searchValue, "=");
  172. while (*parameters) {
  173. if (PORT_Strncasecmp(parameters, searchValue, paramLen + 1) == 0) {
  174. parameters += paramLen + 1;
  175. returnValue = NSSUTIL_ArgFetchValue(parameters, &next);
  176. break;
  177. } else {
  178. parameters = NSSUTIL_ArgSkipParameter(parameters);
  179. }
  180. parameters = NSSUTIL_ArgStrip(parameters);
  181. }
  182. return returnValue;
  183. }
  184. /*
  185. * find the next flag in the parameter list
  186. */
  187. const char *
  188. NSSUTIL_ArgNextFlag(const char *flags)
  189. {
  190. for (; *flags; flags++) {
  191. if (*flags == ',') {
  192. flags++;
  193. break;
  194. }
  195. }
  196. return flags;
  197. }
  198. /*
  199. * return true if the flag is set in the label parameter.
  200. */
  201. PRBool
  202. NSSUTIL_ArgHasFlag(const char *label, const char *flag, const char *parameters)
  203. {
  204. char *flags;
  205. const char *index;
  206. int len = strlen(flag);
  207. PRBool found = PR_FALSE;
  208. flags = NSSUTIL_ArgGetParamValue(label, parameters);
  209. if (flags == NULL)
  210. return PR_FALSE;
  211. for (index = flags; *index; index = NSSUTIL_ArgNextFlag(index)) {
  212. if (PORT_Strncasecmp(index, flag, len) == 0) {
  213. found = PR_TRUE;
  214. break;
  215. }
  216. }
  217. PORT_Free(flags);
  218. return found;
  219. }
  220. /*
  221. * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal
  222. */
  223. long
  224. NSSUTIL_ArgDecodeNumber(const char *num)
  225. {
  226. int radix = 10;
  227. unsigned long value = 0;
  228. long retValue = 0;
  229. int sign = 1;
  230. int digit;
  231. if (num == NULL)
  232. return retValue;
  233. num = NSSUTIL_ArgStrip(num);
  234. if (*num == '-') {
  235. sign = -1;
  236. num++;
  237. }
  238. if (*num == '0') {
  239. radix = 8;
  240. num++;
  241. if ((*num == 'x') || (*num == 'X')) {
  242. radix = 16;
  243. num++;
  244. }
  245. }
  246. for (; *num; num++) {
  247. if (isdigit(*num)) {
  248. digit = *num - '0';
  249. } else if ((*num >= 'a') && (*num <= 'f')) {
  250. digit = *num - 'a' + 10;
  251. } else if ((*num >= 'A') && (*num <= 'F')) {
  252. digit = *num - 'A' + 10;
  253. } else {
  254. break;
  255. }
  256. if (digit >= radix)
  257. break;
  258. value = value * radix + digit;
  259. }
  260. retValue = ((int)value) * sign;
  261. return retValue;
  262. }
  263. /*
  264. * parameters are tag value pairs. This function returns the tag or label (the
  265. * value before the equal size.
  266. */
  267. char *
  268. NSSUTIL_ArgGetLabel(const char *inString, int *next)
  269. {
  270. char *name = NULL;
  271. const char *string;
  272. int len;
  273. /* look for the end of the <label>= */
  274. for (string = inString; *string; string++) {
  275. if (*string == '=') {
  276. break;
  277. }
  278. if (NSSUTIL_ArgIsBlank(*string))
  279. break;
  280. }
  281. len = string - inString;
  282. *next = len;
  283. if (*string == '=')
  284. (*next) += 1;
  285. if (len > 0) {
  286. name = PORT_Alloc(len + 1);
  287. PORT_Strncpy(name, inString, len);
  288. name[len] = 0;
  289. }
  290. return name;
  291. }
  292. /*
  293. * read an argument at a Long integer
  294. */
  295. long
  296. NSSUTIL_ArgReadLong(const char *label, const char *params,
  297. long defValue, PRBool *isdefault)
  298. {
  299. char *value;
  300. long retValue;
  301. if (isdefault)
  302. *isdefault = PR_FALSE;
  303. value = NSSUTIL_ArgGetParamValue(label, params);
  304. if (value == NULL) {
  305. if (isdefault)
  306. *isdefault = PR_TRUE;
  307. return defValue;
  308. }
  309. retValue = NSSUTIL_ArgDecodeNumber(value);
  310. if (value)
  311. PORT_Free(value);
  312. return retValue;
  313. }
  314. /*
  315. * prepare a string to be quoted with 'quote' marks. We do that by adding
  316. * appropriate escapes.
  317. */
  318. static int
  319. nssutil_escapeQuotesSize(const char *string, char quote, PRBool addquotes)
  320. {
  321. int escapes = 0, size = 0;
  322. const char *src;
  323. size = addquotes ? 2 : 0;
  324. for (src = string; *src; src++) {
  325. if ((*src == quote) || (*src == '\\'))
  326. escapes++;
  327. size++;
  328. }
  329. return size + escapes + 1;
  330. }
  331. static char *
  332. nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes)
  333. {
  334. char *newString = 0;
  335. int size = 0;
  336. const char *src;
  337. char *dest;
  338. size = nssutil_escapeQuotesSize(string, quote, addquotes);
  339. dest = newString = PORT_ZAlloc(size);
  340. if (newString == NULL) {
  341. return NULL;
  342. }
  343. if (addquotes)
  344. *dest++ = quote;
  345. for (src = string; *src; src++, dest++) {
  346. if ((*src == '\\') || (*src == quote)) {
  347. *dest++ = '\\';
  348. }
  349. *dest = *src;
  350. }
  351. if (addquotes)
  352. *dest = quote;
  353. return newString;
  354. }
  355. int
  356. NSSUTIL_EscapeSize(const char *string, char quote)
  357. {
  358. return nssutil_escapeQuotesSize(string, quote, PR_FALSE);
  359. }
  360. char *
  361. NSSUTIL_Escape(const char *string, char quote)
  362. {
  363. return nssutil_escapeQuotes(string, quote, PR_FALSE);
  364. }
  365. int
  366. NSSUTIL_QuoteSize(const char *string, char quote)
  367. {
  368. return nssutil_escapeQuotesSize(string, quote, PR_TRUE);
  369. }
  370. char *
  371. NSSUTIL_Quote(const char *string, char quote)
  372. {
  373. return nssutil_escapeQuotes(string, quote, PR_TRUE);
  374. }
  375. int
  376. NSSUTIL_DoubleEscapeSize(const char *string, char quote1, char quote2)
  377. {
  378. int escapes = 0, size = 0;
  379. const char *src;
  380. for (src = string; *src; src++) {
  381. if (*src == '\\')
  382. escapes += 3; /* \\\\ */
  383. if (*src == quote1)
  384. escapes += 2; /* \\quote1 */
  385. if (*src == quote2)
  386. escapes++; /* \quote2 */
  387. size++;
  388. }
  389. return escapes + size + 1;
  390. }
  391. char *
  392. NSSUTIL_DoubleEscape(const char *string, char quote1, char quote2)
  393. {
  394. char *round1 = NULL;
  395. char *retValue = NULL;
  396. if (string == NULL) {
  397. goto done;
  398. }
  399. round1 = nssutil_escapeQuotes(string, quote1, PR_FALSE);
  400. if (round1) {
  401. retValue = nssutil_escapeQuotes(round1, quote2, PR_FALSE);
  402. PORT_Free(round1);
  403. }
  404. done:
  405. if (retValue == NULL) {
  406. retValue = PORT_Strdup("");
  407. }
  408. return retValue;
  409. }
  410. /************************************************************************
  411. * These functions are used in contructing strings.
  412. * NOTE: they will always return a string, but sometimes it will return
  413. * a specific NULL string. These strings must be freed with util_freePair.
  414. */
  415. /* string to return on error... */
  416. static char *nssutil_nullString = "";
  417. static char *
  418. nssutil_formatValue(PLArenaPool *arena, char *value, char quote)
  419. {
  420. char *vp, *vp2, *retval;
  421. int size = 0, escapes = 0;
  422. for (vp = value; *vp; vp++) {
  423. if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE))
  424. escapes++;
  425. size++;
  426. }
  427. if (arena) {
  428. retval = PORT_ArenaZAlloc(arena, size + escapes + 1);
  429. } else {
  430. retval = PORT_ZAlloc(size + escapes + 1);
  431. }
  432. if (retval == NULL)
  433. return NULL;
  434. vp2 = retval;
  435. for (vp = value; *vp; vp++) {
  436. if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE))
  437. *vp2++ = NSSUTIL_ARG_ESCAPE;
  438. *vp2++ = *vp;
  439. }
  440. return retval;
  441. }
  442. static PRBool
  443. nssutil_argHasChar(char *v, char c)
  444. {
  445. for (; *v; v++) {
  446. if (*v == c)
  447. return PR_TRUE;
  448. }
  449. return PR_FALSE;
  450. }
  451. static PRBool
  452. nssutil_argHasBlanks(char *v)
  453. {
  454. for (; *v; v++) {
  455. if (NSSUTIL_ArgIsBlank(*v))
  456. return PR_TRUE;
  457. }
  458. return PR_FALSE;
  459. }
  460. static char *
  461. nssutil_formatPair(char *name, char *value, char quote)
  462. {
  463. char openQuote = quote;
  464. char closeQuote = NSSUTIL_ArgGetPair(quote);
  465. char *newValue = NULL;
  466. char *returnValue;
  467. PRBool need_quote = PR_FALSE;
  468. if (!value || (*value == 0))
  469. return nssutil_nullString;
  470. if (nssutil_argHasBlanks(value) || NSSUTIL_ArgIsQuote(value[0]))
  471. need_quote = PR_TRUE;
  472. if ((need_quote && nssutil_argHasChar(value, closeQuote)) || nssutil_argHasChar(value, NSSUTIL_ARG_ESCAPE)) {
  473. value = newValue = nssutil_formatValue(NULL, value, quote);
  474. if (newValue == NULL)
  475. return nssutil_nullString;
  476. }
  477. if (need_quote) {
  478. returnValue = PR_smprintf("%s=%c%s%c", name, openQuote, value, closeQuote);
  479. } else {
  480. returnValue = PR_smprintf("%s=%s", name, value);
  481. }
  482. if (returnValue == NULL)
  483. returnValue = nssutil_nullString;
  484. if (newValue)
  485. PORT_Free(newValue);
  486. return returnValue;
  487. }
  488. static char *
  489. nssutil_formatIntPair(char *name, unsigned long value,
  490. unsigned long def)
  491. {
  492. char *returnValue;
  493. if (value == def)
  494. return nssutil_nullString;
  495. returnValue = PR_smprintf("%s=%d", name, value);
  496. return returnValue;
  497. }
  498. static void
  499. nssutil_freePair(char *pair)
  500. {
  501. if (pair && pair != nssutil_nullString) {
  502. PR_smprintf_free(pair);
  503. }
  504. }
  505. /************************************************************************
  506. * Parse the Slot specific parameters in the NSS params.
  507. */
  508. struct nssutilArgSlotFlagTable {
  509. char *name;
  510. int len;
  511. unsigned long value;
  512. };
  513. #define NSSUTIL_ARG_ENTRY(arg, flag) \
  514. { \
  515. #arg, sizeof(#arg) - 1, flag \
  516. }
  517. static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = {
  518. NSSUTIL_ARG_ENTRY(RSA, SECMOD_RSA_FLAG),
  519. NSSUTIL_ARG_ENTRY(ECC, SECMOD_ECC_FLAG),
  520. NSSUTIL_ARG_ENTRY(DSA, SECMOD_RSA_FLAG),
  521. NSSUTIL_ARG_ENTRY(RC2, SECMOD_RC4_FLAG),
  522. NSSUTIL_ARG_ENTRY(RC4, SECMOD_RC2_FLAG),
  523. NSSUTIL_ARG_ENTRY(DES, SECMOD_DES_FLAG),
  524. NSSUTIL_ARG_ENTRY(DH, SECMOD_DH_FLAG),
  525. NSSUTIL_ARG_ENTRY(FORTEZZA, SECMOD_FORTEZZA_FLAG),
  526. NSSUTIL_ARG_ENTRY(RC5, SECMOD_RC5_FLAG),
  527. NSSUTIL_ARG_ENTRY(SHA1, SECMOD_SHA1_FLAG),
  528. NSSUTIL_ARG_ENTRY(SHA256, SECMOD_SHA256_FLAG),
  529. NSSUTIL_ARG_ENTRY(SHA512, SECMOD_SHA512_FLAG),
  530. NSSUTIL_ARG_ENTRY(MD5, SECMOD_MD5_FLAG),
  531. NSSUTIL_ARG_ENTRY(MD2, SECMOD_MD2_FLAG),
  532. NSSUTIL_ARG_ENTRY(SSL, SECMOD_SSL_FLAG),
  533. NSSUTIL_ARG_ENTRY(TLS, SECMOD_TLS_FLAG),
  534. NSSUTIL_ARG_ENTRY(AES, SECMOD_AES_FLAG),
  535. NSSUTIL_ARG_ENTRY(Camellia, SECMOD_CAMELLIA_FLAG),
  536. NSSUTIL_ARG_ENTRY(SEED, SECMOD_SEED_FLAG),
  537. NSSUTIL_ARG_ENTRY(PublicCerts, SECMOD_FRIENDLY_FLAG),
  538. NSSUTIL_ARG_ENTRY(RANDOM, SECMOD_RANDOM_FLAG),
  539. NSSUTIL_ARG_ENTRY(Disable, SECMOD_DISABLE_FLAG),
  540. };
  541. static int nssutil_argSlotFlagTableSize =
  542. sizeof(nssutil_argSlotFlagTable) / sizeof(nssutil_argSlotFlagTable[0]);
  543. /* turn the slot flags into a bit mask */
  544. unsigned long
  545. NSSUTIL_ArgParseSlotFlags(const char *label, const char *params)
  546. {
  547. char *flags;
  548. const char *index;
  549. unsigned long retValue = 0;
  550. int i;
  551. PRBool all = PR_FALSE;
  552. flags = NSSUTIL_ArgGetParamValue(label, params);
  553. if (flags == NULL)
  554. return 0;
  555. if (PORT_Strcasecmp(flags, "all") == 0)
  556. all = PR_TRUE;
  557. for (index = flags; *index; index = NSSUTIL_ArgNextFlag(index)) {
  558. for (i = 0; i < nssutil_argSlotFlagTableSize; i++) {
  559. if (all ||
  560. (PORT_Strncasecmp(index, nssutil_argSlotFlagTable[i].name,
  561. nssutil_argSlotFlagTable[i].len) == 0)) {
  562. retValue |= nssutil_argSlotFlagTable[i].value;
  563. }
  564. }
  565. }
  566. PORT_Free(flags);
  567. return retValue;
  568. }
  569. /* parse a single slot specific parameter */
  570. static void
  571. nssutil_argDecodeSingleSlotInfo(char *name, char *params,
  572. struct NSSUTILPreSlotInfoStr *slotInfo)
  573. {
  574. char *askpw;
  575. slotInfo->slotID = NSSUTIL_ArgDecodeNumber(name);
  576. slotInfo->defaultFlags = NSSUTIL_ArgParseSlotFlags("slotFlags", params);
  577. slotInfo->timeout = NSSUTIL_ArgReadLong("timeout", params, 0, NULL);
  578. askpw = NSSUTIL_ArgGetParamValue("askpw", params);
  579. slotInfo->askpw = 0;
  580. if (askpw) {
  581. if (PORT_Strcasecmp(askpw, "every") == 0) {
  582. slotInfo->askpw = -1;
  583. } else if (PORT_Strcasecmp(askpw, "timeout") == 0) {
  584. slotInfo->askpw = 1;
  585. }
  586. PORT_Free(askpw);
  587. slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS;
  588. }
  589. slotInfo->hasRootCerts = NSSUTIL_ArgHasFlag("rootFlags", "hasRootCerts",
  590. params);
  591. slotInfo->hasRootTrust = NSSUTIL_ArgHasFlag("rootFlags", "hasRootTrust",
  592. params);
  593. }
  594. /* parse all the slot specific parameters. */
  595. struct NSSUTILPreSlotInfoStr *
  596. NSSUTIL_ArgParseSlotInfo(PLArenaPool *arena, const char *slotParams,
  597. int *retCount)
  598. {
  599. const char *slotIndex;
  600. struct NSSUTILPreSlotInfoStr *slotInfo = NULL;
  601. int i = 0, count = 0, next;
  602. *retCount = 0;
  603. if ((slotParams == NULL) || (*slotParams == 0))
  604. return NULL;
  605. /* first count the number of slots */
  606. for (slotIndex = NSSUTIL_ArgStrip(slotParams); *slotIndex;
  607. slotIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(slotIndex))) {
  608. count++;
  609. }
  610. /* get the data structures */
  611. if (arena) {
  612. slotInfo = PORT_ArenaZNewArray(arena,
  613. struct NSSUTILPreSlotInfoStr, count);
  614. } else {
  615. slotInfo = PORT_ZNewArray(struct NSSUTILPreSlotInfoStr, count);
  616. }
  617. if (slotInfo == NULL)
  618. return NULL;
  619. for (slotIndex = NSSUTIL_ArgStrip(slotParams), i = 0;
  620. *slotIndex && i < count;) {
  621. char *name;
  622. name = NSSUTIL_ArgGetLabel(slotIndex, &next);
  623. slotIndex += next;
  624. if (!NSSUTIL_ArgIsBlank(*slotIndex)) {
  625. char *args = NSSUTIL_ArgFetchValue(slotIndex, &next);
  626. slotIndex += next;
  627. if (args) {
  628. nssutil_argDecodeSingleSlotInfo(name, args, &slotInfo[i]);
  629. i++;
  630. PORT_Free(args);
  631. }
  632. }
  633. if (name)
  634. PORT_Free(name);
  635. slotIndex = NSSUTIL_ArgStrip(slotIndex);
  636. }
  637. *retCount = i;
  638. return slotInfo;
  639. }
  640. /************************************************************************
  641. * make a new slot specific parameter
  642. */
  643. /* first make the slot flags */
  644. static char *
  645. nssutil_mkSlotFlags(unsigned long defaultFlags)
  646. {
  647. char *flags = NULL;
  648. unsigned int i;
  649. int j;
  650. for (i = 0; i < sizeof(defaultFlags) * 8; i++) {
  651. if (defaultFlags & (1UL << i)) {
  652. char *string = NULL;
  653. for (j = 0; j < nssutil_argSlotFlagTableSize; j++) {
  654. if (nssutil_argSlotFlagTable[j].value == (1UL << i)) {
  655. string = nssutil_argSlotFlagTable[j].name;
  656. break;
  657. }
  658. }
  659. if (string) {
  660. if (flags) {
  661. char *tmp;
  662. tmp = PR_smprintf("%s,%s", flags, string);
  663. PR_smprintf_free(flags);
  664. flags = tmp;
  665. } else {
  666. flags = PR_smprintf("%s", string);
  667. }
  668. }
  669. }
  670. }
  671. return flags;
  672. }
  673. /* now make the root flags */
  674. #define NSSUTIL_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts") + sizeof("hasRootTrust")
  675. static char *
  676. nssutil_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust)
  677. {
  678. char *flags = (char *)PORT_ZAlloc(NSSUTIL_MAX_ROOT_FLAG_SIZE);
  679. PRBool first = PR_TRUE;
  680. PORT_Memset(flags, 0, NSSUTIL_MAX_ROOT_FLAG_SIZE);
  681. if (hasRootCerts) {
  682. PORT_Strcat(flags, "hasRootCerts");
  683. first = PR_FALSE;
  684. }
  685. if (hasRootTrust) {
  686. if (!first)
  687. PORT_Strcat(flags, ",");
  688. PORT_Strcat(flags, "hasRootTrust");
  689. }
  690. return flags;
  691. }
  692. /* now make a full slot string */
  693. char *
  694. NSSUTIL_MkSlotString(unsigned long slotID, unsigned long defaultFlags,
  695. unsigned long timeout, unsigned char askpw_in,
  696. PRBool hasRootCerts, PRBool hasRootTrust)
  697. {
  698. char *askpw, *flags, *rootFlags, *slotString;
  699. char *flagPair, *rootFlagsPair;
  700. switch (askpw_in) {
  701. case 0xff:
  702. askpw = "every";
  703. break;
  704. case 1:
  705. askpw = "timeout";
  706. break;
  707. default:
  708. askpw = "any";
  709. break;
  710. }
  711. flags = nssutil_mkSlotFlags(defaultFlags);
  712. rootFlags = nssutil_mkRootFlags(hasRootCerts, hasRootTrust);
  713. flagPair = nssutil_formatPair("slotFlags", flags, '\'');
  714. rootFlagsPair = nssutil_formatPair("rootFlags", rootFlags, '\'');
  715. if (flags)
  716. PR_smprintf_free(flags);
  717. if (rootFlags)
  718. PORT_Free(rootFlags);
  719. if (defaultFlags & PK11_OWN_PW_DEFAULTS) {
  720. slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]",
  721. (PRUint32)slotID, flagPair, askpw, timeout,
  722. rootFlagsPair);
  723. } else {
  724. slotString = PR_smprintf("0x%08lx=[%s %s]",
  725. (PRUint32)slotID, flagPair, rootFlagsPair);
  726. }
  727. nssutil_freePair(flagPair);
  728. nssutil_freePair(rootFlagsPair);
  729. return slotString;
  730. }
  731. /************************************************************************
  732. * Parse Full module specs into: library, commonName, module parameters,
  733. * and NSS specifi parameters.
  734. */
  735. SECStatus
  736. NSSUTIL_ArgParseModuleSpecEx(const char *modulespec, char **lib, char **mod,
  737. char **parameters, char **nss,
  738. char **config)
  739. {
  740. int next;
  741. modulespec = NSSUTIL_ArgStrip(modulespec);
  742. *lib = *mod = *parameters = *nss = *config = 0;
  743. while (*modulespec) {
  744. NSSUTIL_HANDLE_STRING_ARG(modulespec, *lib, "library=", ;)
  745. NSSUTIL_HANDLE_STRING_ARG(modulespec, *mod, "name=", ;)
  746. NSSUTIL_HANDLE_STRING_ARG(modulespec, *parameters, "parameters=", ;)
  747. NSSUTIL_HANDLE_STRING_ARG(modulespec, *nss, "nss=", ;)
  748. NSSUTIL_HANDLE_STRING_ARG(modulespec, *config, "config=", ;)
  749. NSSUTIL_HANDLE_FINAL_ARG(modulespec)
  750. }
  751. return SECSuccess;
  752. }
  753. /************************************************************************
  754. * Parse Full module specs into: library, commonName, module parameters,
  755. * and NSS specifi parameters.
  756. */
  757. SECStatus
  758. NSSUTIL_ArgParseModuleSpec(const char *modulespec, char **lib, char **mod,
  759. char **parameters, char **nss)
  760. {
  761. int next;
  762. modulespec = NSSUTIL_ArgStrip(modulespec);
  763. *lib = *mod = *parameters = *nss = 0;
  764. while (*modulespec) {
  765. NSSUTIL_HANDLE_STRING_ARG(modulespec, *lib, "library=", ;)
  766. NSSUTIL_HANDLE_STRING_ARG(modulespec, *mod, "name=", ;)
  767. NSSUTIL_HANDLE_STRING_ARG(modulespec, *parameters, "parameters=", ;)
  768. NSSUTIL_HANDLE_STRING_ARG(modulespec, *nss, "nss=", ;)
  769. NSSUTIL_HANDLE_FINAL_ARG(modulespec)
  770. }
  771. return SECSuccess;
  772. }
  773. /************************************************************************
  774. * make a new module spec from it's components */
  775. char *
  776. NSSUTIL_MkModuleSpecEx(char *dllName, char *commonName, char *parameters,
  777. char *NSS,
  778. char *config)
  779. {
  780. char *moduleSpec;
  781. char *lib, *name, *param, *nss, *conf;
  782. /*
  783. * now the final spec
  784. */
  785. lib = nssutil_formatPair("library", dllName, '\"');
  786. name = nssutil_formatPair("name", commonName, '\"');
  787. param = nssutil_formatPair("parameters", parameters, '\"');
  788. nss = nssutil_formatPair("NSS", NSS, '\"');
  789. if (config) {
  790. conf = nssutil_formatPair("config", config, '\"');
  791. moduleSpec = PR_smprintf("%s %s %s %s %s", lib, name, param, nss, conf);
  792. nssutil_freePair(conf);
  793. } else {
  794. moduleSpec = PR_smprintf("%s %s %s %s", lib, name, param, nss);
  795. }
  796. nssutil_freePair(lib);
  797. nssutil_freePair(name);
  798. nssutil_freePair(param);
  799. nssutil_freePair(nss);
  800. return (moduleSpec);
  801. }
  802. /************************************************************************
  803. * make a new module spec from it's components */
  804. char *
  805. NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters,
  806. char *NSS)
  807. {
  808. return NSSUTIL_MkModuleSpecEx(dllName, commonName, parameters, NSS, NULL);
  809. }
  810. /************************************************************************
  811. * add a single flag to the Flags= section inside the spec's NSS= section */
  812. char *
  813. NSSUTIL_AddNSSFlagToModuleSpec(char *spec, char *addFlag)
  814. {
  815. const char *prefix = "flags=";
  816. const size_t prefixLen = strlen(prefix);
  817. char *lib = NULL, *name = NULL, *param = NULL, *nss = NULL, *conf = NULL;
  818. char *nss2 = NULL, *result = NULL;
  819. SECStatus rv;
  820. rv = NSSUTIL_ArgParseModuleSpecEx(spec, &lib, &name, &param, &nss, &conf);
  821. if (rv != SECSuccess) {
  822. return NULL;
  823. }
  824. if (nss && NSSUTIL_ArgHasFlag("flags", addFlag, nss)) {
  825. /* It's already there, nothing to do! */
  826. PORT_Free(lib);
  827. PORT_Free(name);
  828. PORT_Free(param);
  829. PORT_Free(nss);
  830. PORT_Free(conf);
  831. return PORT_Strdup(spec);
  832. }
  833. if (!nss || !strlen(nss)) {
  834. nss2 = PORT_Alloc(prefixLen + strlen(addFlag) + 1);
  835. PORT_Strcpy(nss2, prefix);
  836. PORT_Strcat(nss2, addFlag);
  837. } else {
  838. const char *iNss = nss;
  839. PRBool alreadyAdded = PR_FALSE;
  840. size_t maxSize = strlen(nss) + strlen(addFlag) + prefixLen + 2; /* space and null terminator */
  841. nss2 = PORT_Alloc(maxSize);
  842. *nss2 = 0;
  843. while (*iNss) {
  844. iNss = NSSUTIL_ArgStrip(iNss);
  845. if (PORT_Strncasecmp(iNss, prefix, prefixLen) == 0) {
  846. /* We found an existing Flags= section. */
  847. char *oldFlags;
  848. const char *valPtr;
  849. int valSize;
  850. valPtr = iNss + prefixLen;
  851. oldFlags = NSSUTIL_ArgFetchValue(valPtr, &valSize);
  852. iNss = valPtr + valSize;
  853. PORT_Strcat(nss2, prefix);
  854. PORT_Strcat(nss2, oldFlags);
  855. PORT_Strcat(nss2, ",");
  856. PORT_Strcat(nss2, addFlag);
  857. PORT_Strcat(nss2, " ");
  858. PORT_Free(oldFlags);
  859. alreadyAdded = PR_TRUE;
  860. iNss = NSSUTIL_ArgStrip(iNss);
  861. PORT_Strcat(nss2, iNss); /* remainder of input */
  862. break;
  863. } else {
  864. /* Append this other name=value pair and continue. */
  865. const char *startOfNext = NSSUTIL_ArgSkipParameter(iNss);
  866. PORT_Strncat(nss2, iNss, (startOfNext - iNss));
  867. if (nss2[strlen(nss2) - 1] != ' ') {
  868. PORT_Strcat(nss2, " ");
  869. }
  870. iNss = startOfNext;
  871. }
  872. iNss = NSSUTIL_ArgStrip(iNss);
  873. }
  874. if (!alreadyAdded) {
  875. /* nss wasn't empty, and it didn't contain a Flags section. We can
  876. * assume that other content from nss has already been added to
  877. * nss2, which means we already have a trailing space separator. */
  878. PORT_Strcat(nss2, prefix);
  879. PORT_Strcat(nss2, addFlag);
  880. }
  881. }
  882. result = NSSUTIL_MkModuleSpecEx(lib, name, param, nss2, conf);
  883. PORT_Free(lib);
  884. PORT_Free(name);
  885. PORT_Free(param);
  886. PORT_Free(nss);
  887. PORT_Free(nss2);
  888. PORT_Free(conf);
  889. return result;
  890. }
  891. #define NSSUTIL_ARG_FORTEZZA_FLAG "FORTEZZA"
  892. /******************************************************************************
  893. * Parse the cipher flags from the NSS parameter
  894. */
  895. void
  896. NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers, const char *cipherList)
  897. {
  898. newCiphers[0] = newCiphers[1] = 0;
  899. if ((cipherList == NULL) || (*cipherList == 0))
  900. return;
  901. for (; *cipherList; cipherList = NSSUTIL_ArgNextFlag(cipherList)) {
  902. if (PORT_Strncasecmp(cipherList, NSSUTIL_ARG_FORTEZZA_FLAG,
  903. sizeof(NSSUTIL_ARG_FORTEZZA_FLAG) - 1) == 0) {
  904. newCiphers[0] |= SECMOD_FORTEZZA_FLAG;
  905. }
  906. /* add additional flags here as necessary */
  907. /* direct bit mapping escape */
  908. if (*cipherList == 0) {
  909. if (cipherList[1] == 'l') {
  910. newCiphers[1] |= atoi(&cipherList[2]);
  911. } else {
  912. newCiphers[0] |= atoi(&cipherList[2]);
  913. }
  914. }
  915. }
  916. }
  917. /*********************************************************************
  918. * make NSS parameter...
  919. */
  920. /* First make NSS specific flags */
  921. #define MAX_FLAG_SIZE sizeof("internal") + sizeof("FIPS") + sizeof("moduleDB") + \
  922. sizeof("moduleDBOnly") + sizeof("critical")
  923. static char *
  924. nssutil_mkNSSFlags(PRBool internal, PRBool isFIPS,
  925. PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical)
  926. {
  927. char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE);
  928. PRBool first = PR_TRUE;
  929. PORT_Memset(flags, 0, MAX_FLAG_SIZE);
  930. if (internal) {
  931. PORT_Strcat(flags, "internal");
  932. first = PR_FALSE;
  933. }
  934. if (isFIPS) {
  935. if (!first)
  936. PORT_Strcat(flags, ",");
  937. PORT_Strcat(flags, "FIPS");
  938. first = PR_FALSE;
  939. }
  940. if (isModuleDB) {
  941. if (!first)
  942. PORT_Strcat(flags, ",");
  943. PORT_Strcat(flags, "moduleDB");
  944. first = PR_FALSE;
  945. }
  946. if (isModuleDBOnly) {
  947. if (!first)
  948. PORT_Strcat(flags, ",");
  949. PORT_Strcat(flags, "moduleDBOnly");
  950. first = PR_FALSE;
  951. }
  952. if (isCritical) {
  953. if (!first)
  954. PORT_Strcat(flags, ",");
  955. PORT_Strcat(flags, "critical");
  956. }
  957. return flags;
  958. }
  959. /* construct the NSS cipher flags */
  960. static char *
  961. nssutil_mkCipherFlags(unsigned long ssl0, unsigned long ssl1)
  962. {
  963. char *cipher = NULL;
  964. unsigned int i;
  965. for (i = 0; i < sizeof(ssl0) * 8; i++) {
  966. if (ssl0 & (1UL << i)) {
  967. char *string;
  968. if ((1UL << i) == SECMOD_FORTEZZA_FLAG) {
  969. string = PR_smprintf("%s", NSSUTIL_ARG_FORTEZZA_FLAG);
  970. } else {
  971. string = PR_smprintf("0h0x%08lx", 1UL << i);
  972. }
  973. if (cipher) {
  974. char *tmp;
  975. tmp = PR_smprintf("%s,%s", cipher, string);
  976. PR_smprintf_free(cipher);
  977. PR_smprintf_free(string);
  978. cipher = tmp;
  979. } else {
  980. cipher = string;
  981. }
  982. }
  983. }
  984. for (i = 0; i < sizeof(ssl0) * 8; i++) {
  985. if (ssl1 & (1UL << i)) {
  986. if (cipher) {
  987. char *tmp;
  988. tmp = PR_smprintf("%s,0l0x%08lx", cipher, 1UL << i);
  989. PR_smprintf_free(cipher);
  990. cipher = tmp;
  991. } else {
  992. cipher = PR_smprintf("0l0x%08lx", 1UL << i);
  993. }
  994. }
  995. }
  996. return cipher;
  997. }
  998. /* Assemble a full NSS string. */
  999. char *
  1000. NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal,
  1001. PRBool isFIPS, PRBool isModuleDB, PRBool isModuleDBOnly,
  1002. PRBool isCritical, unsigned long trustOrder,
  1003. unsigned long cipherOrder, unsigned long ssl0, unsigned long ssl1)
  1004. {
  1005. int slotLen, i;
  1006. char *slotParams, *ciphers, *nss, *nssFlags;
  1007. const char *tmp;
  1008. char *trustOrderPair, *cipherOrderPair, *slotPair, *cipherPair, *flagPair;
  1009. /* now let's build up the string
  1010. * first the slot infos
  1011. */
  1012. slotLen = 0;
  1013. for (i = 0; i < (int)slotCount; i++) {
  1014. slotLen += PORT_Strlen(slotStrings[i]) + 1;
  1015. }
  1016. slotLen += 1; /* space for the final NULL */
  1017. slotParams = (char *)PORT_ZAlloc(slotLen);
  1018. PORT_Memset(slotParams, 0, slotLen);
  1019. for (i = 0; i < (int)slotCount; i++) {
  1020. PORT_Strcat(slotParams, slotStrings[i]);
  1021. PORT_Strcat(slotParams, " ");
  1022. PR_smprintf_free(slotStrings[i]);
  1023. slotStrings[i] = NULL;
  1024. }
  1025. /*
  1026. * now the NSS structure
  1027. */
  1028. nssFlags = nssutil_mkNSSFlags(internal, isFIPS, isModuleDB, isModuleDBOnly,
  1029. isCritical);
  1030. /* for now only the internal module is critical */
  1031. ciphers = nssutil_mkCipherFlags(ssl0, ssl1);
  1032. trustOrderPair = nssutil_formatIntPair("trustOrder", trustOrder,
  1033. NSSUTIL_DEFAULT_TRUST_ORDER);
  1034. cipherOrderPair = nssutil_formatIntPair("cipherOrder", cipherOrder,
  1035. NSSUTIL_DEFAULT_CIPHER_ORDER);
  1036. slotPair = nssutil_formatPair("slotParams", slotParams, '{'); /* } */
  1037. if (slotParams)
  1038. PORT_Free(slotParams);
  1039. cipherPair = nssutil_formatPair("ciphers", ciphers, '\'');
  1040. if (ciphers)
  1041. PR_smprintf_free(ciphers);
  1042. flagPair = nssutil_formatPair("Flags", nssFlags, '\'');
  1043. if (nssFlags)
  1044. PORT_Free(nssFlags);
  1045. nss = PR_smprintf("%s %s %s %s %s", trustOrderPair,
  1046. cipherOrderPair, slotPair, cipherPair, flagPair);
  1047. nssutil_freePair(trustOrderPair);
  1048. nssutil_freePair(cipherOrderPair);
  1049. nssutil_freePair(slotPair);
  1050. nssutil_freePair(cipherPair);
  1051. nssutil_freePair(flagPair);
  1052. tmp = NSSUTIL_ArgStrip(nss);
  1053. if (*tmp == '\0') {
  1054. PR_smprintf_free(nss);
  1055. nss = NULL;
  1056. }
  1057. return nss;
  1058. }
  1059. /*****************************************************************************
  1060. *
  1061. * Private calls for use by softoken and utilmod.c
  1062. */
  1063. #define SQLDB "sql:"
  1064. #define EXTERNDB "extern:"
  1065. #define LEGACY "dbm:"
  1066. #define MULTIACCESS "multiaccess:"
  1067. #define SECMOD_DB "secmod.db"
  1068. const char *
  1069. _NSSUTIL_EvaluateConfigDir(const char *configdir,
  1070. NSSDBType *pdbType, char **appName)
  1071. {
  1072. NSSDBType dbType;
  1073. PRBool checkEnvDefaultDB = PR_FALSE;
  1074. *appName = NULL;
  1075. /* force the default */
  1076. dbType = NSS_DB_TYPE_SQL;
  1077. if (configdir == NULL) {
  1078. checkEnvDefaultDB = PR_TRUE;
  1079. } else if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS) - 1) == 0) {
  1080. char *cdir;
  1081. dbType = NSS_DB_TYPE_MULTIACCESS;
  1082. *appName = PORT_Strdup(configdir + sizeof(MULTIACCESS) - 1);
  1083. if (*appName == NULL) {
  1084. return configdir;
  1085. }
  1086. cdir = *appName;
  1087. while (*cdir && *cdir != ':') {
  1088. cdir++;
  1089. }
  1090. if (*cdir == ':') {
  1091. *cdir = 0;
  1092. cdir++;
  1093. }
  1094. configdir = cdir;
  1095. } else if (PORT_Strncmp(configdir, SQLDB, sizeof(SQLDB) - 1) == 0) {
  1096. dbType = NSS_DB_TYPE_SQL;
  1097. configdir = configdir + sizeof(SQLDB) - 1;
  1098. } else if (PORT_Strncmp(configdir, EXTERNDB, sizeof(EXTERNDB) - 1) == 0) {
  1099. dbType = NSS_DB_TYPE_EXTERN;
  1100. configdir = configdir + sizeof(EXTERNDB) - 1;
  1101. } else if (PORT_Strncmp(configdir, LEGACY, sizeof(LEGACY) - 1) == 0) {
  1102. dbType = NSS_DB_TYPE_LEGACY;
  1103. configdir = configdir + sizeof(LEGACY) - 1;
  1104. } else {
  1105. checkEnvDefaultDB = PR_TRUE;
  1106. }
  1107. /* look up the default from the environment */
  1108. if (checkEnvDefaultDB) {
  1109. char *defaultType = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE");
  1110. if (defaultType != NULL) {
  1111. if (PORT_Strncmp(defaultType, SQLDB, sizeof(SQLDB) - 2) == 0) {
  1112. dbType = NSS_DB_TYPE_SQL;
  1113. } else if (PORT_Strncmp(defaultType, EXTERNDB, sizeof(EXTERNDB) - 2) == 0) {
  1114. dbType = NSS_DB_TYPE_EXTERN;
  1115. } else if (PORT_Strncmp(defaultType, LEGACY, sizeof(LEGACY) - 2) == 0) {
  1116. dbType = NSS_DB_TYPE_LEGACY;
  1117. }
  1118. }
  1119. }
  1120. /* if the caller has already set a type, don't change it */
  1121. if (*pdbType == NSS_DB_TYPE_NONE) {
  1122. *pdbType = dbType;
  1123. }
  1124. return configdir;
  1125. }
  1126. char *
  1127. _NSSUTIL_GetSecmodName(const char *param, NSSDBType *dbType, char **appName,
  1128. char **filename, PRBool *rw)
  1129. {
  1130. int next;
  1131. char *configdir = NULL;
  1132. char *secmodName = NULL;
  1133. char *value = NULL;
  1134. const char *save_params = param;
  1135. const char *lconfigdir;
  1136. PRBool noModDB = PR_FALSE;
  1137. param = NSSUTIL_ArgStrip(param);
  1138. while (*param) {
  1139. NSSUTIL_HANDLE_STRING_ARG(param, configdir, "configDir=", ;)
  1140. NSSUTIL_HANDLE_STRING_ARG(param, secmodName, "secmod=", ;)
  1141. NSSUTIL_HANDLE_FINAL_ARG(param)
  1142. }
  1143. *rw = PR_TRUE;
  1144. if (NSSUTIL_ArgHasFlag("flags", "readOnly", save_params)) {
  1145. *rw = PR_FALSE;
  1146. }
  1147. if (!secmodName || *secmodName == '\0') {
  1148. if (secmodName)
  1149. PORT_Free(secmodName);
  1150. secmodName = PORT_Strdup(SECMOD_DB);
  1151. }
  1152. *filename = secmodName;
  1153. lconfigdir = _NSSUTIL_EvaluateConfigDir(configdir, dbType, appName);
  1154. if (NSSUTIL_ArgHasFlag("flags", "noModDB", save_params)) {
  1155. /* there isn't a module db, don't load the legacy support */
  1156. noModDB = PR_TRUE;
  1157. *dbType = NSS_DB_TYPE_SQL;
  1158. PORT_Free(*filename);
  1159. *filename = NULL;
  1160. *rw = PR_FALSE;
  1161. }
  1162. /* only use the renamed secmod for legacy databases */
  1163. if ((*dbType != NSS_DB_TYPE_LEGACY) &&
  1164. (*dbType != NSS_DB_TYPE_MULTIACCESS) &&
  1165. !NSSUTIL_ArgHasFlag("flags", "forceSecmodChoice", save_params)) {
  1166. secmodName = "pkcs11.txt";
  1167. }
  1168. if (noModDB) {
  1169. value = NULL;
  1170. } else if (lconfigdir && lconfigdir[0] != '\0') {
  1171. value = PR_smprintf("%s" NSSUTIL_PATH_SEPARATOR "%s",
  1172. lconfigdir, secmodName);
  1173. } else {
  1174. value = PR_smprintf("%s", secmodName);
  1175. }
  1176. if (configdir)
  1177. PORT_Free(configdir);
  1178. return value;
  1179. }