Example #1
0
File: mgmt.c Project: redlicha/tgt
static int account_mgmt(int lld_no,  struct mgmt_task *mtask)
{
    struct tgtadm_req *req = &mtask->req;
    struct tgtadm_rsp *rsp = &mtask->rsp;
    int err = TGTADM_UNSUPPORTED_OPERATION;
    char *user, *password;

    switch (req->op) {
    case OP_NEW:
    case OP_DELETE:
    case OP_BIND:
    case OP_UNBIND:
        user = strstr(mtask->buf, "user="******"password=");

            err = account_add(user, password);
        } else {
            if (req->op == OP_DELETE) {
                err = account_del(user);
            } else
                err = account_ctl(req->tid, req->ac_dir,
                                  user, req->op == OP_BIND);
        }
        break;
    case OP_SHOW:
retry:
        err = account_show(mtask->buf, mtask->bsize);
        if (err == mtask->bsize) {
            char *p;
            mtask->bsize <<= 1;
            p = realloc(mtask->buf, mtask->bsize);
            if (p) {
                mtask->buf = p;
                goto retry;
            } else
                err = TGTADM_NOMEM;
        }
        break;
    default:
        break;
    }
out:
    if (req->op == OP_SHOW)
        set_show_results(rsp, &err);
    else {
        rsp->err = err;
        rsp->len = sizeof(*rsp);
    }
    return err;
}
Example #2
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;
}
Example #3
0
File: mgmt.c Project: fujita/tgt
static tgtadm_err account_mgmt(int lld_no,  struct mgmt_task *mtask)
{
	struct tgtadm_req *req = &mtask->req;
	char *user, *password;
	tgtadm_err adm_err = TGTADM_UNSUPPORTED_OPERATION;

	switch (req->op) {
	case OP_NEW:
	case OP_DELETE:
	case OP_BIND:
	case OP_UNBIND:
		user = strstr(mtask->req_buf, "user="******"password=");

			adm_err = account_add(user, password);
		} else {
			if (req->op == OP_DELETE) {
				adm_err = account_del(user);
			} else
				adm_err = account_ctl(req->tid, req->ac_dir,
						      user, req->op == OP_BIND);
		}
		break;
	case OP_SHOW:
		concat_buf_init(&mtask->rsp_concat);
		adm_err = account_show(&mtask->rsp_concat);
		concat_buf_finish(&mtask->rsp_concat);
		break;
	default:
		break;
	}

	return adm_err;
}
Example #4
0
static void cmd_account(irc_t *irc, char **cmd)
{
	account_t *a;
	int len;

	if (global.conf->authmode == AUTHMODE_REGISTERED && !(irc->status & USTATUS_IDENTIFIED)) {
		irc_rootmsg(irc, "This server only accepts registered users");
		return;
	}

	len = strlen(cmd[1]);

	if (len >= 1 && g_strncasecmp(cmd[1], "add", len) == 0) {
		struct prpl *prpl;

		MIN_ARGS(3);

		if (!global.conf->allow_account_add) {
			irc_rootmsg(irc, "This server does not allow adding new accounts");
			return;
		}

		if (cmd[4] == NULL) {
			for (a = irc->b->accounts; a; a = a->next) {
				if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
					irc_rootmsg(irc, "Enter password for account %s "
					            "first (use /OPER)", a->tag);
					return;
				}
			}

			irc->status |= OPER_HACK_ACCOUNT_PASSWORD;
		}

		prpl = find_protocol(cmd[2]);

		if (prpl == NULL) {
			if (is_protocol_disabled(cmd[2])) {
				irc_rootmsg(irc, "Protocol disabled in global config");
			} else {
				irc_rootmsg(irc, "Unknown protocol");
			}
			return;
		}

		for (a = irc->b->accounts; a; a = a->next) {
			if (a->prpl == prpl && prpl->handle_cmp(a->user, cmd[3]) == 0) {
				irc_rootmsg(irc, "Warning: You already have an account with "
				            "protocol `%s' and username `%s'. Are you accidentally "
				            "trying to add it twice?", prpl->name, cmd[3]);
			}
		}

		a = account_add(irc->b, prpl, cmd[3], cmd[4] ? cmd[4] : PASSWORD_PENDING);
		if (cmd[5]) {
			irc_rootmsg(irc, "Warning: Passing a servername/other flags to `account add' "
			            "is now deprecated. Use `account set' instead.");
			set_setstr(&a->set, "server", cmd[5]);
		}

		irc_rootmsg(irc, "Account successfully added with tag %s", a->tag);

		if (cmd[4] == NULL) {
			set_t *oauth = set_find(&a->set, "oauth");
			if (oauth && bool2int(set_value(oauth))) {
				*a->pass = '******';
				irc_rootmsg(irc, "No need to enter a password for this "
				            "account since it's using OAuth");
			} else {
				irc_rootmsg(irc, "You can now use the /OPER command to "
				            "enter the password");
				if (oauth) {
					irc_rootmsg(irc, "Alternatively, enable OAuth if "
					            "the account supports it: account %s "
					            "set oauth on", a->tag);
				}
			}
		}

		return;
	} else if (len >= 1 && g_strncasecmp(cmd[1], "list", len) == 0) {
		int i = 0;

		if (strchr(irc->umode, 'b')) {
			irc_rootmsg(irc, "Account list:");
		}

		for (a = irc->b->accounts; a; a = a->next) {
			char *con;

			if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) {
				con = " (connected)";
			} else if (a->ic) {
				con = " (connecting)";
			} else if (a->reconnect) {
				con = " (awaiting reconnect)";
			} else {
				con = "";
			}

			irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con);

			i++;
		}
		irc_rootmsg(irc, "End of account list");

		return;
	} else if (cmd[2]) {
		/* Try the following two only if cmd[2] == NULL */
	} else if (len >= 2 && g_strncasecmp(cmd[1], "on", len) == 0) {
		if (irc->b->accounts) {
			irc_rootmsg(irc, "Trying to get all accounts connected...");

			for (a = irc->b->accounts; a; a = a->next) {
				if (!a->ic && a->auto_connect) {
					if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
						irc_rootmsg(irc, "Enter password for account %s "
						            "first (use /OPER)", a->tag);
					} else {
						account_on(irc->b, a);
					}
				}
			}
		} else {
			irc_rootmsg(irc, "No accounts known. Use `account add' to add one.");
		}

		return;
	} else if (len >= 2 && g_strncasecmp(cmd[1], "off", len) == 0) {
		irc_rootmsg(irc, "Deactivating all active (re)connections...");

		for (a = irc->b->accounts; a; a = a->next) {
			if (a->ic) {
				account_off(irc->b, a);
			} else if (a->reconnect) {
				cancel_auto_reconnect(a);
			}
		}

		return;
	}

	MIN_ARGS(2);
	len = strlen(cmd[2]);

	/* At least right now, don't accept on/off/set/del as account IDs even
	   if they're a proper match, since people not familiar with the new
	   syntax yet may get a confusing/nasty surprise. */
	if (g_strcasecmp(cmd[1], "on") == 0 ||
	    g_strcasecmp(cmd[1], "off") == 0 ||
	    g_strcasecmp(cmd[1], "set") == 0 ||
	    g_strcasecmp(cmd[1], "del") == 0 ||
	    (a = account_get(irc->b, cmd[1])) == NULL) {
		irc_rootmsg(irc, "Could not find account `%s'.", cmd[1]);

		return;
	}

	if (len >= 1 && g_strncasecmp(cmd[2], "del", len) == 0) {
		if (a->flags & ACC_FLAG_LOCKED) {
			irc_rootmsg(irc, "Account is locked, can't delete");
		}
		else if (a->ic) {
			irc_rootmsg(irc, "Account is still logged in, can't delete");
		} else {
			account_del(irc->b, a);
			irc_rootmsg(irc, "Account deleted");
		}
	} else if (len >= 2 && g_strncasecmp(cmd[2], "on", len) == 0) {
		if (a->ic) {
			irc_rootmsg(irc, "Account already online");
		} else if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
			irc_rootmsg(irc, "Enter password for account %s "
			            "first (use /OPER)", a->tag);
		} else {
			account_on(irc->b, a);
		}
	} else if (len >= 2 && g_strncasecmp(cmd[2], "off", len) == 0) {
		if (a->ic) {
			account_off(irc->b, a);
		} else if (a->reconnect) {
			cancel_auto_reconnect(a);
			irc_rootmsg(irc, "Reconnect cancelled");
		} else {
			irc_rootmsg(irc, "Account already offline");
		}
	} else if (len >= 1 && g_strncasecmp(cmd[2], "set", len) == 0) {
		cmd_set_real(irc, cmd + 2, &a->set, cmd_account_set_checkflags);
	} else {
		irc_rootmsg(irc,
		            "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "account",
		            cmd[2]);
	}
}
Example #5
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 );
		*/
	}
}
Example #6
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;
}