コード例 #1
0
static int _handle_privmsg_command(t_connection * conn, int numparams, char ** params, char * text)
{
    if ((numparams>=1)&&(text))
    {
        int i;
        char ** e;

        e = irc_get_listelems(params[0]);
        /* FIXME: support wildcards! */

        /* start amadeo: code was sent by some unkown fellow of pvpgn (maybe u wanna give us your name
           for any credits), it adds nick-registration, i changed some things here and there... */
        for (i=0; ((e)&&(e[i])); i++) {
            if (strcasecmp(e[i],"NICKSERV")==0) {
                char * pass;
                char * p;

                pass = std::strchr(text,' ');
                if (pass)
                    *pass++ = '\0';

                if (strcasecmp(text,"identify")==0) {
                    switch (conn_get_state(conn)) {
                    case conn_state_bot_password:
                    {
                        if (pass) {
                            t_hash h;

                            for (p = pass; *p; p++)
                                if (std::isupper((int)*p)) *p = std::tolower(*p);
                            bnet_hash(&h,std::strlen(pass),pass);
                            irc_authenticate(conn,hash_get_str(h));
                        }
                        else {
                            message_send_text(conn,message_type_notice,NULL,"Syntax: IDENTIFY <password> (max 16 characters)");
                        }
                        break;
                    }
                    case conn_state_loggedin:
                    {
                        message_send_text(conn,message_type_notice,NULL,"You don't need to IDENTIFY");
                        break;
                    }
                    default:
                        ;
                        eventlog(eventlog_level_trace,__FUNCTION__,"got /msg in unexpected connection state (%s)",conn_state_get_str(conn_get_state(conn)));
                    }
                }
                else if (strcasecmp(text,"register")==0) {
                    unsigned int j;
                    t_hash       passhash;
                    t_account  * temp;
                    char         msgtemp[MAX_IRC_MESSAGE_LEN];
                    char       * username=(char *)conn_get_loggeduser(conn);

                    if (account_check_name(username)<0) {
                        message_send_text(conn,message_type_error,conn,"Account name contains invalid symbol!");
                        break;
                    }

                    if(!prefs_get_allow_new_accounts()) {
                        message_send_text(conn,message_type_error,conn,"Account creation is not allowed");
                        break;
                    }

                    if (!pass || pass[0]=='\0' || (std::strlen(pass)>16) ) {
                        message_send_text(conn,message_type_error,conn,"Syntax: REGISTER <password> (max 16 characters)");
                        break;
                    }

                    for (j=0; j<std::strlen(pass); j++)
                        if (std::isupper((int)pass[j])) pass[j] = std::tolower((int)pass[j]);

                    bnet_hash(&passhash,std::strlen(pass),pass);

                    snprintf(msgtemp, sizeof(msgtemp), "Trying to create account \"%s\" with password \"%s\"",username,pass);
                    message_send_text(conn,message_type_info,conn,msgtemp);

                    temp = accountlist_create_account(username,hash_get_str(passhash));
                    if (!temp) {
                        message_send_text(conn,message_type_error,conn,"Failed to create account!");
                        eventlog(eventlog_level_debug,__FUNCTION__,"[%d] account \"%s\" not created (failed)",conn_get_socket(conn),username);
                        conn_unget_chatname(conn,username);
                        break;
                    }

                    snprintf(msgtemp, sizeof(msgtemp), "Account "UID_FORMAT" created.",account_get_uid(temp));
                    message_send_text(conn,message_type_info,conn,msgtemp);
                    eventlog(eventlog_level_debug,__FUNCTION__,"[%d] account \"%s\" created",conn_get_socket(conn),username);
                    conn_unget_chatname(conn,username);
                }
                else {
                    char tmp[MAX_IRC_MESSAGE_LEN+1];
                    message_send_text(conn,message_type_notice,NULL,"Invalid arguments for NICKSERV");
                    snprintf(tmp, sizeof(tmp), ":Unrecognized command \"%s\"", text);
                    message_send_text(conn,message_type_notice,NULL,tmp);
                }
            }
            else if (conn_get_state(conn)==conn_state_loggedin) {
                if (e[i][0]=='#') {
                    /* channel message */
                    t_channel * channel;

                    if ((channel = channellist_find_channel_by_name(irc_convert_ircname(e[i]),NULL,NULL))) {
                        if ((std::strlen(text)>=9)&&(std::strncmp(text,"\001ACTION ",8)==0)&&(text[std::strlen(text)-1]=='\001')) {
                            /* at least "\001ACTION \001" */
                            /* it's a CTCP ACTION message */
                            text = text + 8;
                            text[std::strlen(text)-1] = '\0';
                            channel_message_send(channel,message_type_emote,conn,text);
                        }
                        else {
                            channel_message_log(channel, conn, 1, text);
                            channel_message_send(channel,message_type_talk,conn,text);
                        }
                    }
                    else {
                        irc_send(conn,ERR_NOSUCHCHANNEL,":No such channel");
                    }
                }
                else {
                    /* whisper */
                    t_connection * user;

                    if ((user = connlist_find_connection_by_accountname(e[i])))
                    {
                        message_send_text(user,message_type_whisper,conn,text);
                    }
                    else
                    {
                        irc_send(conn,ERR_NOSUCHNICK,":No such user");
                    }
                }
            }
        }
        if (e)
            irc_unget_listelems(e);
    }
    else
        irc_send(conn,ERR_NEEDMOREPARAMS,"PRIVMSG :Not enough parameters");
    return 0;
}
コード例 #2
0
ファイル: handle_bot.c プロジェクト: 91D2/pvpgn
extern int handle_bot_packet(t_connection * c, t_packet const * const packet)
{
    t_packet * rpacket;
    
    if (!c)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL connection",conn_get_socket(c));
	return -1;
    }
    if (!packet)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL packet",conn_get_socket(c));
	return -1;
    }
    if (packet_get_class(packet)!=packet_class_raw)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
        return -1;
    }
    
    {
	char const * const linestr=packet_get_str_const(packet,0,MAX_MESSAGE_LEN);
	
	if (packet_get_size(packet)<2) /* empty line */
	    return 0;
	if (!linestr)
	{
	    eventlog(eventlog_level_warn,__FUNCTION__,"[%d] line too long",conn_get_socket(c));
	    return 0;
	}
	
	switch (conn_get_state(c))
	{
	case conn_state_connected:
	    conn_add_flags(c,MF_PLUG);
	    conn_set_clienttag(c,CLIENTTAG_BNCHATBOT_UINT);
	    
	    {
		char const * temp=linestr;
		
		if (temp[0]=='\004') /* FIXME: no echo, ignore for now (we always do no echo) */
		    temp = &temp[1];
		
		if (temp[0]=='\0') /* empty line */
		{
		    conn_set_state(c,conn_state_bot_username); /* don't look for ^D or reset tag and flags */
		    break;
		}
		
		conn_set_state(c,conn_state_bot_password);
		
		if (conn_set_loggeduser(c,temp)<0)
		    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set username to \"%s\"",conn_get_socket(c),temp);
		
		{
		    char const * const msg="\r\nPassword: "******"[%d] could not create rpacket",conn_get_socket(c));
			break;
		    }
#if 1 /* don't echo */
		    packet_append_ntstring(rpacket,conn_get_loggeduser(c));
#endif
		    packet_append_ntstring(rpacket,msg);
		    conn_push_outqueue(c,rpacket);
		    packet_del_ref(rpacket);
		}
	    }
	    break;
	    
	case conn_state_bot_username:
	    conn_set_state(c,conn_state_bot_password);
	    
	    if (conn_set_loggeduser(c,linestr)<0)
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set username to \"%s\"",conn_get_socket(c),linestr);
	    
	    {
		char const * const temp="\r\nPassword: "******"[%d] could not create rpacket",conn_get_socket(c));
		    break;
		}
