Coverage Report

Created: 2025-08-18 06:34

/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
90
{
21
90
    switch (c) {
22
75
        case '\'':
23
75
            return c;
24
6
        case '\"':
25
6
            return c;
26
0
        case '<':
27
0
            return '>';
28
2
        case '{':
29
2
            return '}';
30
5
        case '[':
31
5
            return ']';
32
2
        case '(':
33
2
            return ')';
34
0
        default:
35
0
            break;
36
90
    }
37
0
    return ' ';
38
90
}
39
40
PRBool
41
NSSUTIL_ArgIsBlank(char c)
42
3.36k
{
43
3.36k
    return isspace((unsigned char)c);
44
3.36k
}
45
46
PRBool
47
NSSUTIL_ArgIsEscape(char c)
48
6.98k
{
49
6.98k
    return c == '\\';
50
6.98k
}
51
52
PRBool
53
NSSUTIL_ArgIsQuote(char c)
54
219
{
55
219
    switch (c) {
56
86
        case '\'':
57
98
        case '\"':
58
98
        case '<':
59
101
        case '{': /* } end curly to keep vi bracket matching working */
60
104
        case '(': /* ) */
61
110
        case '[': /* ] */
62
110
            return PR_TRUE;
63
109
        default:
64
109
            break;
65
219
    }
66
109
    return PR_FALSE;
67
219
}
68
69
const char *
70
NSSUTIL_ArgStrip(const char *c)
71
121
{
72
205
    while (*c && NSSUTIL_ArgIsBlank(*c))
73
84
        c++;
74
121
    return c;
75
121
}
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
155
{
84
155
    char endChar = ' ';
85
155
    PRBool lastEscape = PR_FALSE;
86
87
155
    if (NSSUTIL_ArgIsQuote(*string)) {
88
90
        endChar = NSSUTIL_ArgGetPair(*string);
89
90
        string++;
90
90
    }
91
92
4.10k
    for (; *string; string++) {
93
4.08k
        if (lastEscape) {
94
0
            lastEscape = PR_FALSE;
95
0
            continue;
96
0
        }
97
4.08k
        if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
98
0
            lastEscape = PR_TRUE;
99
0
            continue;
100
0
        }
101
4.08k
        if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string))
102
43
            break;
103
4.04k
        if (*string == endChar) {
104
90
            break;
105
90
        }
106
4.04k
    }
107
108
155
    return string;
109
155
}
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
65
{
118
65
    const char *end = NSSUTIL_ArgFindEnd(string);
119
65
    char *retString, *copyString;
120
65
    PRBool lastEscape = PR_FALSE;
121
65
    int len;
122
123
65
    len = end - string;
124
65
    if (len == 0) {
125
1
        *pcount = 0;
126
1
        return NULL;
127
1
    }
128
129
64
    copyString = retString = (char *)PORT_Alloc(len + 1);
130
131
64
    if (*end)
132
48
        len++;
133
64
    *pcount = len;
134
64
    if (retString == NULL)
135
0
        return NULL;
136
137
64
    if (NSSUTIL_ArgIsQuote(*string))
138
20
        string++;
139
2.96k
    for (; string < end; string++) {
140
2.90k
        if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
141
0
            lastEscape = PR_TRUE;
142
0
            continue;
143
0
        }
144
2.90k
        lastEscape = PR_FALSE;
145
2.90k
        *copyString++ = *string;
146
2.90k
    }
147
64
    *copyString = 0;
148
64
    return retString;
149
64
}
150
151
/*
152
 * point to the next parameter in string
153
 */
154
const char *
155
NSSUTIL_ArgSkipParameter(const char *string)
156
90
{
157
90
    const char *end;
158
    /* look for the end of the <name>= */
159
885
    for (; *string; string++) {
160
885
        if (*string == '=') {
161
90
            string++;
162
90
            break;
163
90
        }
164
795
        if (NSSUTIL_ArgIsBlank(*string))
165
0
            return (string);
166
795
    }
167
168
90
    end = NSSUTIL_ArgFindEnd(string);
169
90
    if (*end)
170
84
        end++;
171
90
    return end;
172
90
}
173
174
/*
175
 * get the value from that tag value pair.
176
 */
