handle_auth.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:27k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2000  Ross Combs (rocombs@cs.nmsu.edu)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #include "common/setup_before.h"
  19. #ifdef HAVE_STRING_H
  20. # include <string.h>
  21. #else
  22. # ifdef HAVE_STRINGS_H
  23. #  include <strings.h>
  24. # endif
  25. #endif
  26. #include "compat/strcasecmp.h"
  27. #include "common/packet.h"
  28. #include "common/eventlog.h"
  29. #include "account.h"
  30. #include "connection.h"
  31. #include "common/queue.h"
  32. #include "common/bnethash.h"
  33. #include "common/bnethashconv.h"
  34. #include "common/bn_type.h"
  35. #include "common/field_sizes.h"
  36. #include "common/auth_protocol.h"
  37. #include "character.h"
  38. #include "common/util.h"
  39. #include "handle_auth.h"
  40. #include "common/setup_after.h"
  41. static int add_charlistreq_packet (t_packet * rpacket, t_account * account, char const * clienttag, char const * realmname, char const * name);
  42. extern int handle_auth_packet(t_connection * c, t_packet const * const packet)
  43. {
  44.     t_packet * rpacket;
  45.     
  46.     if (!c)
  47.     {
  48. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got NULL connection",conn_get_socket(c));
  49. return -1;
  50.     }
  51.     if (!packet)
  52.     {
  53. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got NULL packet",conn_get_socket(c));
  54. return -1;
  55.     }
  56.     if (packet_get_class(packet)!=packet_class_auth)
  57.     {
  58. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
  59. return -1;
  60.     }
  61.     
  62.     switch (conn_get_state(c))
  63.     {
  64.     case conn_state_connected:
  65. switch (packet_get_type(packet))
  66. {
  67. case CLIENT_AUTHLOGINREQ:
  68.     if (packet_get_size(packet)<sizeof(t_client_authloginreq))
  69.     {
  70. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad AUTHLOGINREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_authloginreq),packet_get_size(packet));
  71. break;
  72.     }
  73.     
  74.     {
  75. char const   * username;
  76. t_connection * normalcon;
  77. unsigned int   reply;
  78. if (!(username = packet_get_str_const(packet,sizeof(t_client_authloginreq),USER_NAME_MAX)))
  79. {
  80.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad AUTHLOGINREQ packet (missing or too long username)",conn_get_socket(c));
  81.     break;
  82. }
  83. eventlog(eventlog_level_debug,"handle_auth_packet","[%d] username = "%s"",conn_get_socket(c),username);
  84. if (!(normalcon = connlist_find_connection_by_sessionkey(bn_int_get(packet->u.client_authloginreq.sessionkey))))
  85. {
  86.     eventlog(eventlog_level_info,"handle_auth_packet","[%d] auth login for "%s" refused (bad session key %u)",conn_get_socket(c),username,bn_int_get(packet->u.client_authloginreq.sessionkey));
  87.     reply = SERVER_AUTHLOGINREPLY_REPLY_BANNED;
  88. }
  89. else
  90. {
  91.     unsigned int salt;
  92.     struct
  93.     {
  94. bn_int   salt;
  95. bn_int   sessionkey;
  96. bn_int   sessionnum;
  97. bn_int   secret;
  98.     } temp;
  99.     t_hash       secret_hash;
  100.     t_hash       try_hash;
  101.     char const * tname;
  102.     
  103.     salt = bn_int_get(packet->u.client_authloginreq.unknown9);
  104.     bn_int_set(&temp.salt,salt);
  105.     bn_int_set(&temp.sessionkey,conn_get_sessionkey(normalcon));
  106.     bn_int_set(&temp.sessionnum,conn_get_sessionnum(normalcon));
  107.     bn_int_set(&temp.secret,conn_get_secret(normalcon));
  108.     bnet_hash(&secret_hash,sizeof(temp),&temp);
  109.     
  110.     bnhash_to_hash(packet->u.client_authloginreq.secret_hash,&try_hash);
  111.     
  112.     if (hash_eq(try_hash,secret_hash)!=1)
  113.     {
  114. eventlog(eventlog_level_info,"handle_auth_packet","[%d] auth login for "%s" refused (bad password)",conn_get_socket(c),username);
  115. conn_increment_passfail_count (c);
  116. reply = SERVER_AUTHLOGINREPLY_REPLY_BANNED;
  117.     }
  118.     else
  119.     {
  120. if (strcasecmp(username,(tname = conn_get_username(normalcon)))!=0)
  121. {
  122.     eventlog(eventlog_level_info,"handle_auth_packet","[%d] auth login for "%s" refused (username does not match "%s")",conn_get_socket(c),username,tname);
  123.     conn_unget_username(normalcon,tname);
  124.     reply = SERVER_AUTHLOGINREPLY_REPLY_BANNED;
  125. }
  126. else
  127. {
  128.     conn_unget_username(normalcon,tname);
  129.     eventlog(eventlog_level_info,"handle_auth_packet","[%d] auth login for "%s" accepted (correct password)",conn_get_socket(c),username);
  130.     reply = SERVER_AUTHLOGINREPLY_REPLY_SUCCESS;
  131.     conn_bind(c,normalcon);
  132.     conn_set_state(c,conn_state_loggedin); /* FIXME: what about the other connection? */
  133. }
  134.     }
  135. }
  136. if ((rpacket = packet_create(packet_class_auth)))
  137. {
  138.     packet_set_size(rpacket,sizeof(t_server_authloginreply));
  139.     packet_set_type(rpacket,SERVER_AUTHLOGINREPLY);
  140.     bn_int_set(&rpacket->u.server_authloginreply.reply,reply);
  141.     conn_push_outqueue(c,rpacket);
  142.     packet_del_ref(rpacket);
  143. }
  144.     }
  145.     break;
  146.     
  147. default:
  148.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] unknown (unlogged in) auth packet type 0x%02hx, len %u",conn_get_socket(c),packet_get_type(packet),packet_get_size(packet));
  149. }
  150. break;
  151.     case conn_state_loggedin:
  152. switch (packet_get_type(packet))
  153. {
  154. case CLIENT_CREATECHARREQ:
  155.     if (packet_get_size(packet)<sizeof(t_client_createcharreq))
  156.     {
  157. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CREATECHARREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_createcharreq),packet_get_size(packet));
  158. break;
  159.     }
  160.     
  161.     {
  162. char const *          charname;
  163. unsigned int          reply;
  164. t_character_class     charclass;
  165. t_character_expansion charexpansion;
  166. if (!(charname = packet_get_str_const(packet,sizeof(t_client_createcharreq),UNCHECKED_NAME_STR)))
  167. {
  168.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CREATECHARREQ packet (missing or too long charname)",conn_get_socket(c));
  169.     break;
  170. }
  171. eventlog(eventlog_level_debug,"handle_auth_packet","[%d] CREATECHARREQ %u %04x %04x",
  172.  conn_get_socket(c),
  173.  bn_short_get(packet->u.client_createcharreq.class),
  174.  bn_short_get(packet->u.client_createcharreq.unknown1),
  175.  bn_short_get(packet->u.client_createcharreq.expansion));
  176. switch (bn_short_get(packet->u.client_createcharreq.class))
  177. {
  178. case CLIENT_CREATECHARREQ_CLASS_AMAZON:
  179.     charclass = character_class_amazon;
  180.     break;
  181. case CLIENT_CREATECHARREQ_CLASS_SORCERESS:
  182.     charclass = character_class_sorceress;
  183.     break;
  184. case CLIENT_CREATECHARREQ_CLASS_NECROMANCER:
  185.     charclass = character_class_necromancer;
  186.     break;
  187. case CLIENT_CREATECHARREQ_CLASS_PALADIN:
  188.     charclass = character_class_paladin;
  189.     break;
  190. case CLIENT_CREATECHARREQ_CLASS_BARBARIAN:
  191.     charclass = character_class_barbarian;
  192.     break;
  193. case CLIENT_CREATECHARREQ_CLASS_DRUID:
  194.     charclass = character_class_druid;
  195.     break;
  196. case CLIENT_CREATECHARREQ_CLASS_ASSASSIN:
  197.     charclass = character_class_assassin;
  198.     break;
  199. default:
  200.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] got unknown character class %u",conn_get_socket(c),bn_short_get(packet->u.client_createcharreq.class));
  201.     charclass = character_class_none;
  202. }
  203. switch (bn_short_get(packet->u.client_createcharreq.expansion))
  204. {
  205. case CLIENT_CREATECHARREQ_EXPANSION_CLASSIC:
  206.     charexpansion = character_expansion_classic;
  207.     break;
  208. case CLIENT_CREATECHARREQ_EXPANSION_LOD:
  209.     charexpansion = character_expansion_lod;
  210.     break;
  211. default:
  212.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] got unknown character expansion %04x",conn_get_socket(c),bn_short_get(packet->u.client_createcharreq.expansion));
  213.     charexpansion = character_expansion_none;
  214. }
  215. if (character_create(conn_get_account(c),
  216.      conn_get_clienttag(c),
  217.      conn_get_realmname(c),
  218.      charname,
  219.      charclass,
  220.      charexpansion)<0)
  221. {
  222.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] could not create character "%s"",conn_get_socket(c),charname);
  223.     reply = SERVER_CREATECHARREPLY_REPLY_REJECTED;
  224. }
  225. else
  226. {
  227.     conn_set_character(c,characterlist_find_character(conn_get_realmname(c),charname));
  228.     reply = SERVER_CREATECHARREPLY_REPLY_SUCCESS;
  229. }
  230. if ((rpacket = packet_create(packet_class_auth)))
  231. {
  232.     packet_set_size(rpacket,sizeof(t_server_createcharreply));
  233.     packet_set_type(rpacket,SERVER_CREATECHARREPLY);
  234.     bn_int_set(&rpacket->u.server_createcharreply.reply,reply);
  235.     conn_push_outqueue(c,rpacket);
  236.     packet_del_ref(rpacket);
  237. }
  238.     }
  239.     break;
  240.     
  241. case CLIENT_CREATEGAMEREQ:
  242.     if (packet_get_size(packet)<sizeof(t_client_creategamereq))
  243.     {
  244. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CREATEGAMEREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_creategamereq),packet_get_size(packet));
  245. break;
  246.     }
  247.     
  248.     /* FIXME: actually create game */
  249.     if ((rpacket = packet_create(packet_class_auth)))
  250.     {
  251. packet_set_size(rpacket,sizeof(t_server_creategamereply));
  252. packet_set_type(rpacket,SERVER_CREATEGAMEREPLY);
  253. bn_short_set(&rpacket->u.server_creategamereply.unknown1,bn_short_get(packet->u.client_creategamereq.unknown1));
  254. bn_short_set(&rpacket->u.server_creategamereply.unknown2,SERVER_CREATEGAMEREPLY_UNKNOWN2);
  255. bn_short_set(&rpacket->u.server_creategamereply.unknown3,SERVER_CREATEGAMEREPLY_UNKNOWN3);
  256. bn_int_set(&rpacket->u.server_creategamereply.reply,SERVER_CREATEGAMEREPLY_REPLY_OK);
  257. conn_push_outqueue(c,rpacket);
  258. packet_del_ref(rpacket);
  259.     }
  260.     break;
  261.     
  262. case CLIENT_JOINGAMEREQ2:
  263.     if (packet_get_size(packet)<sizeof(t_client_joingamereq2))
  264.     {
  265. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad JOINGAMEREQ2 packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_joingamereq2),packet_get_size(packet));
  266. break;
  267.     }
  268.     
  269.     if ((rpacket = packet_create(packet_class_auth)))
  270.     {
  271. packet_set_size(rpacket,sizeof(t_server_joingamereply2));
  272. packet_set_type(rpacket,SERVER_JOINGAMEREPLY2);
  273. bn_short_set(&rpacket->u.server_joingamereply2.unknown1,bn_short_get(packet->u.client_joingamereq2.unknown1));
  274. bn_int_set(&rpacket->u.server_joingamereply2.unknown2,SERVER_JOINGAMEREPLY2_UNKNOWN2);
  275. #ifdef SENDSERVER
  276. bn_int_nset(&rpacket->u.server_joingamereply2.addr,conn_get_real_local_addr(c)); /* FIXME: game server may be on another machine */
  277. #else
  278. bn_int_nset(&rpacket->u.server_joingamereply2.addr,conn_get_game_addr(c));
  279. #endif
  280. bn_int_set(&rpacket->u.server_joingamereply2.unknown4,SERVER_JOINGAMEREPLY2_UNKNOWN4);
  281. bn_int_set(&rpacket->u.server_joingamereply2.reply,SERVER_JOINGAMEREPLY2_REPLY_OK);
  282. conn_push_outqueue(c,rpacket);
  283. packet_del_ref(rpacket);
  284.     }
  285.     break;
  286.     
  287. case CLIENT_D2GAMELISTREQ:
  288.     if (packet_get_size(packet)<sizeof(t_client_d2gamelistreq))
  289.     {
  290. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad D2GAMELISTREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_d2gamelistreq),packet_get_size(packet));
  291. break;
  292.     }
  293.     
  294.     /* FIXME: actually get game list */
  295.     if ((rpacket = packet_create(packet_class_auth)))
  296.     {
  297. packet_set_size(rpacket,sizeof(t_server_d2gamelistreply));
  298. packet_set_type(rpacket,SERVER_D2GAMELISTREPLY);
  299. bn_short_set(&rpacket->u.server_d2gamelistreply.unknown1,bn_short_get(packet->u.client_d2gamelistreq.unknown1));
  300. bn_int_set(&rpacket->u.server_d2gamelistreply.unknown2,SERVER_D2GAMELISTREPLY_UNKNOWN2);
  301. bn_byte_set(&rpacket->u.server_d2gamelistreply.unknown3,SERVER_D2GAMELISTREPLY_UNKNOWN3);
  302. bn_int_set(&rpacket->u.server_d2gamelistreply.unknown4,SERVER_D2GAMELISTREPLY_UNKNOWN4);
  303. packet_append_string(rpacket,"Nope"); /* game name */
  304. packet_append_string(rpacket,""); /* game pass? */
  305. conn_push_outqueue(c,rpacket);
  306. packet_del_ref(rpacket);
  307.     }
  308.     if ((rpacket = packet_create(packet_class_auth)))
  309.     {
  310. packet_set_size(rpacket,sizeof(t_server_d2gamelistreply));
  311. packet_set_type(rpacket,SERVER_D2GAMELISTREPLY);
  312. bn_short_set(&rpacket->u.server_d2gamelistreply.unknown1,bn_short_get(packet->u.client_d2gamelistreq.unknown1));
  313. bn_int_set(&rpacket->u.server_d2gamelistreply.unknown2,SERVER_D2GAMELISTREPLY_UNKNOWN2);
  314. bn_byte_set(&rpacket->u.server_d2gamelistreply.unknown3,SERVER_D2GAMELISTREPLY_UNKNOWN3);
  315. bn_int_set(&rpacket->u.server_d2gamelistreply.unknown4,SERVER_D2GAMELISTREPLY_UNKNOWN4_END);
  316. packet_append_string(rpacket,"");
  317. packet_append_string(rpacket,"");
  318. packet_append_string(rpacket,"");
  319. conn_push_outqueue(c,rpacket);
  320. packet_del_ref(rpacket);
  321.     }
  322.     break;
  323.     
  324. case CLIENT_GAMEINFOREQ:
  325.     if (packet_get_size(packet)<sizeof(t_client_gameinforeq))
  326.     {
  327. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad GAMEINFOREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_gameinforeq),packet_get_size(packet));
  328. break;
  329.     }
  330.     
  331.     /* FIXME: send real game info */
  332.     if ((rpacket = packet_create(packet_class_auth)))
  333.     {
  334. packet_set_size(rpacket,sizeof(t_server_gameinforeply));
  335. packet_set_type(rpacket,SERVER_GAMEINFOREPLY);
  336. bn_short_set(&rpacket->u.server_gameinforeply.unknown1,bn_short_get(packet->u.client_gameinforeq.unknown1));
  337. bn_int_set(&rpacket->u.server_gameinforeply.unknown2,SERVER_GAMEINFOREPLY_UNKNOWN2);
  338. bn_int_set(&rpacket->u.server_gameinforeply.unknown3,SERVER_GAMEINFOREPLY_UNKNOWN3);
  339. bn_byte_set(&rpacket->u.server_gameinforeply.gamelevel,0x01);
  340. bn_byte_set(&rpacket->u.server_gameinforeply.leveldiff,0xff);
  341. bn_byte_set(&rpacket->u.server_gameinforeply.maxchar,0x08);
  342. bn_byte_set(&rpacket->u.server_gameinforeply.currchar,0x01);
  343.                 memset(rpacket->u.server_gameinforeply.class,0xcc,16);
  344.                 memset(rpacket->u.server_gameinforeply.level,0xcc,16);
  345. bn_byte_set(&rpacket->u.server_gameinforeply.unknown4,SERVER_GAMEINFOREPLY_UNKNOWN4);
  346. packet_append_string(rpacket,"Player1");
  347. packet_append_string(rpacket,"Player2");
  348. conn_push_outqueue(c,rpacket);
  349. packet_del_ref(rpacket);
  350.     }
  351.     break;
  352.     
  353. case CLIENT_CHARLOGINREQ:
  354.     if (packet_get_size(packet)<sizeof(t_client_charloginreq))
  355.     {
  356. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CHARLOGINREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_charloginreq),packet_get_size(packet));
  357. break;
  358.     }
  359.     
  360.     {
  361. char const *  charname;
  362. t_character * ch;
  363. char const *  charlist;
  364. if (!(charname = packet_get_str_const(packet,sizeof(t_client_charloginreq),UNCHECKED_NAME_STR)))
  365. {
  366.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CHARLOGINREQ packet (missing or too long charname)",conn_get_socket(c));
  367.     break;
  368. }
  369.         
  370.         if ((rpacket = packet_create(packet_class_auth)))
  371.         {
  372.     packet_set_size(rpacket,sizeof(t_server_charloginreply));
  373.     packet_set_type(rpacket,SERVER_CHARLOGINREPLY);
  374.     if ((ch = characterlist_find_character(conn_get_realmname(c),charname)))
  375.     {
  376. if (!(charlist = account_get_closed_characterlist(conn_get_account(c),conn_get_clienttag(c),conn_get_realmname(c))))
  377. {
  378.     eventlog(eventlog_level_info,"handle_auth_packet","[%d] character login for "%s" refused (account has no charlist)",conn_get_socket(c),charname);
  379.     bn_int_set(&rpacket->u.server_charloginreply.reply,0xffffffff); /* FIXME */
  380. }
  381. else
  382. {
  383.     if (character_verify_charlist(ch,charlist)<0)
  384.     {
  385. eventlog(eventlog_level_info,"handle_auth_packet","[%d] character login for "%s" refused (character not in account charlist)",conn_get_socket(c),charname);
  386. bn_int_set(&rpacket->u.server_charloginreply.reply,0xffffffff); /* FIXME */
  387.     }
  388.     else
  389.     {
  390. conn_set_character(c,ch);
  391. bn_int_set(&rpacket->u.server_charloginreply.reply,SERVER_CHARLOGINREPLY_REPLY_SUCCESS);
  392.     }
  393.     account_unget_closed_characterlist(conn_get_account(c),charlist);
  394. }
  395.     }
  396.     else
  397.     {
  398. eventlog(eventlog_level_info,"handle_auth_packet","[%d] character login for "%s" refused (no such character in realm "%s")",conn_get_socket(c),charname,conn_get_realmname(c));
  399. bn_int_set(&rpacket->u.server_charloginreply.reply,0xffffffff); /* FIXME */
  400.     }
  401.     conn_push_outqueue(c,rpacket);
  402.     packet_del_ref(rpacket);
  403.         }
  404.     }
  405.     break;
  406.     
  407. case CLIENT_DELETECHARREQ:
  408.     if (packet_get_size(packet)<sizeof(t_client_deletecharreq))
  409.     {
  410. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad DELETECHARREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_deletecharreq),packet_get_size(packet));
  411. break;
  412.     }
  413.     
  414.     if ((rpacket = packet_create(packet_class_auth)))
  415.     {
  416. packet_set_size(rpacket,sizeof(t_server_deletecharreply));
  417. packet_set_type(rpacket,SERVER_DELETECHARREPLY);
  418. bn_short_set(&rpacket->u.server_deletecharreply.unknown1,bn_short_get(packet->u.client_deletecharreq.unknown1));
  419. bn_int_set(&rpacket->u.server_deletecharreply.reply,SERVER_DELETECHARREPLY_REPLY_SUCCESS);
  420. conn_push_outqueue(c,rpacket);
  421. packet_del_ref(rpacket);
  422.     }
  423.     break;
  424.     
  425. case CLIENT_LADDERREQ2:
  426.     if (packet_get_size(packet)<sizeof(t_client_ladderreq2))
  427.     {
  428. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad LADDERREQ2 packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_ladderreq2),packet_get_size(packet));
  429. break;
  430.     }
  431.     
  432.     if ((rpacket = packet_create(packet_class_auth)))
  433.     {
  434. packet_set_size(rpacket,sizeof(t_server_ladderreply2));
  435. packet_set_type(rpacket,SERVER_LADDERREPLY2);
  436. bn_byte_set(&rpacket->u.server_ladderreply2.unknown1,bn_byte_get(packet->u.client_ladderreq2.class));
  437. bn_short_set(&rpacket->u.server_ladderreply2.unknown2,SERVER_LADDERREPLY2_UNKNOWN2);
  438. bn_short_set(&rpacket->u.server_ladderreply2.unknown3,SERVER_LADDERREPLY2_UNKNOWN3);
  439. bn_short_set(&rpacket->u.server_ladderreply2.unknown4,SERVER_LADDERREPLY2_UNKNOWN4);
  440. bn_int_set(&rpacket->u.server_ladderreply2.unknown5,SERVER_LADDERREPLY2_UNKNOWN5);
  441. bn_int_set(&rpacket->u.server_ladderreply2.unknown6,SERVER_LADDERREPLY2_UNKNOWN6);
  442. conn_push_outqueue(c,rpacket);
  443. packet_del_ref(rpacket);
  444.     }
  445.     break;
  446.     
  447. case CLIENT_AUTHMOTDREQ:
  448.     if (packet_get_size(packet)<sizeof(t_client_authmotdreq))
  449.     {
  450. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad AUTHMOTDREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_authmotdreq),packet_get_size(packet));
  451. break;
  452.     }
  453.     
  454.     if ((rpacket = packet_create(packet_class_auth)))
  455.     {
  456. packet_set_size(rpacket,sizeof(t_server_authmotdreply));
  457. packet_set_type(rpacket,SERVER_AUTHMOTDREPLY);
  458. bn_byte_set(&rpacket->u.server_authmotdreply.unknown1,SERVER_AUTHMOTDREPLY_UNKNOWN1);
  459. packet_append_string(rpacket,"Hello.");
  460. conn_push_outqueue(c,rpacket);
  461. packet_del_ref(rpacket);
  462.     }
  463.     break;
  464.     
  465. case CLIENT_CHARLISTREQ:
  466.     if (packet_get_size(packet)<sizeof(t_client_charlistreq))
  467.     {
  468. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CHARLISTREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_charlistreq),packet_get_size(packet));
  469. break;
  470.     }
  471.             eventlog(eventlog_level_debug,"handle_auth_packet","CHARLISTREQ.unknown1 = 0x%04x", bn_short_get(packet->u.client_charlistreq.unknown1));
  472.             eventlog(eventlog_level_debug,"handle_auth_packet","CHARLISTREQ.unknown2 = 0x%04x", bn_short_get(packet->u.client_charlistreq.unknown2));
  473.     if ((rpacket = packet_create(packet_class_auth)))
  474.     {
  475.            /* FIXME: Set *real* Number of characters here */
  476.         int number_of_characters = 0;
  477. packet_set_size(rpacket,sizeof(t_server_charlistreply));
  478. packet_set_type(rpacket,SERVER_CHARLISTREPLY);
  479. bn_short_set(&rpacket->u.server_charlistreply.unknown1, bn_short_get(packet->u.client_charlistreq.unknown1));
  480. bn_short_set(&rpacket->u.server_charlistreply.unknown2, 0);
  481. {
  482.     char const * realmname = conn_get_realmname(c);
  483.     char const * charlist = account_get_closed_characterlist (conn_get_account(c), conn_get_clienttag(c), realmname);
  484.     char         tempname[32];
  485.     if (charlist == NULL)
  486.     {
  487.         eventlog(eventlog_level_debug,"handle_auth_packet","no characters in Realm %s",realmname);
  488.     }
  489.     else
  490.     {
  491.         char const * start;
  492. char const * next_char;
  493. int    list_len;
  494. int    name_len;
  495. int    i;
  496. eventlog(eventlog_level_debug,"handle_auth_packet","got characterlist "%s" for Realm %s",charlist,realmname);
  497. list_len  = strlen(charlist);
  498. start     = charlist;
  499. next_char = start;
  500. for (i = 0; i < list_len; i++, next_char++)
  501. {
  502.     if (',' == *next_char)
  503.     {
  504.         name_len = next_char - start;
  505. strncpy(tempname, start, name_len);
  506. tempname[name_len] = '';
  507. number_of_characters += add_charlistreq_packet(rpacket, conn_get_account(c), conn_get_clienttag(c), realmname, tempname);
  508. start = next_char + 1;
  509.     }
  510. }
  511. name_len = next_char - start;
  512. strncpy(tempname, start, name_len);
  513. tempname[name_len] = '';
  514. number_of_characters += add_charlistreq_packet(rpacket, conn_get_account(c), conn_get_clienttag(c), realmname, tempname);
  515. start = next_char + 1;
  516.     }    
  517. }
  518. bn_short_set(&rpacket->u.server_charlistreply.nchars_1, number_of_characters);
  519. bn_short_set(&rpacket->u.server_charlistreply.nchars_2, number_of_characters);
  520. eventlog(eventlog_level_debug,"handle_auth_packet","CHARLISTREPLY.unknown1 = 0x%04x", bn_short_get(rpacket->u.server_charlistreply.unknown1));
  521. eventlog(eventlog_level_debug,"handle_auth_packet","CHARLISTREPLY.nchars_1 = 0x%04x", bn_short_get(rpacket->u.server_charlistreply.nchars_1));
  522. eventlog(eventlog_level_debug,"handle_auth_packet","CHARLISTREPLY.unknown2 = 0x%04x", bn_short_get(rpacket->u.server_charlistreply.unknown2));
  523. eventlog(eventlog_level_debug,"handle_auth_packet","CHARLISTREPLY.nchars_2 = 0x%04x", bn_short_get(rpacket->u.server_charlistreply.nchars_2));
  524. conn_push_outqueue(c,rpacket);
  525. packet_del_ref(rpacket);
  526.     }
  527.     break;
  528. case CLIENT_CONVERTCHARREQ:
  529.     if (packet_get_size(packet)<sizeof(t_client_convertcharreq))
  530.     {
  531. eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CONVERTCHARREQ packet (expected %u bytes, got %u)",conn_get_socket(c),sizeof(t_client_convertcharreq),packet_get_size(packet));
  532. break;
  533.     }
  534.     {
  535. char const * charname;
  536. if (!(charname = packet_get_str_const(packet,sizeof(t_client_convertcharreq),UNCHECKED_NAME_STR)))
  537. {
  538.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] got bad CONVERTCHARREQ packet (missing or too long charname)",conn_get_socket(c));
  539.     break;
  540. }
  541. eventlog(eventlog_level_debug,"handle_auth_packet","[%d] CONVERTCHARREQ %s, FIXME: Add code later",
  542.  conn_get_socket(c),
  543.                          charname);
  544. if ((rpacket = packet_create(packet_class_auth)))
  545. {
  546.     packet_set_size(rpacket,sizeof(t_server_convertcharreply));
  547.     packet_set_type(rpacket,SERVER_CONVERTCHARREPLY);
  548.                     bn_int_set(&rpacket->u.server_convertcharreply.unknown1, SERVER_CONVERTCHARREPLY_UNKNOWN1);
  549.     conn_push_outqueue(c,rpacket);
  550.     packet_del_ref(rpacket);
  551. }
  552.             }
  553.             break;
  554.             
  555. default:
  556.     eventlog(eventlog_level_error,"handle_auth_packet","[%d] unknown (logged in) auth packet type 0x%02hx, len %u",conn_get_socket(c),packet_get_type(packet),packet_get_size(packet));
  557. }
  558. break;
  559.     default:
  560. eventlog(eventlog_level_error,"handle_auth_packet","[%d] unknown auth connection state %d",conn_get_socket(c),(int)conn_get_state(c));
  561.     }
  562.     
  563.     return 0;
  564. }
  565. static int add_charlistreq_packet (t_packet * rpacket, t_account * account, char const * clienttag, char const * realmname, char const * name)
  566. {
  567.     char const * chardata_as_hex;
  568.     char         chardata_key[256]; /* FIXME: buffer overflow on realmnname or name */
  569.     eventlog(eventlog_level_debug, "add_charlistreq_packet", "about to add charlist data for "%s" in realm "%s"", name, realmname);
  570.     sprintf (chardata_key, "BNET\Characters\%s\%s\%s\0", clienttag, realmname, name);
  571.     chardata_as_hex = account_get_strattr(account, chardata_key);
  572.     eventlog(eventlog_level_debug, "add_charlistreq_packet", "key "%s"", chardata_key);
  573.     eventlog(eventlog_level_debug, "add_charlistreq_packet", "value "%s"", chardata_as_hex);
  574.     /* FIXME: This seems to be a request for character lists, try the following canned request
  575.      *        that I tcpdump(1)'ed from a real Battle Net connection
  576. # 569 packet from server: type=0x0017(SERVER_CHARLISTREPLY) length=199 class=auth
  577. 0000:   C7 00 17 08 00 04 00 00   00 04 00 68 61 6B 61 6E    ...........hakan
  578. 0010:   41 73 73 54 65 6D 70 00   84 80 FF FF FF FF FF FF    AssTemp.........
  579. 0020:   FF FF FF FF FF 07 FF FF   FF FF FF FF FF FF FF FF    ................
  580. 0030:   FF 01 A1 80 80 80 FF FF   FF 00 68 61 6B 61 6E 44    ..........hakanD
  581. 0040:   72 75 54 65 6D 70 00 84   80 FF FF FF FF FF FF FF    ruTemp..........
  582. 0050:   FF FF FF FF 06 FF FF FF   FF FF FF FF FF FF FF FF    ................
  583. 0060:   01 A1 80 80 80 FF FF FF   00 68 61 6B 61 6E 50 61    .........hakanPa
  584. 0070:   6C 4F 6C 5F 64 00 84 80   FF FF FF FF FF FF FF FF    lOl_d...........
  585. 0080:   FF FF FF 04 FF FF FF FF   FF FF FF FF FF FF FF 01    ................
  586. 0090:   81 80 80 80 FF FF FF 00   68 61 6B 61 6E 50 61 6C    ........hakanPal
  587. 00A0:   54 65 6D 70 00 84 80 FF   FF FF FF FF FF FF FF FF    Temp............
  588. 00B0:   FF FF 04 FF FF FF FF FF   FF FF FF FF FF FF 01 A1    ................
  589. 00C0:   80 80 80 FF FF FF 00                                 .......         
  590. # 20 packet from server: type=0x0017(SERVER_CHARLISTREPLY) length=164 class=auth
  591. 0000:   A4 00 17 08 00 00 00 00   00 00 00 61 73 61 00 84    ...........asa..
  592. 0010:   80 FF FF FF FF FF FF FF   FF FF FF FF 07 FF FF FF    ................
  593. 0020:   FF FF FF FF FF FF FF FF   01 A1 80 80 80 FF FF FF    ................
  594. 0030:   00 70 61 6C 00 84 80 FF   FF FF FF FF FF FF FF FF    .pal............
  595. 0040:   FF FF 04 FF FF FF FF FF   FF FF FF FF FF FF 01 A1    ................
  596. 0050:   80 80 80 FF FF FF 00 73   6F 72 63 00 84 80 FF FF    .......sorc.....
  597. 0060:   FF FF FF FF FF FF FF FF   FF 02 FF FF FF FF FF FF    ................
  598. 0070:   FF FF FF FF FF 01 A1 80   80 80 FF FF FF 00 61 6D    ..............am
  599. 0080:   61 00 84 80 FF FF FF FF   FF FF FF FF FF FF FF 01    a...............
  600. 0090:   FF FF FF FF FF FF FF FF   FF FF FF 01 A1 80 80 80    ................
  601. 00A0:   FF FF FF 00                                          ....            
  602.      */
  603.     if (chardata_as_hex != NULL)
  604.     {
  605.         int  append_length;
  606.         char chardata[64];
  607. int  length;
  608.         length = hex_to_str(chardata_as_hex, chardata, 33); /* FIXME: make sure chardata_as_hex is long enough (33*3 (+1?) ) */
  609. /* Append a '' as terminator to character data */
  610. chardata[length] = '';
  611. length++;
  612.         append_length = packet_append_string (rpacket, name);
  613. eventlog(eventlog_level_debug, "add_charlistreq_packet", "length %d for name "%s"", append_length, name);
  614. append_length = packet_append_string (rpacket, chardata);
  615. eventlog(eventlog_level_debug, "add_charlistreq_packet", "length %d [%d] for character data", append_length, length); /* length should be == strlen(chardata) */
  616. return 1;
  617.     }
  618.     return 0;
  619. }