]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
In the NSS crypto back end, add mutex protection and fork protection
authorGreg Hudson <ghudson@mit.edu>
Sat, 25 Sep 2010 15:09:08 +0000 (15:09 +0000)
committerGreg Hudson <ghudson@mit.edu>
Sat, 25 Sep 2010 15:09:08 +0000 (15:09 +0000)
to the libnss context.

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/nss@24348 dc483132-0cff-0310-8789-dd5450dbe970

src/include/k5-int.h
src/lib/crypto/builtin/Makefile.in
src/lib/crypto/builtin/init.c [new file with mode: 0644]
src/lib/crypto/krb/crypto_libinit.c
src/lib/crypto/nss/enc_provider/enc_gen.c
src/lib/crypto/openssl/Makefile.in
src/lib/crypto/openssl/init.c [new file with mode: 0644]

index bb078c0705ca18238f5f03e8c95102177557a490..4fa8649a318adaa72d9af66c7a213e21db3fefa8 100644 (file)
@@ -816,6 +816,7 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context,
  * Internal - for cleanup.
  */
 extern void krb5int_prng_cleanup(void);
+extern void krb5int_crypto_impl_cleanup(void);
 
 
 #ifdef KRB5_OLD_CRYPTO
@@ -2533,6 +2534,7 @@ krb5int_c_mandatory_cksumtype(krb5_context, krb5_enctype, krb5_cksumtype *);
 
 extern int krb5int_crypto_init (void);
 extern int krb5int_prng_init(void);
+extern int krb5int_crypto_impl_init(void);
 
 /*
  * Referral definitions, debugging hooks, and subfunctions.
index a65f64df988504f0d06ad021c3bb528e6bdba439..5f6d9ee3541b1a3088476142e8c5feec62cad005 100644 (file)
@@ -26,14 +26,17 @@ EXTRADEPSRCS= $(srcdir)/t_cf2.c
 
 STLIBOBJS=\
        hmac.o  \
-       pbkdf2.o                
+       init.o  \
+       pbkdf2.o
 
 OBJS=\
        $(OUTPRE)hmac.$(OBJEXT) \
-       $(OUTPRE)pbkdf2.$(OBJEXT)               
+       $(OUTPRE)init.$(OBJEXT) \
+       $(OUTPRE)pbkdf2.$(OBJEXT)
 
 SRCS=\
        $(srcdir)/hmac.c        \
+       $(srcdir)/init.c        \
        $(srcdir)/pbkdf2.c      
 
 STOBJLISTS= des/OBJS.ST md4/OBJS.ST    \
diff --git a/src/lib/crypto/builtin/init.c b/src/lib/crypto/builtin/init.c
new file mode 100644 (file)
index 0000000..af69523
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/builtin/init.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Built-in back-end library init functions
+ */
+
+int
+krb5int_crypto_impl_init(void)
+{
+    return 0;
+}
+
+void
+krb5int_crypto_impl_cleanup(void)
+{
+}
index a69db38e3b8cdfc1f7a055884b3d8527e8a3f4cc..b94a01cc0ba4f9327c8c562af6fbbcf9e52a0c32 100644 (file)
@@ -14,7 +14,11 @@ extern void krb5int_prng_cleanup (void);
 
 int cryptoint_initialize_library (void)
 {
-    return krb5int_prng_init();
+    int err;
+    err = krb5int_prng_init();
+    if (err)
+        return err;
+    return krb5int_crypto_impl_init();
 }
 
 int krb5int_crypto_init(void)
@@ -30,5 +34,6 @@ void cryptoint_cleanup_library (void)
 {
     if (!INITIALIZER_RAN(cryptoint_initialize_library))
         return;
-    krb5int_prng_cleanup ();
+    krb5int_prng_cleanup();
+    krb5int_crypto_impl_cleanup();
 }
index 6ad50b840e096584f0765637c1a25082db3397b0..d2fbfb5bb96d3d209ca1dcc4d1d00a42a29a686b 100644 (file)
@@ -49,6 +49,9 @@
 #define MAX_KEY_LENGTH 64
 #define MAX_BLOCK_SIZE 64
 
+static NSSInitContext *k5_nss_ctx = NULL;
+static pid_t k5_nss_pid = 0;
+static k5_mutex_t k5_nss_lock = K5_MUTEX_PARTIAL_INITIALIZER;
 
 krb5_error_code
 k5_nss_map_error(int nss_error)
@@ -65,34 +68,64 @@ k5_nss_map_last_error(void)
     return k5_nss_map_error(PORT_GetError());
 }
 