177
char *
178
NSSUTIL_ArgGetParamValue(const char *paramName, const char *parameters)
179
52
{
180
52
    char searchValue[256];
181
52
    size_t paramLen = strlen(paramName);
182
52
    char *returnValue = NULL;
183
52
    int next;
184
185
52
    if ((parameters == NULL) || (*parameters == 0))
186
0
        return NULL;
187
188
52
    PORT_Assert(paramLen + 2 < sizeof(searchValue));
189
190
52
    PORT_Strcpy(searchValue, paramName);
191
52
    PORT_Strcat(searchValue, "=");
192
123
    while (*parameters) {
193
116
        if (PORT_Strncasecmp(parameters, searchValue, paramLen + 1) == 0) {
194
45
            parameters += paramLen + 1;
195
45
            returnValue = NSSUTIL_ArgFetchValue(parameters, &next);
196
45
            break;
197
71
        } else {
198
71
            parameters = NSSUTIL_ArgSkipParameter(parameters);
199
71
        }
200
71
        parameters = NSSUTIL_ArgStrip(parameters);
201
71
    }
202
52
    return returnValue;
203
52
}
204
205
/*
206
 * find the next flag in the parameter list
207
 */
208
const char *
209
NSSUTIL_ArgNextFlag(const char *flags)
210
137
{
211
1.32k
    for (; *flags; flags++) {
212
1.30k
        if (*flags == ',') {
213
114
            flags++;
214
114
            break;
215
114
        }
216
1.30k
    }
217
137
    return flags;
218
137
}
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
41
{
226
41
    char *flags;
227
41
    const char *index;
228
41
    int len = strlen(flag);
229
41
    PRBool found = PR_FALSE;
230
231
41
    flags = NSSUTIL_ArgGetParamValue(label, parameters);
232
41
    if (flags == NULL)
233
2
        return PR_FALSE;
234
235
158
    for (index = flags; *index; index = NSSUTIL_ArgNextFlag(index)) {
236
136
        if (PORT_Strncasecmp(index, flag, len) == 0) {
237
17
            found = PR_TRUE;
238
17
            break;
239
17
        }
240
136
    }
241
39
    PORT_Free(flags);
242
39
    return found;
243
41
}
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
4
{
251
4
    int radix = 10;
252
4
    unsigned long value = 0;
253
4
    long retValue = 0;
254
4
    int sign = 1;
255
4
    int digit;
256
257
4
    if (num == NULL)
258
0
        return retValue;
259
260
4
    num = NSSUTIL_ArgStrip(num);
261
262
4
    if (*num == '-') {
263
0
        sign = -1;
264
0
        num++;
265
0
    }
266
267
4
    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
12
    for (; *num; num++) {
277
8
        if (isdigit((unsigned char)*num)) {
278
8
            digit = *num - '0';
279
8
        } 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
8
        if (digit >= radix)
287
0
            break;
288
8
        value = value * radix + digit;
289
8
    }
290
291
4
    retValue = ((int)value) * sign;
292
4
    return retValue;
293
4
}
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
1
{
302
1
    char *name = NULL;
303
1
    const char *string;
304
1
    int len;
305
306
    /* look for the end of the <label>= */
307
2
    for (string = inString; *string; string++) {
308
2
        if (*string == '=') {
309
1
            break;
310
1
        }
311
1
        if (NSSUTIL_ArgIsBlank(*string))
312
0
            break;
313
1
    }
314
315
1
    len = string - inString;
316
317
1
    *next = len;
318
1
    if (*string == '=')
319
1
        (*next) += 1;
320
1
    if (len > 0) {
321
1
        name = PORT_Alloc(len + 1);
322
1
        PORT_Strncpy(name, inString, len);
323
1
        name[len] = 0;
324
1
    }
325
1
    return name;
326
1
}
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
5
{
335
5
    char *value;
336
5
    long retValue;
337
5
    if (isdefault)
338
0
        *isdefault = PR_FALSE;
339
340
5
    value = NSSUTIL_ArgGetParamValue(label, params);
341
5
    if (value == NULL) {
342
2
        if (isdefault)
343
0
            *isdefault = PR_TRUE;
344
2
        return defValue;
345
2
    }
346
3
    retValue = NSSUTIL_ArgDecodeNumber(value);
347
3
    if (value)
348
3
        PORT_Free(value);
349
350
3
    return retValue;
351
5
}
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
19
{
360
19
    int escapes = 0, size = 0;
361
19
    const char *src;
362
363
19
    size = addquotes ? 2 : 0;
364
215
    for (src = string; *src; src++) {
365
196
        if ((*src == quote) || (*src == '\\'))
366
0
            escapes++;
367
196
        size++;
368
196
    }
369
19
    return size + escapes + 1;
370
19
}
371
372
static char *
373
nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes)
374
19
{
375
19
    char *newString = 0;
376
19
    int size = 0;
377
19
    const char *src;
378
19
    char *dest;
379
380
19
    size = nssutil_escapeQuotesSize(string, quote, addquotes);
381
382
19
    dest = newString = PORT_ZAlloc(size);
383
19
    if (newString == NULL) {
384
0
        return NULL;
385
0
    }
386
387
19
    if (addquotes)
388
1
        *dest++ = quote;
389
215
    for (src = string; *src; src++, dest++) {
390
196
        if ((*src == '\\') || (*src == quote)) {
391
0
            *dest++ = '\\';
392
0
        }
393
196
        *dest = *src;
394
196
    }
395
19
    if (addquotes)
396
1
        *dest = quote;
397
398
19
    return newString;
399
19
}
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
1
{
422
1
    return nssutil_escapeQuotes(string, quote, PR_TRUE);
423
1
}
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
9
{
446
9
    char *round1 = NULL;
447
9
    char *retValue = NULL;
448
9
    if (string == NULL) {
449
0
        goto done;
450
0
    }
451
9
    round1 = nssutil_escapeQuotes(string, quote1, PR_FALSE);
452
9
    if (round1) {
453
9
        retValue = nssutil_escapeQuotes(round1, quote2, PR_FALSE);
454
9
        PORT_Free(round1);
455
9
    }
456
457
9
done:
458
9
    if (retValue == NULL) {
459
0
        retValue = PORT_Strdup("");
460
0
    }
461
9
    return retValue;
462
9
}
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
1
{
622
1
    char *flags;
623
1
    const char *index;
624
1
    unsigned long retValue = 0;
625
1
    int i;
626
1
    PRBool all = PR_FALSE;
627
628
1
    flags = NSSUTIL_ArgGetParamValue(label, params);
629
1
    if (flags == NULL)
630
0
        return 0;
631
632
1
    if (PORT_Strcasecmp(flags, "all") == 0)
633
0
        all = PR_TRUE;
634
635
19
    for (index = flags; *index; index = NSSUTIL_ArgNextFlag(index)) {
636
414
        for (i = 0; i < nssutil_argSlotFlagTableSize; i++) {
637
396
            if (all ||
638
396
                (PORT_Strncasecmp(index, nssutil_argSlotFlagTable[i].name,
639
396
                                  nssutil_argSlotFlagTable[i].len) == 0)) {
640
18
                retValue |= nssutil_argSlotFlagTable[i].value;
641
18
            }
642
396
        }
643
18
    }
644
1
    PORT_Free(flags);
645
1
    return retValue;
646
1
}
647
648
/* parse a single slot specific parameter */
649
static void
650
nssutil_argDecodeSingleSlotInfo(char *name, char *params,
651
                                struct NSSUTILPreSlotInfoStr *slotInfo)
