~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/softoken/dbinit.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * NSS utility functions
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public
 
5
 * License Version 1.1 (the "License"); you may not use this file
 
6
 * except in compliance with the License. You may obtain a copy of
 
7
 * the License at http://www.mozilla.org/MPL/
 
8
 * 
 
9
 * Software distributed under the License is distributed on an "AS
 
10
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
11
 * implied. See the License for the specific language governing
 
12
 * rights and limitations under the License.
 
13
 * 
 
14
 * The Original Code is the Netscape security libraries.
 
15
 * 
 
16
 * The Initial Developer of the Original Code is Netscape
 
17
 * Communications Corporation.  Portions created by Netscape are 
 
18
 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 
19
 * Rights Reserved.
 
20
 * 
 
21
 * Contributor(s):
 
22
 * 
 
23
 * Alternatively, the contents of this file may be used under the
 
24
 * terms of the GNU General Public License Version 2 or later (the
 
25
 * "GPL"), in which case the provisions of the GPL are applicable 
 
26
 * instead of those above.  If you wish to allow use of your 
 
27
 * version of this file only under the terms of the GPL and not to
 
28
 * allow others to use your version of this file under the MPL,
 
29
 * indicate your decision by deleting the provisions above and
 
30
 * replace them with the notice and other provisions required by
 
31
 * the GPL.  If you do not delete the provisions above, a recipient
 
32
 * may use your version of this file under either the MPL or the
 
33
 * GPL.
 
34
 *
 
35
 # $Id: dbinit.c,v 1.20 2003/05/30 23:31:30 wtc%netscape.com Exp $
 
36
 */
 
37
 
 
38
#include <ctype.h>
 
39
#include "seccomon.h"
 
40
#include "prinit.h"
 
41
#include "prprf.h"
 
42
#include "prmem.h"
 
43
#include "pcertt.h"
 
44
#include "lowkeyi.h"
 
45
#include "pcert.h"
 
46
#include "cdbhdl.h"
 
47
#include "pkcs11i.h"
 
48
 
 
49
static char *
 
50
pk11_certdb_name_cb(void *arg, int dbVersion)
 
51
{
 
52
    const char *configdir = (const char *)arg;
 
53
    const char *dbver;
 
54
    char *smpname = NULL;
 
55
    char *dbname = NULL;
 
56
 
 
57
    switch (dbVersion) {
 
58
      case 8:
 
59
        dbver = "8";
 
60
        break;
 
61
      case 7:
 
62
        dbver = "7";
 
63
        break;
 
64
      case 6:
 
65
        dbver = "6";
 
66
        break;
 
67
      case 5:
 
68
        dbver = "5";
 
69
        break;
 
70
      case 4:
 
71
      default:
 
72
        dbver = "";
 
73
        break;
 
74
    }
 
75
 
 
76
    /* make sure we return something allocated with PORT_ so we have properly
 
77
     * matched frees at the end */
 
78
    smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
 
79
    if (smpname) {
 
80
        dbname = PORT_Strdup(smpname);
 
81
        PR_smprintf_free(smpname);
 
82
    }
 
83
    return dbname;
 
84
}
 
85
    
 
86
static char *
 
87
pk11_keydb_name_cb(void *arg, int dbVersion)
 
88
{
 
89
    const char *configdir = (const char *)arg;
 
90
    const char *dbver;
 
91
    char *smpname = NULL;
 
92
    char *dbname = NULL;
 
93
    
 
94
    switch (dbVersion) {
 
95
      case 4:
 
96
        dbver = "4";
 
97
        break;
 
98
      case 3:
 
99
        dbver = "3";
 
100
        break;
 
101
      case 1:
 
102
        dbver = "1";
 
103
        break;
 
104
      case 2:
 
105
      default:
 
106
        dbver = "";
 
107
        break;
 
108
    }
 
109
 
 
110
    smpname = PR_smprintf(KEY_DB_FMT, configdir, dbver);
 
111
    if (smpname) {
 
112
        dbname = PORT_Strdup(smpname);
 
113
        PR_smprintf_free(smpname);
 
114
    }
 
115
    return dbname;
 
116
}
 
117
 
 
118
/* for now... we need to define vendor specific codes here.
 
119
 */
 
120
#define CKR_CERTDB_FAILED       CKR_DEVICE_ERROR
 
121
#define CKR_KEYDB_FAILED        CKR_DEVICE_ERROR
 
122
 
 
123
const char *
 
124
pk11_EvaluateConfigDir(const char *configdir,char **appName)
 
125
{
 
126
    if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
 
127
        char *cdir;
 
128
 
 
129
        *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
 
130
        if (*appName == NULL) {
 
131
            return configdir;
 
132
        }
 
133
        cdir = *appName;
 
134
        while (*cdir && *cdir != ':') {
 
135
            cdir++;
 
136
        }
 
137
        if (*cdir == ':') {
 
138
           *cdir = 0;
 
139
           cdir++;
 
140
        }
 
141
        configdir = cdir;
 
142
    }
 
143
    return configdir;
 
144
}
 
