Blob Blame History Raw
From 45d6529dbe1b69f3a838d01a83f0688e91696377 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Trojnara?= <Michal.Trojnara@stunnel.org>
Date: Wed, 29 Aug 2018 21:35:48 +0200
Subject: [PATCH 07/23] Expose check_fork internal API

---
 src/Makefile.am  |   2 +-
 src/atfork.c     |  93 -------------------
 src/libp11-int.h |   7 ++
 src/p11_atfork.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++
 src/p11_front.c  | 138 ----------------------------
 5 files changed, 239 insertions(+), 232 deletions(-)
 delete mode 100644 src/atfork.c
 create mode 100644 src/p11_atfork.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 3cdbce1..2ca250e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,7 +14,7 @@ SHARED_EXT=@SHARED_EXT@
 
 libp11_la_SOURCES = libpkcs11.c p11_attr.c p11_cert.c p11_err.c p11_ckr.c \
 	p11_key.c p11_load.c p11_misc.c p11_rsa.c p11_ec.c p11_pkey.c \
-	p11_slot.c p11_front.c atfork.c libp11.exports
+	p11_slot.c p11_front.c p11_atfork.c libp11.exports
 if WIN32
 libp11_la_SOURCES += libp11.rc
 else
diff --git a/src/atfork.c b/src/atfork.c
deleted file mode 100644
index 04691fb..0000000
--- a/src/atfork.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010-2012 Free Software Foundation, Inc.
- * Copyright (C) 2014 Red Hat
- *
- * Author: Nikos Mavrogiannopoulos
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-#include "libp11-int.h"
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <atfork.h>
-
-#ifdef __sun
-# pragma fini(lib_deinit)
-# pragma init(lib_init)
-# define _CONSTRUCTOR
-# define _DESTRUCTOR
-#else
-# define _CONSTRUCTOR __attribute__((constructor))
-# define _DESTRUCTOR __attribute__((destructor))
-#endif
-
-unsigned int P11_forkid = 0;
-
-#ifndef _WIN32
-
-# ifdef HAVE_ATFORK
-static void fork_handler(void)
-{
-	P11_forkid++;
-}
-# endif
-
-# if defined(HAVE___REGISTER_ATFORK)
-extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
-extern void *__dso_handle;
-
-_CONSTRUCTOR
-int _P11_register_fork_handler(void)
-{
-	if (__register_atfork(0, 0, fork_handler, __dso_handle) != 0)
-		return -1;
-	return 0;
-}
-
-# else
-
-unsigned int _P11_get_forkid(void)
-{
-	return getpid();
-}
-
-int _P11_detect_fork(unsigned int forkid)
-{
-	if (getpid() == forkid)
-		return 0;
-	return 1;
-}
-
-/* we have to detect fork manually */
-_CONSTRUCTOR
-int _P11_register_fork_handler(void)
-{
-	P11_forkid = getpid();
-	return 0;
-}
-
-# endif
-
-#endif /* !_WIN32 */
-
-/* vim: set noexpandtab: */
diff --git a/src/libp11-int.h b/src/libp11-int.h
index b62a13e..411f2b0 100644
--- a/src/libp11-int.h
+++ b/src/libp11-int.h
@@ -323,6 +323,13 @@ extern int pkcs11_store_certificate(PKCS11_TOKEN * token, X509 * x509,
 extern int pkcs11_seed_random(PKCS11_SLOT *, const unsigned char *s, unsigned int s_len);
 extern int pkcs11_generate_random(PKCS11_SLOT *, unsigned char *r, unsigned int r_len);
 
+/* Reinitialize the module afer fork if needed */
+extern int check_fork(PKCS11_CTX *ctx);
+extern int check_slot_fork(PKCS11_SLOT *slot);
+extern int check_token_fork(PKCS11_TOKEN *token);
+extern int check_key_fork(PKCS11_KEY *key);
+extern int check_cert_fork(PKCS11_CERT *cert);
+
 /* Internal implementation of deprecated features */
 
 /* Generate and store a private key on the token */
diff --git a/src/p11_atfork.c b/src/p11_atfork.c
new file mode 100644
index 0000000..fce87c6
--- /dev/null
+++ b/src/p11_atfork.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2010-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Red Hat
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "libp11-int.h"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <atfork.h>
+
+#ifdef __sun
+# pragma fini(lib_deinit)
+# pragma init(lib_init)
+# define _CONSTRUCTOR
+# define _DESTRUCTOR
+#else
+# define _CONSTRUCTOR __attribute__((constructor))
+# define _DESTRUCTOR __attribute__((destructor))
+#endif
+
+unsigned int P11_forkid = 0;
+
+#ifndef _WIN32
+
+# ifdef HAVE_ATFORK
+static void fork_handler(void)
+{
+	P11_forkid++;
+}
+# endif
+
+# if defined(HAVE___REGISTER_ATFORK)
+extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
+extern void *__dso_handle;
+
+_CONSTRUCTOR
+int _P11_register_fork_handler(void)
+{
+	if (__register_atfork(0, 0, fork_handler, __dso_handle) != 0)
+		return -1;
+	return 0;
+}
+
+# else
+
+unsigned int _P11_get_forkid(void)
+{
+	return getpid();
+}
+
+int _P11_detect_fork(unsigned int forkid)
+{
+	if (getpid() == forkid)
+		return 0;
+	return 1;
+}
+
+/* we have to detect fork manually */
+_CONSTRUCTOR
+int _P11_register_fork_handler(void)
+{
+	P11_forkid = getpid();
+	return 0;
+}
+
+# endif
+
+#endif /* !_WIN32 */
+
+/*
+ * PKCS#11 reinitialization after fork
+ * It wipes out the internal state of the PKCS#11 library
+ * Any libp11 references to this state are no longer valid
+ */
+static int check_fork_int(PKCS11_CTX *ctx)
+{
+	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
+
+	if (_P11_detect_fork(cpriv->forkid)) {
+		if (pkcs11_CTX_reload(ctx) < 0)
+			return -1;
+		cpriv->forkid = _P11_get_forkid();
+	}
+	return 0;
+}
+
+/*
+ * PKCS#11 reinitialization after fork
+ * Also relogins and reopens the session if needed
+ */
+static int check_slot_fork_int(PKCS11_SLOT *slot)
+{
+	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+	PKCS11_CTX *ctx = SLOT2CTX(slot);
+	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
+
+	if (check_fork_int(SLOT2CTX(slot)) < 0)
+		return -1;
+	if (spriv->forkid != cpriv->forkid) {
+		if (spriv->loggedIn) {
+			int saved = spriv->haveSession;
+			spriv->haveSession = 0;
+			spriv->loggedIn = 0;
+			if (pkcs11_relogin(slot) < 0)
+				return -1;
+			spriv->haveSession = saved;
+		}
+		if (spriv->haveSession) {
+			spriv->haveSession = 0;
+			if (pkcs11_reopen_session(slot) < 0)
+				return -1;
+		}
+		spriv->forkid = cpriv->forkid;
+	}
+	return 0;
+}
+
+/*
+ * PKCS#11 reinitialization after fork
+ * Also reloads the key
+ */
+static int check_key_fork_int(PKCS11_KEY *key)
+{
+	PKCS11_SLOT *slot = KEY2SLOT(key);
+	PKCS11_KEY_private *kpriv = PRIVKEY(key);
+	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+
+	if (check_slot_fork_int(slot) < 0)
+		return -1;
+	if (spriv->forkid != kpriv->forkid) {
+		pkcs11_reload_key(key);
+		kpriv->forkid = spriv->forkid;
+	}
+	return 0;
+}
+
+/*
+ * Locking interface to check_fork_int()
+ */
+int check_fork(PKCS11_CTX *ctx)
+{
+	PKCS11_CTX_private *cpriv;
+	int rv;
+
+	if (ctx == NULL)
+		return -1;
+	cpriv = PRIVCTX(ctx);
+	CRYPTO_THREAD_write_lock(cpriv->rwlock);
+	rv = check_fork_int(ctx);
+	CRYPTO_THREAD_unlock(cpriv->rwlock);
+	return rv;
+}
+
+/*
+ * Locking interface to check_slot_fork_int()
+ */
+int check_slot_fork(PKCS11_SLOT *slot)
+{
+	PKCS11_CTX_private *cpriv;
+	int rv;
+
+	if (slot == NULL)
+		return -1;
+	cpriv = PRIVCTX(SLOT2CTX(slot));
+	CRYPTO_THREAD_write_lock(cpriv->rwlock);
+	rv = check_slot_fork_int(slot);
+	CRYPTO_THREAD_unlock(cpriv->rwlock);
+	return rv;
+}
+
+/*
+ * Reinitialize token (just its slot)
+ */
+int check_token_fork(PKCS11_TOKEN *token)
+{
+	if (token == NULL)
+		return -1;
+	return check_slot_fork(TOKEN2SLOT(token));
+}
+
+/*
+ * Locking interface to check_key_fork_int()
+ */
+int check_key_fork(PKCS11_KEY *key)
+{
+	PKCS11_CTX_private *cpriv;
+	int rv;
+
+	if (key == NULL)
+		return -1;
+	cpriv = PRIVCTX(KEY2CTX(key));
+	CRYPTO_THREAD_write_lock(cpriv->rwlock);
+	rv = check_key_fork_int(key);
+	CRYPTO_THREAD_unlock(cpriv->rwlock);
+	return rv;
+}
+
+/*
+ * Reinitialize cert (just its token)
+ */
+int check_cert_fork(PKCS11_CERT *cert)
+{
+	if (cert == NULL)
+		return -1;
+	return check_token_fork(CERT2TOKEN(cert));
+}
+
+/* vim: set noexpandtab: */
diff --git a/src/p11_front.c b/src/p11_front.c
index 167a778..efdd4c0 100644
--- a/src/p11_front.c
+++ b/src/p11_front.c
@@ -25,144 +25,6 @@
  * PKCS11_get_ec_key_method
  */
 
-/*
- * PKCS#11 reinitialization after fork
- * It wipes out the internal state of the PKCS#11 library
- * Any libp11 references to this state are no longer valid
- */
-static int check_fork_int(PKCS11_CTX *ctx)
-{
-	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
-
-	if (_P11_detect_fork(cpriv->forkid)) {
-		if (pkcs11_CTX_reload(ctx) < 0)
-			return -1;
-		cpriv->forkid = _P11_get_forkid();
-	}
-	return 0;
-}
-
-/*
- * PKCS#11 reinitialization after fork
- * Also relogins and reopens the session if needed
- */
-static int check_slot_fork_int(PKCS11_SLOT *slot)
-{
-	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
-	PKCS11_CTX *ctx = SLOT2CTX(slot);
-	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
-
-	if (check_fork_int(SLOT2CTX(slot)) < 0)
-		return -1;
-	if (spriv->forkid != cpriv->forkid) {
-		if (spriv->loggedIn) {
-			int saved = spriv->haveSession;
-			spriv->haveSession = 0;
-			spriv->loggedIn = 0;
-			if (pkcs11_relogin(slot) < 0)
-				return -1;
-			spriv->haveSession = saved;
-		}
-		if (spriv->haveSession) {
-			spriv->haveSession = 0;
-			if (pkcs11_reopen_session(slot) < 0)
-				return -1;
-		}
-		spriv->forkid = cpriv->forkid;
-	}
-	return 0;
-}
-
-/*
- * PKCS#11 reinitialization after fork
- * Also reloads the key
- */
-static int check_key_fork_int(PKCS11_KEY *key)
-{
-	PKCS11_SLOT *slot = KEY2SLOT(key);
-	PKCS11_KEY_private *kpriv = PRIVKEY(key);
-	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
-
-	if (check_slot_fork_int(slot) < 0)
-		return -1;
-	if (spriv->forkid != kpriv->forkid) {
-		pkcs11_reload_key(key);
-		kpriv->forkid = spriv->forkid;
-	}
-	return 0;
-}
-
-/*
- * Locking interface to check_fork_int()
- */
-static int check_fork(PKCS11_CTX *ctx)
-{
-	PKCS11_CTX_private *cpriv;
-	int rv;
-
-	if (ctx == NULL)
-		return -1;
-	cpriv = PRIVCTX(ctx);
-	CRYPTO_THREAD_write_lock(cpriv->rwlock);
-	rv = check_fork_int(ctx);
-	CRYPTO_THREAD_unlock(cpriv->rwlock);
-	return rv;
-}
-
-/*
- * Locking interface to check_slot_fork_int()
- */
-static int check_slot_fork(PKCS11_SLOT *slot)
-{
-	PKCS11_CTX_private *cpriv;
-	int rv;
-
-	if (slot == NULL)
-		return -1;
-	cpriv = PRIVCTX(SLOT2CTX(slot));
-	CRYPTO_THREAD_write_lock(cpriv->rwlock);
-	rv = check_slot_fork_int(slot);
-	CRYPTO_THREAD_unlock(cpriv->rwlock);
-	return rv;
-}
-
-/*
- * Reinitialize token (just its slot)
- */
-static int check_token_fork(PKCS11_TOKEN *token)
-{
-	if (token == NULL)
-		return -1;
-	return check_slot_fork(TOKEN2SLOT(token));
-}
-
-/*
- * Locking interface to check_key_fork_int()
- */
-static int check_key_fork(PKCS11_KEY *key)
-{
-	PKCS11_CTX_private *cpriv;
-	int rv;
-
-	if (key == NULL)
-		return -1;
-	cpriv = PRIVCTX(KEY2CTX(key));
-	CRYPTO_THREAD_write_lock(cpriv->rwlock);
-	rv = check_key_fork_int(key);
-	CRYPTO_THREAD_unlock(cpriv->rwlock);
-	return rv;
-}
-
-/*
- * Reinitialize cert (just its token)
- */
-static int check_cert_fork(PKCS11_CERT *cert)
-{
-	if (cert == NULL)
-		return -1;
-	return check_token_fork(CERT2TOKEN(cert));
-}
-
 /* External interface to the libp11 features */
 
 PKCS11_CTX *PKCS11_CTX_new(void)
-- 
2.17.1