diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-09-01 23:09:27 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-09-01 23:09:27 +0100 | 
| commit | 934db064a58ebec2edea83df4fa07e2c83220344 (patch) | |
| tree | b7a4aac7deff47cc743102dcb2bd8ded426c8bcd | |
| parent | 0c85c08d210e16bb10dc283b4a1478ce53c0c1b1 (diff) | |
Do encryption and decryption. Somehow SMP and other things aren't working
so well yet, at least when testing with Pidgin on the other side. Not sure
where the bug is.
| -rw-r--r-- | irc.h | 8 | ||||
| -rw-r--r-- | irc_im.c | 86 | ||||
| -rw-r--r-- | otr.c | 41 | ||||
| -rw-r--r-- | otr.h | 26 | ||||
| -rw-r--r-- | protocols/bee_user.c | 4 | 
5 files changed, 102 insertions, 63 deletions
| @@ -229,12 +229,16 @@ typedef struct irc_plugin  	/* At the end of irc_free(). */  	void (*irc_free)( irc_t *irc ); +	/* Problem with the following two functions is ordering if multiple +	   plugins are handling them. Let's keep fixing that problem for +	   whenever it becomes important. */ +	  	/* Called by bee_irc_user_privmsg_cb(). Return NULL if you want to  	   abort sending the msg. */ -	char* (*filter_msg_out)( irc_user_t *iu, const char *msg, int flags ); +	char* (*filter_msg_out)( irc_user_t *iu, char *msg, int flags );  	/* Called by bee_irc_user_msg(). Return NULL if you swallowed the  	   message and don't want anything to go to the user. */ -	char* (*filter_msg_in)( irc_user_t *iu, const char *msg, int flags ); +	char* (*filter_msg_in)( irc_user_t *iu, char *msg, int flags );  } irc_plugin_t;  extern GSList *irc_plugins; /* struct irc_plugin */ @@ -191,13 +191,15 @@ void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu )  	}  } -static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at ) +static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg_, time_t sent_at )  {  	irc_t *irc = bee->ui_data;  	irc_user_t *iu = (irc_user_t *) bu->ui_data;  	char *dst, *prefix = NULL;  	char *wrapped, *ts = NULL;  	irc_channel_t *ic = NULL; +	char *msg = g_strdup( msg_ ); +	GSList *l;  	if( sent_at > 0 && set_getbool( &irc->b->set, "display_timestamps" ) )  		ts = irc_format_timestamp( irc, sent_at ); @@ -223,11 +225,41 @@ static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, t  		ts = NULL;  	} +	for( l = irc_plugins; l; l = l->next ) +	{ +		irc_plugin_t *p = l->data; +		if( p->filter_msg_in ) +		{ +			char *s = p->filter_msg_in( iu, msg, 0 ); +			if( s ) +			{ +				if( s != msg ) +					g_free( msg ); +				msg = s; +			} +			else +			{ +				/* Modules can swallow messages. */ +				return TRUE; +			} +		} +	} +	 +	if( ( g_strcasecmp( set_getstr( &bee->set, "strip_html" ), "always" ) == 0 ) || +	    ( ( bu->ic->flags & OPT_DOES_HTML ) && set_getbool( &bee->set, "strip_html" ) ) ) +	{ +		char *s = g_strdup( msg ); +		strip_html( s ); +		g_free( msg ); +		msg = s; +	} +	  	wrapped = word_wrap( msg, 425 );  	irc_send_msg( iu, "PRIVMSG", dst, wrapped, prefix );  	g_free( wrapped );  	g_free( prefix ); +	g_free( msg );  	g_free( ts );  	return TRUE; @@ -348,18 +380,18 @@ static gboolean bee_irc_user_privmsg( irc_user_t *iu, const char *msg )  			set_getint( &iu->irc->b->set, "away_reply_timeout" );  	} +	if( iu->pastebuf == NULL ) +		iu->pastebuf = g_string_new( msg ); +	else +	{ +		b_event_remove( iu->pastebuf_timer ); +		g_string_append_printf( iu->pastebuf, "\n%s", msg ); +	} +	  	if( set_getbool( &iu->irc->b->set, "paste_buffer" ) )  	{  		int delay; -		if( iu->pastebuf == NULL ) -			iu->pastebuf = g_string_new( msg ); -		else -		{ -			b_event_remove( iu->pastebuf_timer ); -			g_string_append_printf( iu->pastebuf, "\n%s", msg ); -		} -		  		if( ( delay = set_getint( &iu->irc->b->set, "paste_buffer_delay" ) ) <= 5 )  			delay *= 1000; @@ -368,17 +400,45 @@ static gboolean bee_irc_user_privmsg( irc_user_t *iu, const char *msg )  		return TRUE;  	}  	else -		return bee_user_msg( iu->irc->b, iu->bu, msg, 0 ); +	{ +		bee_irc_user_privmsg_cb( iu, 0, 0 ); +		 +		return TRUE; +	}  }  static gboolean bee_irc_user_privmsg_cb( gpointer data, gint fd, b_input_condition cond )  {  	irc_user_t *iu = data; +	char *msg = g_string_free( iu->pastebuf, FALSE ); +	GSList *l; +	 +	for( l = irc_plugins; l; l = l->next ) +	{ +		irc_plugin_t *p = l->data; +		if( p->filter_msg_out ) +		{ +			char *s = p->filter_msg_out( iu, msg, 0 ); +			if( s ) +			{ +				if( s != msg ) +					g_free( msg ); +				msg = s; +			} +			else +			{ +				/* Modules can swallow messages. */ +				iu->pastebuf = NULL; +				g_free( msg ); +				return FALSE; +			} +		} +	} -	bee_user_msg( iu->irc->b, iu->bu, iu->pastebuf->str, 0 ); +	bee_user_msg( iu->irc->b, iu->bu, msg, 0 ); -	g_string_free( iu->pastebuf, TRUE ); -	iu->pastebuf = 0; +	g_free( msg ); +	iu->pastebuf = NULL;  	iu->pastebuf_timer = 0;  	return FALSE; @@ -343,24 +343,25 @@ int otr_check_for_key(account_t *a)  	}  } -char *otr_handle_message(struct im_connection *ic, const char *handle, const char *msg) +char *otr_filter_msg_in(irc_user_t *iu, char *msg, int flags)  {  	int ignore_msg;  	char *newmsg = NULL;  	OtrlTLV *tlvs = NULL;  	char *colormsg; -	irc_t *irc = ic->bee->ui_data; +	irc_t *irc = iu->irc; +	struct im_connection *ic = iu->bu->ic;  	/* don't do OTR on certain (not classic IM) protocols, e.g. twitter */  	if(ic->acc->prpl->options & OPT_NOOTR) { -		return (g_strdup(msg)); +		return msg;  	}  	ignore_msg = otrl_message_receiving(irc->otr->us, &otr_ops, ic, -		ic->acc->user, ic->acc->prpl->name, handle, msg, &newmsg, +		ic->acc->user, ic->acc->prpl->name, iu->bu->handle, msg, &newmsg,  		&tlvs, NULL, NULL); -	otr_handle_smp(ic, handle, tlvs); +	otr_handle_smp(ic, iu->bu->handle, tlvs);  	if(ignore_msg) {  		/* this was an internal OTR protocol message */ @@ -370,10 +371,10 @@ char *otr_handle_message(struct im_connection *ic, const char *handle, const cha  		return g_strdup(msg);  	} else {  		/* OTR has processed this message */ -		ConnContext *context = otrl_context_find(irc->otr->us, handle, +		ConnContext *context = otrl_context_find(irc->otr->us, iu->bu->handle,  			ic->acc->user, ic->acc->prpl->name, 0, NULL, NULL, NULL);  		if(context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED && -		   set_getbool(&ic->bee->set, "color_encrypted")) { +		   set_getbool(&ic->bee->set, "otr_color_encrypted")) {  			/* color according to f'print trust */  			int color;  			const char *trust = context->active_fingerprint->trust; @@ -397,34 +398,34 @@ char *otr_handle_message(struct im_connection *ic, const char *handle, const cha  	}  } -int otr_send_message(struct im_connection *ic, const char *handle, const char *msg, int flags) +char *otr_filter_msg_out(irc_user_t *iu, char *msg, int flags)  {	  	int st;  	char *otrmsg = NULL;  	ConnContext *ctx = NULL; -	irc_t *irc = ic->bee->ui_data; +	irc_t *irc = iu->irc; +	struct im_connection *ic = iu->bu->ic;  	/* don't do OTR on certain (not classic IM) protocols, e.g. twitter */  	if(ic->acc->prpl->options & OPT_NOOTR) { -		/* TODO(wilmer): const */ -		return (ic->acc->prpl->buddy_msg(ic, (char*) handle, (char*) msg, flags)); +		return msg;  	}  	st = otrl_message_sending(irc->otr->us, &otr_ops, ic, -		ic->acc->user, ic->acc->prpl->name, handle, +		ic->acc->user, ic->acc->prpl->name, iu->bu->handle,  		msg, NULL, &otrmsg, NULL, NULL);  	if(st) { -		return st; +		return NULL;  	}  	ctx = otrl_context_find(irc->otr->us, -			handle, ic->acc->user, ic->acc->prpl->name, +			iu->bu->handle, ic->acc->user, ic->acc->prpl->name,  			1, NULL, NULL, NULL);  	if(otrmsg) {  		if(!ctx) {  			otrl_message_free(otrmsg); -			return 1; +			return NULL;  		}  		st = otrl_message_fragment_and_send(&otr_ops, ic, ctx,  			otrmsg, OTRL_FRAGMENT_SEND_ALL, NULL); @@ -432,16 +433,20 @@ int otr_send_message(struct im_connection *ic, const char *handle, const char *m  	} else {  		/* note: otrl_message_sending handles policy, so that if REQUIRE_ENCRYPTION is set,  		   this case does not occur */ -		st = ic->acc->prpl->buddy_msg( ic, (char *)handle, (char *)msg, flags ); +		return msg;  	} -	return st; +	/* TODO: Error reporting should be done here now (if st!=0), probably. */ +	 +	return NULL;  }  static const struct irc_plugin otr_plugin =  {  	otr_irc_new,  	otr_irc_free, +	otr_filter_msg_out, +	otr_filter_msg_in,  };  static void cmd_otr(irc_t *irc, char **args) @@ -715,7 +720,7 @@ void cmd_otr_connect(irc_t *irc, char **args)  		return;  	} -	/* TODO(wilmer): imc_buddy_msg(u->bu->ic, u->bu->handle, "?OTR?", 0); */ +	bee_user_msg(irc->b, u->bu, "?OTR?", 0);  }  void cmd_otr_smp(irc_t *irc, char **args) @@ -40,7 +40,6 @@ struct im_connection;  struct account; -#ifdef WITH_OTR  #include <libotr/proto.h>  #include <libotr/message.h>  #include <libotr/privkey.h> @@ -80,29 +79,4 @@ void otr_rename(const char *onick, const char *nnick);  /* called from account_add() */  int otr_check_for_key(struct account *a); -/* called from imcb_buddy_msg() */ -char *otr_handle_message(struct im_connection *ic, const char *handle, -	const char *msg); -	 -/* called from imc_buddy_msg() */ -int otr_send_message(struct im_connection *ic, const char *handle, const char *msg, -	int flags); - -#else - -typedef void otr_t; -typedef void *OtrlMessageAppOps; - -#define otr_free(otr) {} -#define otr_load(irc) {} -#define otr_save(irc) {} -#define otr_remove(nick) {} -#define otr_rename(onick,nnick) {} -#define otr_check_for_key(acc) (0) -#define otr_handle_message(ic,handle,msg) (g_strdup(msg)) -#define otr_send_message(ic,h,m,f) (ic->acc->prpl->buddy_msg(ic,h,m,f)) - -void cmd_otr_nosupport(void *, char **); - -#endif  #endif diff --git a/protocols/bee_user.c b/protocols/bee_user.c index 04253c47..33853a1e 100644 --- a/protocols/bee_user.c +++ b/protocols/bee_user.c @@ -237,10 +237,6 @@ void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, ui  		}  	} -	if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) || -	    ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) ) -		strip_html( msg ); -	  	if( bee->ui->user_msg && bu )  		bee->ui->user_msg( bee, bu, msg, sent_at );  	else | 
