aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Moritz Hallberg <sm@khjk.org>2008-02-17 02:39:39 +0100
committerSven Moritz Hallberg <sm@khjk.org>2008-02-17 02:39:39 +0100
commitba5add72f824504a21eb780cae638c3ea2166ba0 (patch)
treedb16826012c15c1fe2b682a4f3b2d514d41d7aaf
parentfd9fa52e0014459079444bd7bfff7a40eef4e27a (diff)
explicitly initialize ssl in order to avoid gnutls and libotr fighting over the global state of libgcrypt
-rw-r--r--lib/ssl_bogus.c4
-rw-r--r--lib/ssl_client.h3
-rw-r--r--lib/ssl_gnutls.c11
-rw-r--r--lib/ssl_nss.c12
-rw-r--r--lib/ssl_openssl.c9
-rw-r--r--otr.c23
-rw-r--r--otr.h8
-rw-r--r--unix.c7
8 files changed, 58 insertions, 19 deletions
diff --git a/lib/ssl_bogus.c b/lib/ssl_bogus.c
index 5bae3496..391e634a 100644
--- a/lib/ssl_bogus.c
+++ b/lib/ssl_bogus.c
@@ -27,6 +27,10 @@
int ssl_errno;
+void ssl_init( void )
+{
+}
+
void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
{
return( NULL );
diff --git a/lib/ssl_client.h b/lib/ssl_client.h
index dcbf9a01..44fd658c 100644
--- a/lib/ssl_client.h
+++ b/lib/ssl_client.h
@@ -46,6 +46,9 @@ extern int ssl_errno;
typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition);
+/* Perform any global initialization the SSL library might need. */
+G_MODULE_EXPORT void ssl_init( void );
+
/* Connect to host:port, call the given function when the connection is
ready to be used for SSL traffic. This is all done asynchronously, no
blocking I/O! (Except for the DNS lookups, for now...) */
diff --git a/lib/ssl_gnutls.c b/lib/ssl_gnutls.c
index b964ab49..ae6f46a4 100644
--- a/lib/ssl_gnutls.c
+++ b/lib/ssl_gnutls.c
@@ -60,6 +60,13 @@ static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition
static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
+void ssl_init( void )
+{
+ gnutls_global_init();
+ initialized = TRUE;
+ atexit( gnutls_global_deinit );
+}
+
void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
{
struct scd *conn = g_new0( struct scd, 1 );
@@ -121,9 +128,7 @@ static gboolean ssl_connected( gpointer data, gint source, b_input_condition con
if( !initialized )
{
- gnutls_global_init();
- initialized = TRUE;
- atexit( gnutls_global_deinit );
+ ssl_init();
}
gnutls_certificate_allocate_credentials( &conn->xcred );
diff --git a/lib/ssl_nss.c b/lib/ssl_nss.c
index 218b3a80..16560e63 100644
--- a/lib/ssl_nss.c
+++ b/lib/ssl_nss.c
@@ -90,6 +90,14 @@ static SECStatus nss_bad_cert (void *arg, PRFileDesc *socket)
}
+void ssl_init( void )
+{
+ PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+ NSS_NoDB_Init(NULL);
+ NSS_SetDomesticPolicy();
+ initialized = TRUE;
+}
+
void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
{
struct scd *conn = g_new0( struct scd, 1 );
@@ -106,9 +114,7 @@ void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data
if( !initialized )
{
- PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
- NSS_NoDB_Init(NULL);
- NSS_SetDomesticPolicy();
+ ssl_init();
}
diff --git a/lib/ssl_openssl.c b/lib/ssl_openssl.c
index b1ba1db9..e54b21ee 100644
--- a/lib/ssl_openssl.c
+++ b/lib/ssl_openssl.c
@@ -56,6 +56,12 @@ static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition
static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
+void ssl_init( void );
+{
+ initialized = TRUE;
+ SSLeay_add_ssl_algorithms();
+}
+
void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
{
struct scd *conn = g_new0( struct scd, 1 );
@@ -114,8 +120,7 @@ static gboolean ssl_connected( gpointer data, gint source, b_input_condition con
if( !initialized )
{
- initialized = TRUE;
- SSLeay_add_ssl_algorithms();
+ ssl_init();
}
meth = TLSv1_client_method();
diff --git a/otr.c b/otr.c
index d30c8c93..418da177 100644
--- a/otr.c
+++ b/otr.c
@@ -111,7 +111,7 @@ int keygen_in_progress(irc_t *irc, const char *handle, const char *protocol);
void otr_keygen(irc_t *irc, const char *handle, const char *protocol);
/* main function for the forked keygen slave */
-void keygen_child_main(OtrlUserState us, int infd, int outfd);
+void keygen_child_main(const char *nick, int infd, int outfd);
/* mainloop handler for when a keygen finishes */
gboolean keygen_finish_handler(gpointer data, gint fd, b_input_condition cond);
@@ -1526,7 +1526,7 @@ void otr_keygen(irc_t *irc, const char *handle, const char *protocol)
if(!p) {
/* child process */
signal(SIGTERM, exit);
- keygen_child_main(irc->otr->us, to[0], from[1]);
+ keygen_child_main(irc->nick, to[0], from[1]);
exit(0);
}
@@ -1547,25 +1547,32 @@ void otr_keygen(irc_t *irc, const char *handle, const char *protocol)
while(*kg)
kg=&((*kg)->next);
*kg = g_new0(kg_t, 1);
- (*kg)->accountname = handle;
- (*kg)->protocol = protocol;
+ (*kg)->accountname = g_strdup(handle);
+ (*kg)->protocol = g_strdup(protocol);
} else {
/* send our job over and remember it */
log_message(LOGLVL_DEBUG, "slave: generate for %s/%s!", handle, protocol);
fprintf(irc->otr->to, "%s\n%s\n", handle, protocol);
fflush(irc->otr->to);
- irc->otr->sent_accountname = handle;
- irc->otr->sent_protocol = protocol;
+ irc->otr->sent_accountname = g_strdup(handle);
+ irc->otr->sent_protocol = g_strdup(protocol);
}
}
-void keygen_child_main(OtrlUserState us, int infd, int outfd)
+void keygen_child_main(const char *nick, int infd, int outfd)
{
+ OtrlUserState us;
+ char *kf;
FILE *input, *output;
char filename[128], accountname[512], protocol[512];
gcry_error_t e;
int tempfd;
+ us = otrl_userstate_create();
+ kf = g_strdup_printf("%s%s.otr_keys", global.conf->configdir, nick);
+ otrl_privkey_read(us, kf);
+ g_free(kf);
+
input = fdopen(infd, "r");
output = fdopen(outfd, "w");
@@ -1619,6 +1626,8 @@ gboolean keygen_finish_handler(gpointer data, gint fd, b_input_condition cond)
}
/* forget this job */
+ g_free(irc->otr->sent_accountname);
+ g_free(irc->otr->sent_protocol);
irc->otr->sent_accountname = NULL;
irc->otr->sent_protocol = NULL;
diff --git a/otr.h b/otr.h
index e5dddbb1..ca45c1e9 100644
--- a/otr.h
+++ b/otr.h
@@ -50,8 +50,8 @@ void cmd_otr(struct irc *, char **args);
/* representing a keygen job */
typedef struct kg {
- const char *accountname;
- const char *protocol;
+ char *accountname;
+ char *protocol;
struct kg *next;
} kg_t;
@@ -64,8 +64,8 @@ typedef struct otr {
FILE *from; /* pipe from keygen slave */
/* active keygen job (NULL if none) */
- const char *sent_accountname;
- const char *sent_protocol;
+ char *sent_accountname;
+ char *sent_protocol;
/* keygen jobs waiting to be sent to slave */
kg_t *todo;
diff --git a/unix.c b/unix.c
index 07cb709f..cbd5c15d 100644
--- a/unix.c
+++ b/unix.c
@@ -30,6 +30,7 @@
#include "protocols/nogaim.h"
#include "help.h"
#include "ipc.h"
+#include "lib/ssl_client.h"
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
@@ -54,6 +55,12 @@ int main( int argc, char *argv[], char **envp )
b_main_init();
nogaim_init();
+ /* Ugly Note: libotr and gnutls both use libgcrypt. libgcrypt
+ has a process-global config state whose initialization happpens
+ twice if libotr and gnutls are used together. libotr installs custom
+ memory management functions for libgcrypt while our gnutls module
+ uses the defaults. Therefore we initialize OTR after SSL. *sigh* */
+ ssl_init();
otr_init();
srand( time( NULL ) ^ getpid() );