#if 1 /* don't echo */
		packet_append_ntstring(rpacket,linestr);
#endif
		packet_append_ntstring(rpacket,temp);
		conn_push_outqueue(c,rpacket);
		packet_del_ref(rpacket);
	    }
	    break;
	    
	case conn_state_bot_password:
	    {
		char const * const tempa="\r\nLogin failed.\r\n\r\nUsername: "******"\r\nAccount has no bot access.\r\n\r\nUsername: "******"[%d] could not create rpacket",conn_get_socket(c));
			break;
		    }
		    
		    packet_append_ntstring(rpacket,tempa);
		    conn_push_outqueue(c,rpacket);
		    packet_del_ref(rpacket);
		    break;
		}
		if (connlist_find_connection_by_accountname(loggeduser))
		{
		    eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (already logged in)",conn_get_socket(c),loggeduser);
		    conn_set_state(c,conn_state_bot_username);
		    
		    if (!(rpacket = packet_create(packet_class_raw)))
		    {
			eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
			break;
		    }
		    
		    packet_append_ntstring(rpacket,tempa);
		    conn_push_outqueue(c,rpacket);
		    packet_del_ref(rpacket);
		    break;
		}
		if (!(account = accountlist_find_account(loggeduser)))
		{
			eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (bad account)",conn_get_socket(c),loggeduser);
			conn_set_state(c,conn_state_bot_username);
			
			if (!(rpacket = packet_create(packet_class_raw)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
			    break;
			}
			
			packet_append_ntstring(rpacket,tempa);
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
		    break;
		}
		if ((oldstrhash1 = account_get_pass(account)))
		{
		    if (hash_set_str(&oldpasshash1,oldstrhash1)<0)
		    {
			eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (corrupted passhash1?)",conn_get_socket(c),loggeduser);
			conn_set_state(c,conn_state_bot_username);
			
			if (!(rpacket = packet_create(packet_class_raw)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
			    break;
			}
			
			packet_append_ntstring(rpacket,tempa);
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
			break;
		    }

                    testpass = xstrdup(linestr);
		    {
			unsigned int i;
			
			for (i=0; i<strlen(testpass); i++)
			    if (isupper((int)testpass[i]))
				testpass[i] = tolower((int)testpass[i]);
		    }
		    if (bnet_hash(&trypasshash1,strlen(testpass),testpass)<0) /* FIXME: force to lowercase */
		    {
			eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (unable to hash password)",conn_get_socket(c), loggeduser);
			conn_set_state(c,conn_state_bot_username);

			xfree((void *)testpass);
			
			if (!(rpacket = packet_create(packet_class_raw)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
			    break;
			}
			
			packet_append_ntstring(rpacket,tempa);
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
			break;
		    }
		    xfree((void *)testpass);
		    if (hash_eq(trypasshash1,oldpasshash1)!=1)
		    {
			eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (wrong password)",conn_get_socket(c), loggeduser);
			conn_set_state(c,conn_state_bot_username);
			
			if (!(rpacket = packet_create(packet_class_raw)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
			    break;
			}
			
			packet_append_ntstring(rpacket,tempa);
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
			break;
		    }
		    
		    
		    if (account_get_auth_botlogin(account)!=1) /* default to false */
		    {
			eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (no bot access)",conn_get_socket(c), loggeduser);
			conn_set_state(c,conn_state_bot_username);
			
			if (!(rpacket = packet_create(packet_class_raw)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
			    break;
			}
			
			packet_append_ntstring(rpacket,tempb);
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
			break;
		    }
		    else if (account_get_auth_lock(account)==1) /* default to false */
		    {
			eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (this account is locked)",conn_get_socket(c), loggeduser);
			conn_set_state(c,conn_state_bot_username);
			
			if (!(rpacket = packet_create(packet_class_raw)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
			    break;
			}
			
			packet_append_ntstring(rpacket,tempb);
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
			break;
		    }
		    
		    eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" bot logged in (correct password)",conn_get_socket(c), loggeduser);
		}
		else
		{
		    eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" bot logged in (no password)",conn_get_socket(c), loggeduser);
		}
		    if (!(rpacket = packet_create(packet_class_raw))) /* if we got this far, let them log in even if this fails */
			eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
		    else
		    {
			packet_append_ntstring(rpacket,"\r\n");
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
		    }

			bnetd_log(loggeduser, addr_num_to_ip_str(conn_get_addr(c)), "BOT", "LOGIN", NULL, 1, 0);
		    conn_login(c,account,loggeduser);

		    message_send_text(c,message_type_uniqueid,c,loggeduser);
		    		    
		    if (conn_set_channel(c,CHANNEL_NAME_CHAT)<0)
			conn_set_channel(c,CHANNEL_NAME_BANNED); /* should not fail */
	    }
	    break;
	    
	case conn_state_loggedin:
	    {
		t_channel const * channel;
		
		conn_set_idletime(c);
		
		if ((channel = conn_get_channel(c)))
		    channel_message_log(channel,c,1,linestr);
		/* we don't log game commands currently */
		
		if (linestr[0]=='/')
		    handle_command(c,linestr);
		else
		    if (channel && !conn_quota_exceeded(c,linestr))
			channel_message_send(channel,message_type_talk,c,linestr);
		    /* else discard */
	    }
	    break;
	    
	default:
	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown bot connection state %d",conn_get_socket(c),(int)conn_get_state(c));
	}
    }
    
    return 0;
}