Beispiel #1
0
static xt_status handle_account( struct xt_node *node, gpointer data )
{
	struct xml_parsedata *xd = data;
	char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag;
	char *pass_b64 = NULL;
	unsigned char *pass_cr = NULL;
	int pass_len;
	struct prpl *prpl = NULL;
	account_t *acc;
	struct xt_node *c;
	
	handle = xt_find_attr( node, "handle" );
	pass_b64 = xt_find_attr( node, "password" );
	server = xt_find_attr( node, "server" );
	autoconnect = xt_find_attr( node, "autoconnect" );
	tag = xt_find_attr( node, "tag" );
	
	protocol = xt_find_attr( node, "protocol" );
	if( protocol )
		prpl = find_protocol( protocol );
	
	if( !handle || !pass_b64 || !protocol || !prpl )
		return XT_ABORT;
	else if( ( pass_len = base64_decode( pass_b64, (unsigned char**) &pass_cr ) ) &&
	         arc_decode( pass_cr, pass_len, &password, xd->given_pass ) >= 0 )
	{
		acc = account_add( xd->irc->b, prpl, handle, password );
		if( server )
			set_setstr( &acc->set, "server", server );
		if( autoconnect )
			set_setstr( &acc->set, "auto_connect", autoconnect );
		if( tag )
			set_setstr( &acc->set, "tag", tag );
	}
	else
		return XT_ABORT;
	
	g_free( pass_cr );
	g_free( password );
	
	handle_settings( node, &acc->set );
	
	for( c = node->children; ( c = xt_find_node( c, "buddy" ) ); c = c->next )
	{
		char *handle, *nick;
		
		handle = xt_find_attr( c, "handle" );
		nick = xt_find_attr( c, "nick" );
		
		if( handle && nick )
			nick_set_raw( acc, handle, nick );
		else
			return XT_ABORT;
	}	
	return XT_HANDLED;
}
Beispiel #2
0
static void cmd_add(irc_t *irc, char **cmd)
{
	account_t *a;
	int add_on_server = 1;
	char *handle = NULL, *s;

	if (g_strcasecmp(cmd[1], "-tmp") == 0) {
		MIN_ARGS(3);
		add_on_server = 0;
		cmd++;
	}

	if (!(a = account_get(irc->b, cmd[1]))) {
		irc_rootmsg(irc, "Invalid account");
		return;
	} else if (!(a->ic && (a->ic->flags & OPT_LOGGED_IN))) {
		irc_rootmsg(irc, "That account is not on-line");
		return;
	}

	if (cmd[3]) {
		if (!nick_ok(irc, cmd[3])) {
			irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]);
			return;
		} else if (irc_user_by_name(irc, cmd[3])) {
			irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]);
			return;
		} else {
			nick_set_raw(a, cmd[2], cmd[3]);
		}
	}

	if ((a->flags & ACC_FLAG_HANDLE_DOMAINS) && cmd[2][0] != '_' &&
	    (!(s = strchr(cmd[2], '@')) || s[1] == '\0')) {
		/* If there's no @ or it's the last char, append the user's
		   domain name now. Exclude handles starting with a _ so
		   adding _xmlconsole will keep working. */
		if (s) {
			*s = '\0';
		}
		if ((s = strchr(a->user, '@'))) {
			cmd[2] = handle = g_strconcat(cmd[2], s, NULL);
		}
	}

	if (add_on_server) {
		irc_channel_t *ic;
		char *s, *group = NULL;;

		if ((ic = irc->root->last_channel) &&
		    (s = set_getstr(&ic->set, "fill_by")) &&
		    strcmp(s, "group") == 0 &&
		    (group = set_getstr(&ic->set, "group"))) {
			irc_rootmsg(irc, "Adding `%s' to contact list (group %s)",
			            cmd[2], group);
		} else {
			irc_rootmsg(irc, "Adding `%s' to contact list", cmd[2]);
		}

		a->prpl->add_buddy(a->ic, cmd[2], group);
	} else {
		bee_user_t *bu;
		irc_user_t *iu;

		/* Only for add -tmp. For regular adds, this callback will
		   be called once the IM server confirms. */
		if ((bu = bee_user_new(irc->b, a->ic, cmd[2], BEE_USER_LOCAL)) &&
		    (iu = bu->ui_data)) {
			irc_rootmsg(irc, "Temporarily assigned nickname `%s' "
			            "to contact `%s'", iu->nick, cmd[2]);
		}
	}

	g_free(handle);
}
Beispiel #3
0
static void xml_start_element( GMarkupParseContext *ctx, const gchar *element_name, const gchar **attr_names, const gchar **attr_values, gpointer data, GError **error )
{
	struct xml_parsedata *xd = data;
	irc_t *irc = xd->irc;
	
	if( xd->unknown_tag > 0 )
	{
		xd->unknown_tag ++;
	}
	else if( g_strcasecmp( element_name, "user" ) == 0 )
	{
		char *nick = xml_attr( attr_names, attr_values, "nick" );
		char *pass = xml_attr( attr_names, attr_values, "password" );
		int st;
		
		if( !nick || !pass )
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		}
		else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 )
		{
			xd->pass_st = XML_PASS_WRONG;
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Error while decoding password attribute" );
		}
		else if( st == 0 )
		{
			if( xd->pass_st != XML_PASS_CHECK_ONLY )
				xd->pass_st = XML_PASS_OK;
		}
		else
		{
			xd->pass_st = XML_PASS_WRONG;
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Password mismatch" );
		}
	}
	else if( xd->pass_st < XML_PASS_OK )
	{
		/* Let's not parse anything else if we only have to check
		   the password. */
	}
	else if( g_strcasecmp( element_name, "account" ) == 0 )
	{
		char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag;
		char *pass_b64 = NULL;
		unsigned char *pass_cr = NULL;
		int pass_len;
		struct prpl *prpl = NULL;
		
		handle = xml_attr( attr_names, attr_values, "handle" );
		pass_b64 = xml_attr( attr_names, attr_values, "password" );
		server = xml_attr( attr_names, attr_values, "server" );
		autoconnect = xml_attr( attr_names, attr_values, "autoconnect" );
		tag = xml_attr( attr_names, attr_values, "tag" );
		
		protocol = xml_attr( attr_names, attr_values, "protocol" );
		if( protocol )
			prpl = find_protocol( protocol );
		
		if( !handle || !pass_b64 || !protocol )
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		else if( !prpl )
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Unknown protocol: %s", protocol );
		else if( ( pass_len = base64_decode( pass_b64, (unsigned char**) &pass_cr ) ) &&
		         arc_decode( pass_cr, pass_len, &password, xd->given_pass ) >= 0 )
		{
			xd->current_account = account_add( irc->b, prpl, handle, password );
			if( server )
				set_setstr( &xd->current_account->set, "server", server );
			if( autoconnect )
				set_setstr( &xd->current_account->set, "auto_connect", autoconnect );
			if( tag )
				set_setstr( &xd->current_account->set, "tag", tag );
		}
		else
		{
			/* Actually the _decode functions don't even return error codes,
			   but maybe they will later... */
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Error while decrypting account password" );
		}
		
		g_free( pass_cr );
		g_free( password );
	}
	else if( g_strcasecmp( element_name, "setting" ) == 0 )
	{
		char *setting;
		
		if( xd->current_setting )
		{
			g_free( xd->current_setting );
			xd->current_setting = NULL;
		}
		
		if( ( setting = xml_attr( attr_names, attr_values, "name" ) ) )
		{
			if( xd->current_channel != NULL )
				xd->current_set_head = &xd->current_channel->set;
			else if( xd->current_account != NULL )
				xd->current_set_head = &xd->current_account->set;
			else
				xd->current_set_head = &xd->irc->b->set;
			
			xd->current_setting = g_strdup( setting );
		}
		else
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
	}
	else if( g_strcasecmp( element_name, "buddy" ) == 0 )
	{
		char *handle, *nick;
		
		handle = xml_attr( attr_names, attr_values, "handle" );
		nick = xml_attr( attr_names, attr_values, "nick" );
		
		if( xd->current_account && handle && nick )
		{
			nick_set_raw( xd->current_account, handle, nick );
		}
		else
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		}
	}
	else if( g_strcasecmp( element_name, "channel" ) == 0 )
	{
		char *name, *type;
		
		name = xml_attr( attr_names, attr_values, "name" );
		type = xml_attr( attr_names, attr_values, "type" );
		
		if( !name || !type )
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
			return;
		}
		
		/* The channel may exist already, for example if it's &bitlbee.
		   Also, it's possible that the user just reconnected and the
		   IRC client already rejoined all channels it was in. They
		   should still get the right settings. */
		if( ( xd->current_channel = irc_channel_by_name( irc, name ) ) ||
		    ( xd->current_channel = irc_channel_new( irc, name ) ) )
			set_setstr(&xd->current_channel->set, "type", type );
	}
	/* Backward compatibility: Keep this around for a while for people
	   switching from BitlBee 1.2.4+. */
	else if( g_strcasecmp( element_name, "chat" ) == 0 )
	{
		char *handle, *channel;
		
		handle = xml_attr( attr_names, attr_values, "handle" );
		channel = xml_attr( attr_names, attr_values, "channel" );
		
		if( xd->current_account && handle && channel )
		{
			irc_channel_t *ic;
			
			if( ( ic = irc_channel_new( irc, channel ) ) &&
			    set_setstr( &ic->set, "type", "chat" ) &&
			    set_setstr( &ic->set, "chat_type", "room" ) &&
			    set_setstr( &ic->set, "account", xd->current_account->tag ) &&
			    set_setstr( &ic->set, "room", handle ) )
			{
				/* Try to pick up some settings where possible. */
				xd->current_channel = ic;
			}
			else if( ic )
				irc_channel_free( ic );
		}
		else
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		}
	}
	else
	{
		xd->unknown_tag ++;
		irc_rootmsg( irc, "Warning: Unknown XML tag found in configuration file (%s). "
		                  "This may happen when downgrading BitlBee versions. "
		                  "This tag will be skipped and the information will be lost "
		                  "once you save your settings.", element_name );
		/*
		g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
		             "Unkown element: %s", element_name );
		*/
	}
}
Beispiel #4
0
static xt_status handle_account(struct xt_node *node, gpointer data)
{
	struct xml_parsedata *xd = data;
	char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag, *locked;
	char *pass_b64 = NULL;
	unsigned char *pass_cr = NULL;
	int pass_len, local = 0;
	struct prpl *prpl = NULL;
	account_t *acc;
	struct xt_node *c;

	handle = xt_find_attr(node, "handle");
	pass_b64 = xt_find_attr(node, "password");
	server = xt_find_attr(node, "server");
	autoconnect = xt_find_attr(node, "autoconnect");
	tag = xt_find_attr(node, "tag");
	locked = xt_find_attr(node, "locked");

	protocol = xt_find_attr(node, "protocol");
	if (protocol) {
		prpl = find_protocol(protocol);
		if (!prpl) {
			irc_rootmsg(xd->irc, "Error loading user config: Protocol not found: `%s'", protocol);
			return XT_ABORT;
		}
		local = protocol_account_islocal(protocol);
	}

	if (!handle || !pass_b64 || !protocol || !prpl) {
		return XT_ABORT;
	}

	pass_len = base64_decode(pass_b64, (unsigned char **) &pass_cr);
	if (xd->irc->auth_backend) {
		password = g_strdup((char *)pass_cr);
	} else {
		pass_len = arc_decode(pass_cr, pass_len, &password, xd->given_pass);
		if (pass_len < 0) {
			g_free(pass_cr);
			g_free(password);
			return XT_ABORT;
		}
	}

	acc = account_add(xd->irc->b, prpl, handle, password);
	if (server) {
		set_setstr(&acc->set, "server", server);
	}
	if (autoconnect) {
		set_setstr(&acc->set, "auto_connect", autoconnect);
	}
	if (tag) {
		set_setstr(&acc->set, "tag", tag);
	}
	if (local) {
		acc->flags |= ACC_FLAG_LOCAL;
	}
	if (locked && !g_strcasecmp(locked, "true")) {
		acc->flags |= ACC_FLAG_LOCKED;
	}

	g_free(pass_cr);
	g_free(password);

	handle_settings(node, &acc->set);

	for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) {
		char *handle, *nick;

		handle = xt_find_attr(c, "handle");
		nick = xt_find_attr(c, "nick");

		if (handle && nick) {
			nick_set_raw(acc, handle, nick);
		} else {
			return XT_ABORT;
		}
	}
	return XT_HANDLED;
}
Beispiel #5
0
void nick_set(bee_user_t *bu, const char *nick)
{
	nick_set_raw(bu->ic->acc, bu->handle, nick);
}