-static NSSInitContext *krb5_nss_init = NULL;
+int
+krb5int_crypto_impl_init(void)
+{
+    return k5_mutex_finish_init(&k5_nss_lock);
+}
+
+void
+krb5int_crypto_impl_cleanup(void)
+{
+    k5_mutex_destroy(&k5_nss_lock);
+}
 
 /*
  * krb5 doesn't have a call into the crypto engine to initialize it, so we do
  * it here.  This code will try to piggyback on any application initialization
  * done to NSS.  Otherwise get our one library init context.
  */
+#define NSS_KRB5_CONFIGDIR "sql:/etc/pki/nssdb"
 krb5_error_code
 k5_nss_init(void)
 {
-#ifdef LINUX
-    /* Default to the system NSS. */
-#define NSS_KRB5_CONFIGDIR  "sql:/etc/pki/nssdb"
-#define NSS_KRB5_FLAGS   0
-#else
-    /* Other platforms don't have a system NSS defined yet, do a nodb init. */
-#define NSS_KRB5_CONFIGDIR  NULL
-#define NSS_KRB5_FLAGS NSS_INIT_NOMODDB|NSS_INIT_NOCERTDB
-#endif
-    if (krb5_nss_init)          /* We've already initialized NSS. */
-        return 0;
-    if (NSS_IsInitialized())    /* Someone else has initialized NSS. */
-        return 0;
-    krb5_nss_init = NSS_InitContext(NSS_KRB5_CONFIGDIR, "", "", "", NULL,
-                                    NSS_INIT_READONLY | NSS_INIT_NOROOTINIT |
-                                    NSS_KRB5_FLAGS);
-    if (!krb5_nss_init)
-        return k5_nss_map_last_error();
+    PRUint32 flags = NSS_INIT_READONLY | NSS_INIT_NOROOTINIT;
+    krb5_error_code ret;
+    SECStatus rv;
+    pid_t pid;
+
+    ret = k5_mutex_lock(&k5_nss_lock);
+    if (ret)
+        return ret;
+
+    pid = getpid();
+    if (k5_nss_ctx != NULL) {
+        /* Do nothing if the existing context is still good. */
+        if (k5_nss_pid == pid)
+            goto cleanup;
+
+        /* We've forked since the last init, and need to reinitialize. */
+        rv = NSS_ShutdownContext(k5_nss_ctx);
+        k5_nss_ctx = NULL;
+        if (rv != SECSuccess) {
+            ret = k5_nss_map_last_error();
+            goto cleanup;
+        }
+    }
+    k5_nss_ctx = NSS_InitContext(NSS_KRB5_CONFIGDIR, "", "", "", NULL, flags);
+    if (k5_nss_ctx == NULL) {
+        /* There may be no system database; try again without it. */
+        flags |= NSS_INIT_NOMODDB | NSS_INIT_NOCERTDB;
+        k5_nss_ctx = NSS_InitContext(NULL, "", "", "", NULL, flags);
+        if (k5_nss_ctx == NULL) {
+            ret = k5_nss_map_last_error();
+            goto cleanup;
+        }
+    }
+    k5_nss_pid = pid;
+
+cleanup:
+    k5_mutex_unlock(&k5_nss_lock);
     return 0;
 }
 
index a008d5727787b412a32931dd3784bf3ca4979559..34dd0c5c510385a0fe4235261acc83928d035a98 100644 (file)
@@ -22,14 +22,17 @@ DEFS=
 
 STLIBOBJS=\
        hmac.o  \
-       pbkdf2.o                
+       init.o  \
+       pbkdf2.o
 
 OBJS=\
        $(OUTPRE)hmac.$(OBJEXT) \
-       $(OUTPRE)pbkdf2.$(OBJEXT)               
+       $(OUTPRE)init.$(OBJEXT) \
+       $(OUTPRE)pbkdf2.$(OBJEXT)
 
 SRCS=\
        $(srcdir)/hmac.c        \
+       $(srcdir)/init.c        \
        $(srcdir)/pbkdf2.c      
 
 STOBJLISTS= des/OBJS.ST md4/OBJS.ST    \
diff --git a/src/lib/crypto/openssl/init.c b/src/lib/crypto/openssl/init.c
new file mode 100644 (file)
index 0000000..aaa13cc
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/openssl/init.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * OpenSSL back-end library init functions
+ */
+
+int
+krb5int_crypto_impl_init(void)
+{
+    return 0;
+}
+
+void
+krb5int_crypto_impl_cleanup(void)
+{
+}