145
 
 
146
static CK_RV
 
147
pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
 
148
                                            NSSLOWCERTCertDBHandle **certdbPtr)
 
149
{
 
150
    NSSLOWCERTCertDBHandle *certdb = NULL;
 
151
    CK_RV        crv = CKR_CERTDB_FAILED;
 
152
    SECStatus    rv;
 
153
    char * name = NULL;
 
154
    char * appName = NULL;
 
155
 
 
156
    if (prefix == NULL) {
 
157
        prefix = "";
 
158
    }
 
159
 
 
160
    configdir = pk11_EvaluateConfigDir(configdir, &appName);
 
161
 
 
162
    name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
 
163
    if (name == NULL) goto loser;
 
164
 
 
165
    certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle));
 
166
    if (certdb == NULL) 
 
167
        goto loser;
 
168
 
 
169
/* fix when we get the DB in */
 
170
    rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
 
171
                                pk11_certdb_name_cb, (void *)name, PR_FALSE);
 
172
    if (rv == SECSuccess) {
 
173
        crv = CKR_OK;
 
174
        *certdbPtr = certdb;
 
175
        certdb = NULL;
 
176
    }
 
177
loser: 
 
178
    if (certdb) PR_Free(certdb);
 
179
    if (name) PR_smprintf_free(name);
 
180
    if (appName) PORT_Free(appName);
 
181
    return crv;
 
182
}
 
183
 
 
184
static CK_RV
 
185
pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
 
186
                                                NSSLOWKEYDBHandle **keydbPtr)
 
187
{
 
188
    NSSLOWKEYDBHandle *keydb;
 
189
    char * name = NULL;
 
190
    char * appName = NULL;
 
191
 
 
192
    if (prefix == NULL) {
 
193
        prefix = "";
 
194
    }
 
195
    configdir = pk11_EvaluateConfigDir(configdir, &appName);
 
196
 
 
197
    name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);      
 
198
    if (name == NULL) 
 
199
        return SECFailure;
 
200
    keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix, 
 
201
                                        pk11_keydb_name_cb, (void *)name);
 
202
    PR_smprintf_free(name);
 
203
    if (appName) PORT_Free(appName);
 
204
    if (keydb == NULL)
 
205
        return CKR_KEYDB_FAILED;
 
206
    *keydbPtr = keydb;
 
207
 
 
208
    return CKR_OK;
 
209
}
 
210
 
 
211
 
 
212
/*
 
213
 * OK there are now lots of options here, lets go through them all:
 
214
 *
 
215
 * configdir - base directory where all the cert, key, and module datbases live.
 
216
 * certPrefix - prefix added to the beginning of the cert database example: "
 
217
 *                      "https-server1-"
 
218
 * keyPrefix - prefix added to the beginning of the key database example: "
 
219
 *                      "https-server1-"
 
220
 * secmodName - name of the security module database (usually "secmod.db").
 
221
 * readOnly - Boolean: true if the databases are to be openned read only.
 
222
 * nocertdb - Don't open the cert DB and key DB's, just initialize the 
 
223
 *                      Volatile certdb.
 
224
 * nomoddb - Don't open the security module DB, just initialize the 
 
225
 *                      PKCS #11 module.
 
226
 * forceOpen - Continue to force initializations even if the databases cannot
 
227
 *                      be opened.
 
228
 */
 
229
CK_RV
 
230
pk11_DBInit(const char *configdir, const char *certPrefix, 
 
231
            const char *keyPrefix, PRBool readOnly, 
 
232
            PRBool noCertDB, PRBool noKeyDB, PRBool forceOpen,
 
233
            NSSLOWCERTCertDBHandle **certdbPtr, NSSLOWKEYDBHandle **keydbPtr)
 
234
{
 
235
    CK_RV crv = CKR_OK;
 
236
 
 
237
 
 
238
    if (!noCertDB) {
 
239
        crv = pk11_OpenCertDB(configdir, certPrefix, readOnly, certdbPtr);
 
240
        if (crv != CKR_OK) {
 
241
            if (!forceOpen) goto loser;
 
242
            crv = CKR_OK;
 
243
        }
 
244
    }
 
245
    if (!noKeyDB) {
 
246
 
 
247
        crv = pk11_OpenKeyDB(configdir, keyPrefix, readOnly, keydbPtr);
 
248
        if (crv != CKR_OK) {
 
249
            if (!forceOpen) goto loser;
 
250
            crv = CKR_OK;
 
251
        }
 
252
    }
 
253
 
 
254
 
 
255
loser:
 
256
    return crv;
 
257
}
 
258
 
 
259
 
 
260
void
 
261
pk11_DBShutdown(NSSLOWCERTCertDBHandle *certHandle, 
 
262
                NSSLOWKEYDBHandle *keyHandle)
 
263
{
 
264
    if (certHandle) {
 
265
        nsslowcert_ClosePermCertDB(certHandle);
 
266
        PORT_Free(certHandle);
 
267
        certHandle= NULL;
 
268
    }
 
269
 
 
270
    if (keyHandle) {
 
271
        nsslowkey_CloseKeyDB(keyHandle);
 
272
        keyHandle= NULL;
 
273
    }
 
274
}
 