652
1
{
653
1
    char *askpw;
654
655
1
    slotInfo->slotID = NSSUTIL_ArgDecodeNumber(name);
656
1
    slotInfo->defaultFlags = NSSUTIL_ArgParseSlotFlags("slotFlags", params);
657
1
    slotInfo->timeout = NSSUTIL_ArgReadLong("timeout", params, 0, NULL);
658
659
1
    askpw = NSSUTIL_ArgGetParamValue("askpw", params);
660
1
    slotInfo->askpw = 0;
661
662
1
    if (askpw) {
663
1
        if (PORT_Strcasecmp(askpw, "every") == 0) {
664
0
            slotInfo->askpw = -1;
665
1
        } else if (PORT_Strcasecmp(askpw, "timeout") == 0) {
666
0
            slotInfo->askpw = 1;
667
0
        }
668
1
        PORT_Free(askpw);
669
1
        slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS;
670
1
    }
671
1
    slotInfo->hasRootCerts = NSSUTIL_ArgHasFlag("rootFlags", "hasRootCerts",
672
1
                                                params);
673
1
    slotInfo->hasRootTrust = NSSUTIL_ArgHasFlag("rootFlags", "hasRootTrust",
674
1
                                                params);
675
1
}
676
677
/* parse all the slot specific parameters. */
678
struct NSSUTILPreSlotInfoStr *
679
NSSUTIL_ArgParseSlotInfo(PLArenaPool *arena, const char *slotParams,
680
                         int *retCount)
