[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

rpms/pyOpenSSL/devel pyOpenSSL-threadsafe.patch,NONE,1.1



Author: dcbw

Update of /cvs/dist/rpms/pyOpenSSL/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv14913

Added Files:
	pyOpenSSL-threadsafe.patch 
Log Message:
A patch that makes pyOpenSSL more or less threadsafe


pyOpenSSL-threadsafe.patch:
 crypto/crypto.c |   70 ++++++++++++++++++++++++++++++++++++++++
 ssl/context.c   |   97 +++++++++++++++++++++++---------------------------------
 2 files changed, 111 insertions(+), 56 deletions(-)

--- NEW FILE pyOpenSSL-threadsafe.patch ---
--- pyOpenSSL-0.6/src/ssl/context.c.threadsafe	2004-08-06 06:24:38.000000000 -0400
+++ pyOpenSSL-0.6/src/ssl/context.c	2005-07-12 22:30:02.000000000 -0400
@@ -53,39 +53,33 @@
 static int
 global_passphrase_callback(char *buf, int maxlen, int verify, void *arg)
 {
-    int len;
+    int len = 0;
     char *str;
     PyObject *argv, *ret = NULL;
     ssl_ContextObj *ctx = (ssl_ContextObj *)arg;
 
+    if (!ctx->tstate)
+        fprintf (stderr, "ERROR: ctx->tstate == NULL!\n");
+    MY_END_ALLOW_THREADS(ctx->tstate);
+
     /* The Python callback is called with a (maxlen,verify,userdata) tuple */
     argv = Py_BuildValue("(iiO)", maxlen, verify, ctx->passphrase_userdata);
-    if (ctx->tstate != NULL)
-    {
-        /* We need to get back our thread state before calling the callback */
-        MY_END_ALLOW_THREADS(ctx->tstate);
-        ret = PyEval_CallObject(ctx->passphrase_callback, argv);
-        MY_BEGIN_ALLOW_THREADS(ctx->tstate);
-    }
-    else
-    {
-        ret = PyEval_CallObject(ctx->passphrase_callback, argv);
-    }
+    ret = PyEval_CallObject(ctx->passphrase_callback, argv);
     Py_DECREF(argv);
 
     if (ret == NULL)
-        return 0;
+        goto out;
 
     if (!PyObject_IsTrue(ret))
     {
         Py_DECREF(ret);
-	return 0;
+        goto out;
     }
 
     if (!PyString_Check(ret))
     {
         Py_DECREF(ret);
-        return 0;
+        goto out;
     }
 
     len = PyString_Size(ret);
@@ -96,6 +90,8 @@
     strncpy(buf, str, len);
     Py_XDECREF(ret);
 
+out:
+    MY_BEGIN_ALLOW_THREADS(ctx->tstate);
     return len;
 }
 
@@ -115,43 +111,39 @@
     SSL *ssl;
     ssl_ConnectionObj *conn;
     crypto_X509Obj *cert;
-    int errnum, errdepth, c_ret;
+    int errnum, errdepth, c_ret = 0;
 
-    cert = crypto_X509_New(X509_STORE_CTX_get_current_cert(x509_ctx), 0);
     errnum = X509_STORE_CTX_get_error(x509_ctx);
     errdepth = X509_STORE_CTX_get_error_depth(x509_ctx);
     ssl = (SSL *)X509_STORE_CTX_get_app_data(x509_ctx);
     conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
 
+    if (!conn->tstate)
+        fprintf (stderr, "ERROR: ctx->tstate == NULL!\n");
+    MY_END_ALLOW_THREADS(conn->tstate);
+
+    cert = crypto_X509_New(X509_STORE_CTX_get_current_cert(x509_ctx), 0);
+
     argv = Py_BuildValue("(OOiii)", (PyObject *)conn, (PyObject *)cert,
                                     errnum, errdepth, ok);
     Py_DECREF(cert);
-    if (conn->tstate != NULL)
-    {
-        /* We need to get back our thread state before calling the callback */
-        MY_END_ALLOW_THREADS(conn->tstate);
-        ret = PyEval_CallObject(conn->context->verify_callback, argv);
-        MY_BEGIN_ALLOW_THREADS(conn->tstate);
-    }
-    else
-    {
-        ret = PyEval_CallObject(conn->context->verify_callback, argv);
-    }
+    ret = PyEval_CallObject(conn->context->verify_callback, argv);
     Py_DECREF(argv);
 
-    if (ret == NULL)
-        return 0;
-
-    if (PyObject_IsTrue(ret))
+    if (ret != NULL)
     {
-        X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
-        c_ret = 1;
-    }
-    else
-        c_ret = 0;
+        if (PyObject_IsTrue(ret))
+        {
+            X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
+            c_ret = 1;
+        }
+        else
+            c_ret = 0;
 
-    Py_DECREF(ret);
+        Py_DECREF(ret);
+    }
 