275
 
 
276
static int rdbmapflags(int flags);
 
277
static rdbfunc pk11_rdbfunc = NULL;
 
278
static rdbstatusfunc pk11_rdbstatusfunc = NULL;
 
279
 
 
280
/* NOTE: SHLIB_SUFFIX is defined on the command line */
 
281
#define RDBLIB SHLIB_PREFIX"rdb."SHLIB_SUFFIX
 
282
 
 
283
DB * rdbopen(const char *appName, const char *prefix, 
 
284
                        const char *type, int flags, int *status)
 
285
{
 
286
    PRLibrary *lib;
 
287
    DB *db;
 
288
 
 
289
    if (pk11_rdbfunc) {
 
290
        db = (*pk11_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
 
291
        if (!db && status && pk11_rdbstatusfunc) {
 
292
            *status = (*pk11_rdbstatusfunc)();
 
293
        }
 
294
        return db;
 
295
    }
 
296
 
 
297
    /*
 
298
     * try to open the library.
 
299
     */
 
300
    lib = PR_LoadLibrary(RDBLIB);
 
301
 
 
302
    if (!lib) {
 
303
        return NULL;
 
304
    }
 
305
 
 
306
    /* get the entry points */
 
307
    pk11_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus");
 
308
    pk11_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen");
 
309
    if (pk11_rdbfunc) {
 
310
        db = (*pk11_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
 
311
        if (!db && status && pk11_rdbstatusfunc) {
 
312
            *status = (*pk11_rdbstatusfunc)();
 
313
        }
 
314
        return db;
 
315
    }
 
316
 
 
317
    /* couldn't find the entry point, unload the library and fail */
 
318
    PR_UnloadLibrary(lib);
 
319
    return NULL;
 
320
}
 
321
 
 
322
/*
 
323
 * the following data structures are from rdb.h.
 
324
 */
 
325
struct RDBStr {
 
326
    DB  db;
 
327
    int (*xactstart)(DB *db);
 
328
    int (*xactdone)(DB *db, PRBool abort);
 
329
    int version;
 
330
    int (*dbinitcomplete)(DB *db);
 
331
};
 
332
 
 
333
#define DB_RDB ((DBTYPE) 0xff)
 
334
#define RDB_RDONLY      1
 
335
#define RDB_RDWR        2
 
336
#define RDB_CREATE      4
 
337
 
 
338
static int
 
339
rdbmapflags(int flags) {
 
340
   switch (flags) {
 
341
   case NO_RDONLY:
 
342
        return RDB_RDONLY;
 
343
   case NO_RDWR:
 
344
        return RDB_RDWR;
 
345
   case NO_CREATE:
 
346
        return RDB_CREATE;
 
347
   default:
 
348
        break;
 
349
   }
 
350
   return 0;
 
351
}
 
352
 
 
353
 
 
354
PRBool
 
355
db_IsRDB(DB *db)
 
356
{
 
357
    return (PRBool) db->type == DB_RDB;
 
358
}
 
359
 
 
360
int
 
361
db_BeginTransaction(DB *db)
 
362
{
 
363
    struct RDBStr *rdb = (struct RDBStr *)db;
 
364
    if (db->type != DB_RDB) {
 
365
        return 0;
 
366
    }
 
367
 
 
368
    return rdb->xactstart(db);
 
369
}
 
370
 
 
371
int
 
372
db_FinishTransaction(DB *db, PRBool abort)
 
373
{
 
374
    struct RDBStr *rdb = (struct RDBStr *)db;
 
375
    if (db->type != DB_RDB) {
 
376
        return 0;
 
377
    }
 
378
 
 
379
    return rdb->xactdone(db, abort);
 
380
}
 
381
 
 
382
int
 
383
db_InitComplete(DB *db)
 
384
{
 
385
    struct RDBStr *rdb = (struct RDBStr *)db;
 
386
    if (db->type != DB_RDB) {
 
387
        return 0;
 
388
    }
 
389
    /* we should have addes a version number to the RDBS structure. Since we
 
390
     * didn't, we detect that we have and 'extended' structure if the rdbstatus
 
391
     * func exists */
 
392
    if (!pk11_rdbstatusfunc) {
 
393
        return 0;
 
394
    }
 
395
 
 
396
    return rdb->dbinitcomplete(db);
 
397
}
 
398
 
 
399
 
 
400
 
 
401
SECStatus
 
402
db_Copy(DB *dest,DB *src)
 
403
{
 
404
    int ret;
 
405
    DBT key,data;
 
406
    ret = (*src->seq)(src, &key, &data, R_FIRST);
 
407
    if (ret)  {
 
408
        return SECSuccess;
 
409
    }
 
410
 
 
411
    do {
 
412
        (void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE);
 
413
    } while ( (*src->seq)(src, &key, &data, R_NEXT) == 0);
 
414
    (void)(*dest->sync)(dest,0);
 
415
 
 
416
    return SECSuccess;
 
417
}
 
418