Coverage Report

Created: 2025-07-01 06:25

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