diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2008-09-07 15:34:50 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2008-09-07 15:34:50 +0100 | 
| commit | ced1e17474366772791186f865bd45d4decfcaf2 (patch) | |
| tree | 3461a801f9f6df2f084d1fa3a015cf4401f36d20 | |
| parent | d4810dff26f128061d122cf120e1e0174d9df1f2 (diff) | |
| parent | ba3a8a578430418050a7fda3c949d65434b23cb3 (diff) | |
Merging BitlBee 1.2.3 release.
| -rw-r--r-- | bitlbee.h | 2 | ||||
| -rw-r--r-- | doc/CHANGES | 7 | ||||
| -rw-r--r-- | doc/user-guide/Makefile | 2 | ||||
| -rw-r--r-- | doc/user-guide/help.xml | 2 | ||||
| -rw-r--r-- | doc/user-guide/user-guide.xml | 2 | ||||
| -rw-r--r-- | irc.c | 4 | ||||
| -rw-r--r-- | root_commands.c | 12 | ||||
| -rw-r--r-- | storage.c | 40 | ||||
| -rw-r--r-- | storage.h | 8 | ||||
| -rw-r--r-- | storage_text.c | 13 | ||||
| -rw-r--r-- | storage_xml.c | 19 | 
11 files changed, 63 insertions, 48 deletions
| @@ -32,7 +32,7 @@  #define _WIN32_WINNT 0x0501  #define PACKAGE "BitlBee" -#define BITLBEE_VERSION "1.2.2" +#define BITLBEE_VERSION "1.2.3"  #define VERSION BITLBEE_VERSION  #define MAX_STRING 511 diff --git a/doc/CHANGES b/doc/CHANGES index f480e3ae..84dbe162 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -3,6 +3,13 @@ found in the bzr commit logs, for example you can try:  http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on +Version 1.2.3: +- Fixed one more flaw similar to the previous hijacking bug, caused by incon- +  sistent handling of the USTATUS_IDENTIFIED state. All code touching these +  variables was reviewed and should be correct now. + +Finished 7 Sep 2008  +  Version 1.2.2:  - Security bugfix: It was possible to hijack accounts (without gaining access    to the old account, it's simply an overwrite) diff --git a/doc/user-guide/Makefile b/doc/user-guide/Makefile index eb31fc0f..9841de8d 100644 --- a/doc/user-guide/Makefile +++ b/doc/user-guide/Makefile @@ -12,7 +12,7 @@ all: user-guide.txt user-guide.html help.txt # user-guide.pdf user-guide.ps user  	mv $*.db.txt $@  %.html: %.db.xml -	xsltproc --output $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< +	xsltproc --output $@ http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $<  %.pdf: %.db.xml  	xmlto --skip-validation pdf $< diff --git a/doc/user-guide/help.xml b/doc/user-guide/help.xml index 34fdb9e2..7487a841 100644 --- a/doc/user-guide/help.xml +++ b/doc/user-guide/help.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="iso-8859-1"?> +<?xml version="1.0" encoding="utf-8"?>  <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">  <book id="BitlBee-Help" xmlns:xi="http://www.w3.org/2003/XInclude"> diff --git a/doc/user-guide/user-guide.xml b/doc/user-guide/user-guide.xml index 5b881fb2..5e1c8fe0 100644 --- a/doc/user-guide/user-guide.xml +++ b/doc/user-guide/user-guide.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="iso-8859-1"?> +<?xml version="1.0" encoding="utf-8"?>  <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">  <book id="BitlBee-User-Guide" xmlns:xi="http://www.w3.org/2003/XInclude"> @@ -37,7 +37,7 @@ static char *set_eval_password( set_t *set, char *value )  {  	irc_t *irc = set->data; -	if( irc->status & USTATUS_IDENTIFIED ) +	if( irc->status & USTATUS_IDENTIFIED && value )  	{  		irc_setpass( irc, value );  		return NULL; @@ -238,7 +238,7 @@ void irc_free( irc_t * irc )  	log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );  	if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) )  -		if( storage_save( irc, TRUE ) != STORAGE_OK ) +		if( storage_save( irc, NULL, TRUE ) != STORAGE_OK )  			irc_usermsg( irc, "Error while saving settings!" );  	irc_connection_list = g_slist_remove( irc_connection_list, irc ); diff --git a/root_commands.c b/root_commands.c index 67847650..8770e707 100644 --- a/root_commands.c +++ b/root_commands.c @@ -139,7 +139,7 @@ static void cmd_account( irc_t *irc, char **cmd );  static void cmd_identify( irc_t *irc, char **cmd )  { -	storage_status_t status = storage_load( irc->nick, cmd[1], irc ); +	storage_status_t status = storage_load( irc, cmd[1] );  	char *account_on[] = { "account", "on", NULL };  	switch (status) { @@ -151,6 +151,8 @@ static void cmd_identify( irc_t *irc, char **cmd )  		break;  	case STORAGE_OK:  		irc_usermsg( irc, "Password accepted, settings and accounts loaded" ); +		irc_setpass( irc, cmd[1] ); +		irc->status |= USTATUS_IDENTIFIED;  		irc_umode_set( irc, "+R", 1 );  		if( set_getbool( &irc->set, "auto_connect" ) )  			cmd_account( irc, account_on ); @@ -170,14 +172,14 @@ static void cmd_register( irc_t *irc, char **cmd )  		return;  	} -	irc_setpass( irc, cmd[1] ); -	switch( storage_save( irc, FALSE )) { +	switch( storage_save( irc, cmd[1], FALSE ) ) {  		case STORAGE_ALREADY_EXISTS:  			irc_usermsg( irc, "Nick is already registered" );  			break;  		case STORAGE_OK:  			irc_usermsg( irc, "Account successfully created" ); +			irc_setpass( irc, cmd[1] );  			irc->status |= USTATUS_IDENTIFIED;  			irc_umode_set( irc, "+R", 1 );  			break; @@ -871,7 +873,9 @@ static void cmd_set( irc_t *irc, char **cmd )  static void cmd_save( irc_t *irc, char **cmd )  { -	if( storage_save( irc, TRUE ) == STORAGE_OK ) +	if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) +		irc_usermsg( irc, "Please create an account first" ); +	else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK )  		irc_usermsg( irc, "Configuration saved" );  	else  		irc_usermsg( irc, "Configuration could not be saved!" ); @@ -102,20 +102,21 @@ storage_status_t storage_check_pass (const char *nick, const char *password)  	return STORAGE_NO_SUCH_USER;  } -storage_status_t storage_load (const char *nick, const char *password, irc_t * irc) +storage_status_t storage_load (irc_t * irc, const char *password)  {  	GList *gl; +	if (irc && irc->status & USTATUS_IDENTIFIED) +		return STORAGE_OTHER_ERROR; +	  	/* Loop until we don't get NO_SUCH_USER */  	for (gl = global.storage; gl; gl = gl->next) {  		storage_t *st = gl->data;  		storage_status_t status; -		status = st->load(nick, password, irc); -		if (status == STORAGE_OK) { -			irc_setpass(irc, password); +		status = st->load(irc, password); +		if (status == STORAGE_OK)  			return status; -		}  		if (status != STORAGE_NO_SUCH_USER)   			return status; @@ -124,9 +125,27 @@ storage_status_t storage_load (const char *nick, const char *password, irc_t * i  	return STORAGE_NO_SUCH_USER;  } -storage_status_t storage_save (irc_t *irc, int overwrite) +storage_status_t storage_save (irc_t *irc, char *password, int overwrite)  { -	return ((storage_t *)global.storage->data)->save(irc, overwrite); +	storage_status_t st; +	 +	if (password != NULL) { +		/* Should only use this in the "register" command. */ +		if (irc->password || overwrite) +			return STORAGE_OTHER_ERROR; +		 +		irc_setpass(irc, password); +	} else if ((irc->status & USTATUS_IDENTIFIED) == 0) { +		return STORAGE_NO_SUCH_USER; +	} +	 +	st = ((storage_t *)global.storage->data)->save(irc, overwrite); +	 +	if (password != NULL) { +		irc_setpass(irc, NULL); +	} +	 +	return st;  }  storage_status_t storage_remove (const char *nick, const char *password) @@ -142,14 +161,16 @@ storage_status_t storage_remove (const char *nick, const char *password)  		storage_status_t status;  		status = st->remove(nick, password); -		if (status != STORAGE_NO_SUCH_USER &&  -			status != STORAGE_OK) +		if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK)  			ret = status;  	}  	return ret;  } +#if 0 +Not using this yet. Test thoroughly before adding UI hooks to this function. +  storage_status_t storage_rename (const char *onick, const char *nnick, const char *password)  {  	storage_status_t status; @@ -188,3 +209,4 @@ storage_status_t storage_rename (const char *onick, const char *nnick, const cha  	return STORAGE_OK;  } +#endif @@ -44,7 +44,7 @@ typedef struct {  	storage_status_t (*check_pass) (const char *nick, const char *password); -	storage_status_t (*load) (const char *nick, const char *password, irc_t * irc); +	storage_status_t (*load) (irc_t *irc, const char *password);  	storage_status_t (*save) (irc_t *irc, int overwrite);  	storage_status_t (*remove) (const char *nick, const char *password); @@ -54,11 +54,11 @@ typedef struct {  storage_status_t storage_check_pass (const char *nick, const char *password); -storage_status_t storage_load (const char *nick, const char *password, irc_t * irc); -storage_status_t storage_save (irc_t *irc, int overwrite); +storage_status_t storage_load (irc_t * irc, const char *password); +storage_status_t storage_save (irc_t *irc, char *password, int overwrite);  storage_status_t storage_remove (const char *nick, const char *password); -storage_status_t storage_rename (const char *onick, const char *nnick, const char *password); +/* storage_status_t storage_rename (const char *onick, const char *nnick, const char *password); */  void register_storage_backend(storage_t *);  G_GNUC_MALLOC GList *storage_init(const char *primary, char **migrate); diff --git a/storage_text.c b/storage_text.c index 78f7e3bd..8ce4edcf 100644 --- a/storage_text.c +++ b/storage_text.c @@ -43,7 +43,7 @@ static void text_init (void)  	   it's read only! */  } -static storage_status_t text_load ( const char *my_nick, const char* password, irc_t *irc ) +static storage_status_t text_load( irc_t *irc, const char* password )  {  	char s[512];  	char *line; @@ -53,10 +53,7 @@ static storage_status_t text_load ( const char *my_nick, const char* password, i  	user_t *ru = user_find( irc, ROOT_NICK );  	account_t *acc, *acc_lookup[9]; -	if( irc->status & USTATUS_IDENTIFIED ) -		return( 1 ); -	 -	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" ); +	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );     	fp = fopen( s, "r" );     	if( !fp ) return STORAGE_NO_SUCH_USER; @@ -68,10 +65,6 @@ static storage_status_t text_load ( const char *my_nick, const char* password, i  		return STORAGE_INVALID_PASSWORD;  	} -	/* Do this now. If the user runs with AuthMode = Registered, the -	   account command will not work otherwise. */ -	irc->status |= USTATUS_IDENTIFIED; -	  	while( fscanf( fp, "%511[^\n]s", s ) > 0 )  	{  		fgetc( fp ); @@ -100,7 +93,7 @@ static storage_status_t text_load ( const char *my_nick, const char* password, i  			acc_lookup[8] = acc;  	} -	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" ); +	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );  	fp = fopen( s, "r" );  	if( !fp ) return STORAGE_NO_SUCH_USER;  	while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 ) diff --git a/storage_xml.c b/storage_xml.c index 240bb589..b78c3661 100644 --- a/storage_xml.c +++ b/storage_xml.c @@ -287,7 +287,7 @@ static void xml_init( void )  		log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to `%s'.", global.conf->configdir );  } -static storage_status_t xml_load_real( const char *my_nick, const char *password, irc_t *irc, xml_pass_st action ) +static storage_status_t xml_load_real( irc_t *irc, const char *my_nick, const char *password, xml_pass_st action )  {  	GMarkupParseContext *ctx;  	struct xml_parsedata *xd; @@ -295,9 +295,6 @@ static storage_status_t xml_load_real( const char *my_nick, const char *password  	GError *gerr = NULL;  	int fd, st; -	if( irc && irc->status & USTATUS_IDENTIFIED ) -		return( 1 ); -	  	xd = g_new0( struct xml_parsedata, 1 );  	xd->irc = irc;  	xd->given_nick = g_strdup( my_nick ); @@ -349,21 +346,19 @@ static storage_status_t xml_load_real( const char *my_nick, const char *password  	if( action == XML_PASS_CHECK_ONLY )  		return STORAGE_OK; -	irc->status |= USTATUS_IDENTIFIED; -	  	return STORAGE_OK;  } -static storage_status_t xml_load( const char *my_nick, const char *password, irc_t *irc ) +static storage_status_t xml_load( irc_t *irc, const char *password )  { -	return xml_load_real( my_nick, password, irc, XML_PASS_UNKNOWN ); +	return xml_load_real( irc, irc->nick, password, XML_PASS_UNKNOWN );  }  static storage_status_t xml_check_pass( const char *my_nick, const char *password )  {  	/* This is a little bit risky because we have to pass NULL for the  	   irc_t argument. This *should* be fine, if I didn't miss anything... */ -	return xml_load_real( my_nick, password, NULL, XML_PASS_CHECK_ONLY ); +	return xml_load_real( NULL, my_nick, password, XML_PASS_CHECK_ONLY );  }  static int xml_printf( int fd, int indent, char *fmt, ... ) @@ -399,12 +394,6 @@ static storage_status_t xml_save( irc_t *irc, int overwrite )  	md5_byte_t pass_md5[21];  	md5_state_t md5_state; -	if( irc->password == NULL ) -	{ -		irc_usermsg( irc, "Please register yourself if you want to save your settings." ); -		return STORAGE_OTHER_ERROR; -	} -	  	path2 = g_strdup( irc->nick );  	nick_lc( path2 );  	g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" ); | 