681
2
{
682
2
    const char *slotIndex;
683
2
    struct NSSUTILPreSlotInfoStr *slotInfo = NULL;
684
2
    int i = 0, count = 0, next;
685
686
2
    *retCount = 0;
687
2
    if ((slotParams == NULL) || (*slotParams == 0))
688
1
        return NULL;
689
690
    /* first count the number of slots */
691
2
    for (slotIndex = NSSUTIL_ArgStrip(slotParams); *slotIndex;
692
1
         slotIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(slotIndex))) {
693
1
        count++;
694
1
    }
695
696
    /* get the data structures */
697
1
    if (arena) {
698
1
        slotInfo = PORT_ArenaZNewArray(arena,
699
1
                                       struct NSSUTILPreSlotInfoStr, count);
700
1
    } else {
701
0
        slotInfo = PORT_ZNewArray(struct NSSUTILPreSlotInfoStr, count);
702
0
    }
703
1
    if (slotInfo == NULL)
704
0
        return NULL;
705
706
1
    for (slotIndex = NSSUTIL_ArgStrip(slotParams), i = 0;
707
2
         *slotIndex && i < count;) {
708
1
        char *name;
709
1
        name = NSSUTIL_ArgGetLabel(slotIndex, &next);
710
1
        slotIndex += next;
711
712
1
        if (!NSSUTIL_ArgIsBlank(*slotIndex)) {
713
1
            char *args = NSSUTIL_ArgFetchValue(slotIndex, &next);
714
1
            slotIndex += next;
715
1
            if (args) {
716
1
                nssutil_argDecodeSingleSlotInfo(name, args, &slotInfo[i]);
717
1
                i++;
718
1
                PORT_Free(args);
719
1
            }
720
1
        }
721
1
        if (name)
722
1
            PORT_Free(name);
723
1
        slotIndex = NSSUTIL_ArgStrip(slotIndex);
724
1
    }
725
1
    *retCount = i;
726
1
    return slotInfo;
727
1
}
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
2
{
837
2
    int next;
838
2
    modulespec = NSSUTIL_ArgStrip(modulespec);
839
840
2
    *lib = *mod = *parameters = *nss = *config = 0;
841
842
9
    while (*modulespec) {
843
7
        NSSUTIL_HANDLE_STRING_ARG(modulespec, *lib, "library=", ;)
844
6
        NSSUTIL_HANDLE_STRING_ARG(modulespec, *mod, "name=", ;)
845
4
        NSSUTIL_HANDLE_STRING_ARG(modulespec, *parameters, "parameters=", ;)
846
2
        NSSUTIL_HANDLE_STRING_ARG(modulespec, *nss, "nss=", ;)
847
0
        NSSUTIL_HANDLE_STRING_ARG(modulespec, *config, "config=", ;)
848
0
        NSSUTIL_HANDLE_FINAL_ARG(modulespec)
849
7
    }
850
2
    return SECSuccess;
851
2
}
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
2
{
1009
2
    newCiphers[0] = newCiphers[1] = 0;
1010
2
    if ((cipherList == NULL) || (*cipherList == 0))
1011
2
        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
4
#define SQLDB "sql:"
1189
4
#define EXTERNDB "extern:"
1190
4
#define LEGACY "dbm:"
1191
4
#define MULTIACCESS "multiaccess:"
1192
2
#define SECMOD_DB "secmod.db"
1193
const char *
1194
_NSSUTIL_EvaluateConfigDir(const char *configdir,
1195
                           NSSDBType *pdbType, char **appName)
1196
2
{
1197
2
    NSSDBType dbType;
1198
2
    PRBool checkEnvDefaultDB = PR_FALSE;
1199
2
    *appName = NULL;
1200
    /* force the default */
1201
2
    dbType = NSS_DB_TYPE_SQL;
1202
2
    if (configdir == NULL) {
1203
0
        checkEnvDefaultDB = PR_TRUE;
1204
2
    } 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
2
    } 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
2
    } 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
