static int on_d2cs_authreply(t_connection * c, t_packet const * packet) { t_packet * rpacket; unsigned int version; unsigned int try_version; unsigned int reply; char const * realmname; t_realm * realm; if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_authreply)) { eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size"); return -1; } if (!(realmname=packet_get_str_const(packet,sizeof(t_d2cs_bnetd_authreply),REALM_NAME_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad realmname"); return -1; } if (!(realm=realmlist_find_realm(realmname))) { realm=realmlist_find_realm_by_ip(conn_get_addr(c)); /* should not fail - checked in handle_init_packet() handle_init.c */ eventlog(eventlog_level_warn,__FUNCTION__, "warn: realm name mismatch %s %s", realm_get_name(realm), realmname); if (!(prefs_allow_d2cs_setname())) { /* fail if allow_d2cs_setname = false */ eventlog(eventlog_level_error,__FUNCTION__, "d2cs not allowed to set realm name"); return -1; } if (realm_get_active(realm)) { /* fail if realm already active */ eventlog(eventlog_level_error,__FUNCTION__, "cannot set realm name to %s (realm already active)",realmname); return -1; } realm_set_name(realm,realmname); } version=prefs_get_d2cs_version(); try_version=bn_int_get(packet->u.d2cs_bnetd_authreply.version); if (version && version != try_version) { eventlog(eventlog_level_error,__FUNCTION__,"d2cs version mismatch 0x%X - 0x%X", try_version,version); reply=BNETD_D2CS_AUTHREPLY_BAD_VERSION; } else { reply=BNETD_D2CS_AUTHREPLY_SUCCEED; } if (reply==BNETD_D2CS_AUTHREPLY_SUCCEED) { eventlog(eventlog_level_info,__FUNCTION__,"d2cs %s authed", addr_num_to_ip_str(conn_get_addr(c))); conn_set_state(c,conn_state_loggedin); realm_active(realm,c); } else { eventlog(eventlog_level_error,__FUNCTION__,"failed to auth d2cs %s", addr_num_to_ip_str(conn_get_addr(c))); } if ((rpacket=packet_create(packet_class_d2cs_bnetd))) { packet_set_size(rpacket,sizeof(t_bnetd_d2cs_authreply)); packet_set_type(rpacket,BNETD_D2CS_AUTHREPLY); bn_int_set(&rpacket->u.bnetd_d2cs_authreply.h.seqno,1); bn_int_set(&rpacket->u.bnetd_d2cs_authreply.reply,reply); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } return 0; }
static int on_d2cs_authreply(t_connection * c, t_packet const * packet) { t_packet * rpacket; unsigned int version; unsigned int try_version; unsigned int reply; char const * realmname; t_realm * realm; if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_authreply)) { eventlog(eventlog_level_error,"on_d2cs_authreply","got bad packet size"); return -1; } if (!(realmname=packet_get_str_const(packet,sizeof(t_d2cs_bnetd_authreply),REALM_NAME_LEN))) { eventlog(eventlog_level_error,"on_d2cs_authreply","got bad realmname"); return -1; } if (!(realm=realmlist_find_realm_by_ip(conn_get_addr(c)))) { eventlog(eventlog_level_error,"handle_init_packet", "realm not found"); return -1; } if (realm_get_name(realm) && strcasecmp(realmname,realm_get_name(realm))) { eventlog(eventlog_level_error,"handle_init_packet", "warn: realm name mismatch %s %s", realm_get_name(realm),realmname); } version=prefs_get_d2cs_version(); try_version=bn_int_get(packet->u.d2cs_bnetd_authreply.version); if (version && version != try_version) { eventlog(eventlog_level_error,"on_d2cs_authreply","d2cs version mismatch 0x%X - 0x%X", try_version,version); reply=BNETD_D2CS_AUTHREPLY_BAD_VERSION; } else { reply=BNETD_D2CS_AUTHREPLY_SUCCEED; } if (reply==BNETD_D2CS_AUTHREPLY_SUCCEED) { eventlog(eventlog_level_error,"on_d2cs_authreply","d2cs %s authed", addr_num_to_ip_str(conn_get_addr(c))); conn_set_state(c,conn_state_loggedin); if (prefs_allow_d2cs_setname()) realm_set_name(realm,realmname); realm_active(realm,c); } else { eventlog(eventlog_level_error,"on_d2cs_authreply","failed to auth d2cs %s", addr_num_to_ip_str(conn_get_addr(c))); } if ((rpacket=packet_create(packet_class_d2cs_bnetd))) { packet_set_size(rpacket,sizeof(t_bnetd_d2cs_authreply)); packet_set_type(rpacket,BNETD_D2CS_AUTHREPLY); bn_int_set(&rpacket->u.bnetd_d2cs_authreply.reply,reply); queue_push_packet(conn_get_out_queue(c),rpacket); packet_del_ref(rpacket); } return 0; }
extern int trans_net(unsigned int clientaddr, unsigned int *addr, unsigned short *port) { t_elem const *curr; t_trans *entry; char temp1[32]; char temp2[32]; char temp3[32]; char temp4[32]; #ifdef DEBUG_TRANS eventlog(eventlog_level_debug, __FUNCTION__, "checking %s for client %s ...", addr_num_to_addr_str(*addr, *port), addr_num_to_ip_str(clientaddr)); #endif if (trans_head) { LIST_TRAVERSE_CONST(trans_head, curr) { if (!(entry = (t_trans*)elem_get_data(curr))) { eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list"); continue; } #ifdef DEBUG_TRANS eventlog(eventlog_level_debug, __FUNCTION__, "against entry -> %s output %s network %s", addr_get_addr_str(entry->input, temp1, sizeof(temp1)), addr_get_addr_str(entry->output, temp2, sizeof(temp2)), netaddr_get_addr_str(entry->network, temp3, sizeof(temp3))); #endif if (addr_get_ip(entry->input) != *addr || addr_get_port(entry->input) != *port) { #ifdef DEBUG_TRANS eventlog(eventlog_level_debug, __FUNCTION__, "entry does match input address"); #endif continue; } if (netaddr_contains_addr_num(entry->network, clientaddr) == 0) { #ifdef DEBUG_TRANS eventlog(eventlog_level_debug, __FUNCTION__, "client is not in the correct network"); #endif continue; } #ifdef DEBUG_TRANS eventlog(eventlog_level_debug, __FUNCTION__, "%s translated to %s", addr_num_to_addr_str(*addr, *port), addr_get_addr_str(entry->output, temp4, sizeof(temp4))); #endif *addr = addr_get_ip(entry->output); *port = addr_get_port(entry->output); return 1; /* match found in list */ } } #ifdef DEBUG_TRANS eventlog(eventlog_level_debug, __FUNCTION__, "no match found for %s (not translated)", addr_num_to_addr_str(*addr, *port)); #endif return 0; /* no match found in list */ }
static int irc_who_connection(t_connection * dest, t_connection * c) { t_account * a; char const * tempuser; char const * tempowner; char const * tempname; char const * tempip; char const * tempflags = "@"; /* FIXME: that's dumb */ char temp[MAX_IRC_MESSAGE_LEN]; char const * tempchannel; if (!dest) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL destination"); return -1; } if (!c) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } a = conn_get_account(c); if (!(tempuser = clienttag_uint_to_str(conn_get_clienttag(c)))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag (tempuser)"); return -1; } if (!(tempowner = account_get_ll_owner(a))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL ll_owner (tempowner)"); return -1; } if (!(tempname = conn_get_username(c))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL username (tempname)"); return -1; } if (!(tempip = addr_num_to_ip_str(conn_get_addr(c)))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr (tempip)"); return -1; } if (!(tempchannel = irc_convert_channel(conn_get_channel(c)))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL channel (tempchannel)"); return -1; } if ((strlen(tempchannel)+1+strlen(tempuser)+1+strlen(tempip)+1+strlen(server_get_hostname())+1+strlen(tempname)+1+1+strlen(tempflags)+4+strlen(tempowner)+1)>MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_info,__FUNCTION__,"WHO reply too long - skip"); return -1; } else sprintf(temp,"%s %s %s %s %s %c%s :0 %s",tempchannel,tempuser,tempip,server_get_hostname(),tempname,'H',tempflags,tempowner); irc_send(dest,RPL_WHOREPLY,temp); return 0; }
/* FIXME: we should save client ipaddr into c->ipaddr after accept */ static int dbs_verify_ipaddr(char const * addrlist, t_d2dbs_connection * c) { char * adlist; char * s, *temp; t_elem * elem; t_d2dbs_connection * tempc; unsigned int valid; unsigned int resolveipaddr; adlist = xstrdup(addrlist); temp = adlist; valid = 0; while ((s = strsep(&temp, ","))) { host_lookup(s, &resolveipaddr); if (resolveipaddr == 0) continue; if (c->ipaddr == resolveipaddr) { valid = 1; break; } } xfree(adlist); if (valid) { eventlog(eventlog_level_info, __FUNCTION__, "ip address %s is valid", addr_num_to_ip_str(c->ipaddr)); LIST_TRAVERSE(dbs_server_connection_list, elem) { if (!(tempc = (t_d2dbs_connection*)elem_get_data(elem))) continue; if (tempc != c && tempc->ipaddr == c->ipaddr) { eventlog(eventlog_level_info, __FUNCTION__, "destroying previous connection %d", tempc->serverid); dbs_server_shutdown_connection(tempc); list_remove_elem(dbs_server_connection_list, &elem); } } c->verified = 1; return 0; } else {
static int on_d2gs_initconn(t_connection * c) { t_d2gs * gs; eventlog(eventlog_level_info, __FUNCTION__, "[%d] client initiated d2gs connection",conn_get_socket(c)); if (!(gs=d2gslist_find_gs_by_ip(conn_get_addr(c)))) { /* reload list and see if any dns addy's has changed */ if (d2gslist_reload(prefs_get_d2gs_list())<0) { eventlog(eventlog_level_error, __FUNCTION__, "error reloading game server list,exitting"); return -1; } /* recheck */ if (!(gs=d2gslist_find_gs_by_ip(conn_get_addr(c)))) { eventlog(eventlog_level_error, __FUNCTION__, "d2gs connection from invalid ip address %s",addr_num_to_ip_str(conn_get_addr(c))); return -1; } } conn_set_class(c,conn_class_d2gs); conn_set_state(c,conn_state_connected); conn_set_d2gs_id(c,d2gs_get_id(gs)); if (handle_d2gs_init(c)<0) { eventlog(eventlog_level_error, __FUNCTION__, "failed to init d2gs connection"); return -1; } return 0; }
static int _handle_whereto_command(t_connection * conn, int numparams, char ** params, char * text) { char temp[MAX_IRC_MESSAGE_LEN]; /* Casted to avoid warnings */ const char * wolip; const char * wolname = prefs_get_servername(); const char * woltimezone = prefs_get_wol_timezone(); const char * wollong = prefs_get_wol_longitude(); const char * wollat = prefs_get_wol_latitude(); { /* trans support */ unsigned short port = conn_get_real_local_port(conn); unsigned int addr = conn_get_real_local_addr(conn); trans_net(conn_get_addr(conn), &addr, &port); wolip = addr_num_to_ip_str(addr); } //irc_send(conn,RPL_UPDATE_EXIST,":You must update before connecting!"); // Check if it's an allowed client type if (!tag_check_in_list(conn_get_clienttag(conn), prefs_get_allowed_clients())) { // This is for anyone game but not for Emperor if (conn_get_clienttag(conn) != CLIENTTAG_EMPERORBD_UINT) { // a.xwis.net 4009 RA2 // c.xwis.net 4000 TSUN // c.xwis.net 4010 RNGD // a.xwis.net 4010 YURI // snprintf(temp, sizeof(temp), ":a.xwis.net 4009 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); // snprintf(temp, sizeof(temp), ":c.xwis.net 4000 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); // snprintf(temp, sizeof(temp), ":c.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); // snprintf(temp, sizeof(temp), ":a.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); std::snprintf(temp, sizeof(temp), ":%s %d '0:%s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat); irc_send(conn, RPL_WOLSERV, temp); } // Only for Emperor: Battle for Dune if (conn_get_clienttag(conn) == CLIENTTAG_EMPERORBD_UINT) { std::snprintf(temp, sizeof(temp), ":%s %d '0:Emperor %s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat); irc_send(conn, RPL_WOLSERV, temp); } // Only for CnC Renegade if ((conn_get_clienttag(conn) == CLIENTTAG_RENEGADE_UINT) || (conn_get_clienttag(conn) == CLIENTTAG_RENGDFDS_UINT)) { snprintf(temp, sizeof(temp), ":%s 0 'Ping server' %s %s %s", wolip, woltimezone, wollong, wollat); irc_send(conn, RPL_PINGSERVER, temp); //I dont know for what is this server...? (used in renegade and yuri) //snprintf(temp, sizeof(temp), ":%s 4321 'Port Mangler' %s %s %s", wolip, woltimezone, wollong, wollat); //irc_send(conn,RPL_MANGLERSERV,temp); // on official server list is for Renegade also this server: //:noxchat1.wol.abn-sjc.ea.com 613 UserName :ea4.str.ea.com 0 '0,1,2,3,4,5,6,7,8,9,10:EA Ticket Server' -8 36.1083 -115.0582 } // There are servers for anyone game // FIXME: Check if is WOLv1 supported std::snprintf(temp, sizeof(temp), ":%s %d 'Live chat server' %s %s %s", wolip, BNETD_WOLV1_PORT, woltimezone, wollong, wollat); irc_send(conn, RPL_WOLSERV, temp); } // If game is not allowed than we still send this servers std::snprintf(temp, sizeof(temp), ":%s %d 'Gameres server' %s %s %s", wolip, BNETD_WGAMERES_PORT, woltimezone, wollong, wollat); irc_send(conn, RPL_GAMERESSERV, temp); std::snprintf(temp, sizeof(temp), ":%s %d 'Ladder server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat); irc_send(conn, RPL_LADDERSERV, temp); // There is Word Domination Tour server for Firestorm (maybe for future coding) //snprintf(temp, sizeof(temp), ":%s %d 'WDT server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat); //I dont know for what is this server...? //irc_send(conn,RPL_WDTSERV,temp); return 0; }
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; }
if (valid) { eventlog(eventlog_level_info, __FUNCTION__, "ip address %s is valid", addr_num_to_ip_str(c->ipaddr)); LIST_TRAVERSE(dbs_server_connection_list, elem) { if (!(tempc = (t_d2dbs_connection*)elem_get_data(elem))) continue; if (tempc != c && tempc->ipaddr == c->ipaddr) { eventlog(eventlog_level_info, __FUNCTION__, "destroying previous connection %d", tempc->serverid); dbs_server_shutdown_connection(tempc); list_remove_elem(dbs_server_connection_list, &elem); } } c->verified = 1; return 0; } else { eventlog(eventlog_level_info, __FUNCTION__, "ip address %s is invalid", addr_num_to_ip_str(c->ipaddr)); } return -1; } int dbs_check_timeout(void) { t_elem *elem; t_d2dbs_connection *tempc; std::time_t now; int timeout; now = std::time(NULL); timeout = d2dbs_prefs_get_idletime(); LIST_TRAVERSE(dbs_server_connection_list, elem) {
extern char * message_format_line(t_connection const * c, char const * in) { char * out; unsigned int inpos; unsigned int outpos; unsigned int outlen=MAX_INC; if (!(out = malloc(outlen+1))) return NULL; out[0] = 'I'; for (inpos=0,outpos=1; inpos<strlen(in); inpos++) { if (in[inpos]!='%') { out[outpos] = in[inpos]; outpos += 1; } else switch (in[++inpos]) { case '%': out[outpos++] = '%'; break; case 'a': sprintf(&out[outpos],"%u",accountlist_get_length()); outpos += strlen(&out[outpos]); break; case 'c': sprintf(&out[outpos],"%d",channellist_get_length()); outpos += strlen(&out[outpos]); break; case 'g': sprintf(&out[outpos],"%d",gamelist_get_length()); outpos += strlen(&out[outpos]); break; case 'h': if (gethostname(&out[outpos],MAX_INC)<0) { eventlog(eventlog_level_error,"message_format_line","could not get hostname (gethostname: %s)",strerror(errno)); strcpy(&out[outpos],"localhost"); /* not much else you can do */ } outpos += strlen(&out[outpos]); break; #ifndef ACCT_DYN_LOAD case 'i': sprintf(&out[outpos],UID_FORMAT,conn_get_userid(c)); outpos += strlen(&out[outpos]); break; #endif case 'l': { char const * tname; strncpy(&out[outpos],(tname = conn_get_chatname(c)),MAX_USER_NAME-1); conn_unget_chatname(c,tname); } out[outpos+MAX_USER_NAME-1] = '\0'; outpos += strlen(&out[outpos]); break; case 'r': strncpy(&out[outpos],addr_num_to_ip_str(conn_get_addr(c)),MAX_INC-1); out[outpos+MAX_INC-1] = '\0'; outpos += strlen(&out[outpos]); break; case 't': sprintf(&out[outpos],"%s",conn_get_clienttag(c)); outpos += strlen(&out[outpos]); break; case 'u': sprintf(&out[outpos],"%d",connlist_login_get_length()); outpos += strlen(&out[outpos]); break; case 'v': strcpy(&out[outpos],BNETD_VERSION); outpos += strlen(&out[outpos]); break; case 'C': /* simulated command */ out[0] = 'C'; break; case 'B': /* BROADCAST */ out[0] = 'B'; break; case 'E': /* ERROR */ out[0] = 'E'; break; case 'I': /* INFO */ out[0] = 'I'; break; case 'M': /* MESSAGE */ out[0] = 'M'; break; case 'T': /* EMOTE */ out[0] = 'T'; break; case 'W': /* INFO */ out[0] = 'W'; break; default: eventlog(eventlog_level_warn,"message_format_line","bad formatter \"%%%c\"",in[inpos-1]); } if ((outpos+MAX_INC)>=outlen) { char * newout; outlen += MAX_INC; if (!(newout = realloc(out,outlen))) { free(out); return NULL; } out = newout; } } out[outpos] = '\0'; return out; }
extern int handle_init_packet(t_connection * c, t_packet const * const packet) { 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; } switch (packet_get_type(packet)) { case MIRROR_GREET: if (packet_get_class(packet)!=packet_mirror_greet) { eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet)); return -1; } conn_set_addr(c, packet->u.mirror_greet.remote_addr); conn_set_port(c, packet->u.mirror_greet.remote_port); eventlog(eventlog_level_info,__FUNCTION__,"[%d] mirror greet detected for %s", conn_get_socket(c), addr_num_to_addr_str(conn_get_addr(c),conn_get_port(c))); conn_set_mirror(c, 2); if (ipbanlist_check(addr_num_to_ip_str(conn_get_addr(c)))!=0) { return -1; } if ((prefs_get_max_conns_per_IP()!=0) && (connlist_count_connections(conn_get_addr(c)) > prefs_get_max_conns_per_IP())) { return -1; } break; case CLIENT_INITCONN: if (packet_get_class(packet)!=packet_class_init) { eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet)); return -1; } switch (bn_byte_get(packet->u.client_initconn.class)) { case CLIENT_INITCONN_CLASS_BNET: eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated bnet connection",conn_get_socket(c)); conn_set_state(c,conn_state_connected); conn_set_class(c,conn_class_bnet); break; case CLIENT_INITCONN_CLASS_FILE: eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated file download connection",conn_get_socket(c)); conn_set_state(c,conn_state_connected); conn_set_class(c,conn_class_file); break; case CLIENT_INITCONN_CLASS_BOT: eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated chat bot connection",conn_get_socket(c)); conn_set_state(c,conn_state_connected); conn_set_class(c,conn_class_bot); break; case CLIENT_INITCONN_CLASS_TELNET: eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated telnet connection",conn_get_socket(c)); conn_set_state(c,conn_state_connected); conn_set_class(c,conn_class_telnet); break; case CLIENT_INITCONN_CLASS_D2CS_BNETD: { eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated d2cs_bnetd connection",conn_get_socket(c)); if (!(realmlist_find_realm_by_ip(conn_get_addr(c)))) { eventlog(eventlog_level_info,__FUNCTION__, "[%d] d2cs connection from unknown ip address %s",conn_get_socket(c),addr_num_to_addr_str(conn_get_addr(c),conn_get_port(c))); return -1; } conn_set_state(c,conn_state_connected); conn_set_class(c,conn_class_d2cs_bnetd); if (handle_d2cs_init(c)<0) { eventlog(eventlog_level_info,__FUNCTION__,"faild to init d2cs connection"); return -1; } } break; case CLIENT_INITCONN_CLASS_ENC: eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated encrypted connection (not supported)",conn_get_socket(c)); return -1; default: eventlog(eventlog_level_error,__FUNCTION__,"[%d] client requested unknown class 0x%02x (length %d) (closing connection)",conn_get_socket(c),(unsigned int)bn_byte_get(packet->u.client_initconn.class),packet_get_size(packet)); return -1; } break; default: eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown init packet type 0x%04x, len %u",conn_get_socket(c),packet_get_type(packet),packet_get_size(packet)); return -1; } return 0; }
extern int irc_message_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags) { char * msg; char const * ctag; t_irc_message_from from; if (!packet) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet"); return -1; } msg = NULL; if (me) ctag = clienttag_uint_to_str(conn_get_clienttag(me)); else ctag = clienttag_uint_to_str(CLIENTTAG_IIRC_UINT); switch (type) { /* case message_type_adduser: this is sent manually in handle_irc */ case message_type_adduser: /* when we do it somewhere else, then we can also make sure to not get our logs spammed */ break; case message_type_join: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); if((conn_get_wol(me) == 1)) { char temp[MAX_IRC_MESSAGE_LEN]; memset(temp,0,sizeof(temp)); /** * For WOL the channel JOIN output must be like the following: * user!WWOL@hostname JOIN :clanID,longIP channelName */ sprintf(temp,":0,%u",conn_get_addr(me)); msg = irc_message_preformat(&from,"JOIN",temp,irc_convert_channel(conn_get_channel(me))); } else msg = irc_message_preformat(&from,"JOIN","\r",irc_convert_channel(conn_get_channel(me))); conn_unget_chatname(me,from.nick); break; case message_type_part: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); msg = irc_message_preformat(&from,"PART","\r",irc_convert_channel(conn_get_channel(me))); conn_unget_chatname(me,from.nick); break; case message_type_talk: case message_type_whisper: { char const * dest; char temp[MAX_IRC_MESSAGE_LEN]; if (me) { from.nick = conn_get_chatname(me); from.host = addr_num_to_ip_str(conn_get_addr(me)); } else { from.nick = server_get_hostname(); from.host = server_get_hostname(); } from.user = ctag; if (type==message_type_talk) dest = irc_convert_channel(conn_get_channel(me)); /* FIXME: support more channels and choose right one! */ else dest = ""; /* will be replaced with username in postformat */ sprintf(temp,":%s",text); msg = irc_message_preformat(&from,"PRIVMSG",dest,temp); if (me) conn_unget_chatname(me,from.nick); } break; case message_type_emote: { char const * dest; char temp[MAX_IRC_MESSAGE_LEN]; /* "\001ACTION " + text + "\001" + \0 */ if ((8+strlen(text)+1+1)<=MAX_IRC_MESSAGE_LEN) { sprintf(temp,":\001ACTION %s\001",text); } else { sprintf(temp,":\001ACTION (maximum message length exceeded)\001"); } from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); /* FIXME: also supports whisper emotes? */ dest = irc_convert_channel(conn_get_channel(me)); /* FIXME: support more channels and choose right one! */ msg = irc_message_preformat(&from,"PRIVMSG",dest,temp); conn_unget_chatname(me,from.nick); } break; case message_type_broadcast: case message_type_info: case message_type_error: { char temp[MAX_IRC_MESSAGE_LEN]; sprintf(temp,":%s",text); msg = irc_message_preformat(NULL,"NOTICE",NULL,temp); } break; case message_type_channel: /* ignore it */ break; case message_type_mode: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); msg = irc_message_preformat(&from,"MODE","\r",text); conn_unget_chatname(me,from.nick); break; /** * Westwood Online Extensions */ case message_wol_joingame: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); msg = irc_message_preformat(&from,"JOINGAME",text,"\r"); conn_unget_chatname(me,from.nick); break; case message_wol_gameopt_owner: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); msg = irc_message_preformat(&from,"GAMEOPT",irc_convert_channel(conn_get_channel(me)),text); conn_unget_chatname(me,from.nick); break; case message_wol_gameopt_join: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); msg = irc_message_preformat(&from,"GAMEOPT",channel_wol_get_game_owner(conn_get_channel(me)),text); conn_unget_chatname(me,from.nick); break; case message_wol_start_game: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); msg = irc_message_preformat(&from,"STARTG","u",text); conn_unget_chatname(me,from.nick); break; case message_wol_page: from.nick = conn_get_chatname(me); from.user = ctag; from.host = addr_num_to_ip_str(conn_get_addr(me)); msg = irc_message_preformat(&from,"PAGE","u",text); conn_unget_chatname(me,from.nick); break; default: eventlog(eventlog_level_warn,__FUNCTION__,"%d not yet implemented",type); return -1; } if (msg) { packet_append_string(packet,msg); xfree(msg); return 0; } return -1; }
extern int irc_authenticate(t_connection * conn, char const * passhash) { t_hash h1; t_hash h2; t_account * a; char const * temphash; char const * username; char const * tempapgar; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return 0; } if (!passhash) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL passhash"); return 0; } username = conn_get_loggeduser(conn); if (!username) { /* redundant sanity check */ eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn->protocol.loggeduser"); return 0; } a = accountlist_find_account(username); if (!a) { irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* user does not exist */ return 0; } if (connlist_find_connection_by_account(a) && prefs_get_kick_old_login()==0) { irc_send_cmd(conn,"NOTICE",":Authentication rejected (already logged in) "); } else if (account_get_auth_lock(a)==1) { irc_send_cmd(conn,"NOTICE",":Authentication rejected (account is locked) "); } else { if((conn_get_wol(conn) == 1)) { temphash = account_get_wol_apgar(a); tempapgar = conn_wol_get_apgar(conn); if(temphash == NULL) { account_set_wol_apgar(a,tempapgar); temphash = account_get_wol_apgar(a); } if(tempapgar == NULL) { irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* bad APGAR */ conn_increment_passfail_count(conn); return 0; } if(strcmp(temphash,tempapgar) == 0) { bnetd_log(username, addr_num_to_ip_str(conn_get_addr(conn)), "IRC", "LOGIN", NULL, 1, 0); conn_login(conn,a,username); conn_set_state(conn,conn_state_loggedin); conn_set_clienttag(conn,CLIENTTAG_WWOL_UINT); /* WWOL hope here is ok */ return 1; } else { conn_increment_passfail_count(conn); return 0; } } hash_set_str(&h1,passhash); temphash = account_get_pass(a); hash_set_str(&h2,temphash); if (hash_eq(h1,h2)) { bnetd_log(username, addr_num_to_ip_str(conn_get_addr(conn)), "IRC", "LOGIN", NULL, 1, 0); conn_login(conn,a,username); conn_set_state(conn,conn_state_loggedin); conn_set_clienttag(conn,CLIENTTAG_IIRC_UINT); /* IIRC hope here is ok */ irc_send_cmd(conn,"NOTICE",":Authentication successful. You are now logged in."); return 1; } else { irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* wrong password */ conn_increment_passfail_count(conn); } } return 0; }