+    MY_BEGIN_ALLOW_THREADS(conn->tstate);
     return c_ret;
 }
 
@@ -169,28 +161,19 @@
     ssl_ConnectionObj *conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
     PyObject *argv, *ret;
 
+    if (!conn->tstate)
+        fprintf (stderr, "ERROR: ctx->tstate == NULL!\n");
+    MY_END_ALLOW_THREADS(conn->tstate);
+
     argv = Py_BuildValue("(Oii)", (PyObject *)conn, where, _ret);
-    if (conn->tstate != NULL)
-    {
-        /* We need to get back our thread state before calling the callback */
-        MY_END_ALLOW_THREADS(conn->tstate);
-        ret = PyEval_CallObject(conn->context->info_callback, argv);
-        if (ret == NULL)
-            PyErr_Clear();
-        else
-            Py_DECREF(ret);
-        MY_BEGIN_ALLOW_THREADS(conn->tstate);
-    }
+    ret = PyEval_CallObject(conn->context->info_callback, argv);
+    if (ret == NULL)
+        PyErr_Clear();
     else
-    {
-        ret = PyEval_CallObject(conn->context->info_callback, argv);
-        if (ret == NULL)
-            PyErr_Clear();
-        else
-            Py_DECREF(ret);
-    }
+        Py_DECREF(ret);
     Py_DECREF(argv);
 
+    MY_BEGIN_ALLOW_THREADS(conn->tstate);
     return;
 }
 
@@ -393,6 +376,8 @@
     if (!PyArg_ParseTuple(args, "s|i:use_privatekey_file", &keyfile, &filetype))
         return NULL;
 
+    if (self->tstate)
+        fprintf (stderr, "ERROR: ctx->tstate != NULL!\n");
     MY_BEGIN_ALLOW_THREADS(self->tstate);
     ret = SSL_CTX_use_PrivateKey_file(self->ctx, keyfile, filetype);
     MY_END_ALLOW_THREADS(self->tstate);
--- pyOpenSSL-0.6/src/crypto/crypto.c.threadsafe	2004-08-09 10:56:05.000000000 -0400
+++ pyOpenSSL-0.6/src/crypto/crypto.c	2005-07-12 22:29:32.000000000 -0400
@@ -668,6 +668,72 @@
     { NULL, NULL }
 };
 
+
+#ifdef WITH_THREAD
+
+#define MUTEX_TYPE pthread_mutex_t
+#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
+#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
+#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
+#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
+#define THREAD_ID pthread_self()
+ 
+void handle_error(const char *file, int lineno, const char *msg)
+{
+     fprintf(stderr, "** %s:%i %s\n", file, lineno, msg);
+     ERR_print_errors_fp(stderr);
+}
+ 
+ 
+/* This array will store all of the mutexes available to OpenSSL. */
+static MUTEX_TYPE *mutex_buf = NULL;
+
+
+static void locking_function(int mode, int n, const char * file, int line)
+{
+    if (mode & CRYPTO_LOCK)
+        MUTEX_LOCK(mutex_buf[n]);
+    else
+        MUTEX_UNLOCK(mutex_buf[n]);
+}
+  
+static unsigned long id_function(void)
+{
+    return ((unsigned long)THREAD_ID);
+}
+
+int init_openssl_threads(void)
+{
+    int i;
+  
+    mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
+    if (!mutex_buf)
+        return 0;
+    for (i = 0; i < CRYPTO_num_locks(); i++)
+        MUTEX_SETUP(mutex_buf[i]);
+    CRYPTO_set_id_callback(id_function);
+    CRYPTO_set_locking_callback(locking_function);
+    return 1;
+}
+  
+int deinit_openssl_threads(void)
+{
+    int i;
+  
+    if (!mutex_buf)
+        return 0;
+    CRYPTO_set_id_callback(NULL);
+    CRYPTO_set_locking_callback(NULL);
+    for (i = 0; i < CRYPTO_num_locks(); i++)
+        MUTEX_CLEANUP(mutex_buf[i]);
+    free(mutex_buf);
+    mutex_buf = NULL;
+    return 1;
+} 
+
+#endif
+
+
 /*
  * Initialize crypto sub module
  *
@@ -713,6 +779,10 @@
     PyModule_AddIntConstant(module, "TYPE_DSA", crypto_TYPE_DSA);
 
     dict = PyModule_GetDict(module);
+#ifdef WITH_THREAD
+    if (!init_openssl_threads())
+        goto error;
+#endif
     if (!init_crypto_x509(dict))
         goto error;
     if (!init_crypto_x509name(dict))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]