2
    } 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
2
    } else {
1231
2
        checkEnvDefaultDB = PR_TRUE;
1232
2
    }
1233
1234
    /* look up the default from the environment */
1235
2
    if (checkEnvDefaultDB) {
1236
2
        char *defaultType = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE");
1237
2
        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
2
    }
1247
    /* if the caller has already set a type, don't change it */
1248
2
    if (*pdbType == NSS_DB_TYPE_NONE) {
1249
2
        *pdbType = dbType;
1250
2
    }
1251
2
    return configdir;
1252
2
}
1253
1254
char *
1255
_NSSUTIL_GetSecmodName(const char *param, NSSDBType *dbType, char **appName,
1256
                       char **filename, PRBool *rw)
1257
2
{
1258
2
    int next;
1259
2
    char *configdir = NULL;
1260
2
    char *secmodName = NULL;
1261
2
    char *value = NULL;
1262
2
    const char *save_params = param;
1263
2
    const char *lconfigdir;
1264
2
    PRBool noModDB = PR_FALSE;
1265
2
    param = NSSUTIL_ArgStrip(param);
1266
1267
22
    while (*param) {
1268
20
        NSSUTIL_HANDLE_STRING_ARG(param, configdir, "configDir=", ;)
1269
18
        NSSUTIL_HANDLE_STRING_ARG(param, secmodName, "secmod=", ;)
1270
16
        NSSUTIL_HANDLE_FINAL_ARG(param)
1271
20
    }
1272
1273
2
    *rw = PR_TRUE;
1274
2
    if (NSSUTIL_ArgHasFlag("flags", "readOnly", save_params)) {
1275
2
        *rw = PR_FALSE;
1276
2
    }
1277
1278
2
    if (!secmodName || *secmodName == '\0') {
1279
2
        if (secmodName)
1280
2
            PORT_Free(secmodName);
1281
2
        secmodName = PORT_Strdup(SECMOD_DB);
1282
2
    }
1283
1284
2
    *filename = secmodName;
1285
2
    lconfigdir = _NSSUTIL_EvaluateConfigDir(configdir, dbType, appName);
1286
1287
2
    if (NSSUTIL_ArgHasFlag("flags", "noModDB", save_params)) {
1288
        /* there isn't a module db, don't load the legacy support */
1289
2
        noModDB = PR_TRUE;
1290
2
        *dbType = NSS_DB_TYPE_SQL;
1291
2
        PORT_Free(*filename);
1292
2
        *filename = NULL;
1293
2
        *rw = PR_FALSE;
1294
2
    }
1295
1296
    /* only use the renamed secmod for legacy databases */
1297
2
    if ((*dbType != NSS_DB_TYPE_LEGACY) &&
1298
2
        (*dbType != NSS_DB_TYPE_MULTIACCESS) &&
1299
2
        !NSSUTIL_ArgHasFlag("flags", "forceSecmodChoice", save_params)) {
1300
2
        secmodName = "pkcs11.txt";
1301
2
    }
1302
1303
2
    if (noModDB) {
1304
2
        value = NULL;
1305
2
    } 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
2
    if (configdir)
1312
2
        PORT_Free(configdir);
1313
2
    return value;
1314
2
}