diff options
| author | Sven Moritz Hallberg <sm@khjk.org> | 2008-02-17 02:39:39 +0100 | 
|---|---|---|
| committer | Sven Moritz Hallberg <sm@khjk.org> | 2008-02-17 02:39:39 +0100 | 
| commit | ba5add72f824504a21eb780cae638c3ea2166ba0 (patch) | |
| tree | db16826012c15c1fe2b682a4f3b2d514d41d7aaf | |
| parent | fd9fa52e0014459079444bd7bfff7a40eef4e27a (diff) | |
explicitly initialize ssl in order to avoid gnutls and libotr fighting over the global state of libgcrypt
| -rw-r--r-- | lib/ssl_bogus.c | 4 | ||||
| -rw-r--r-- | lib/ssl_client.h | 3 | ||||
| -rw-r--r-- | lib/ssl_gnutls.c | 11 | ||||
| -rw-r--r-- | lib/ssl_nss.c | 12 | ||||
| -rw-r--r-- | lib/ssl_openssl.c | 9 | ||||
| -rw-r--r-- | otr.c | 23 | ||||
| -rw-r--r-- | otr.h | 8 | ||||
| -rw-r--r-- | unix.c | 7 | 
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(); @@ -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; @@ -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; @@ -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() ); | 
