Advertisement
Guest User

db.h

a guest
Nov 11th, 2023
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.30 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "constants.h"
  3. #include "config.h"
  4. #include "input.h"
  5. #include "desc_client.h"
  6. #include "desc_manager.h"
  7. #include "protocol.h"
  8. #include "matrix_card.h"
  9. #include "passpod.h"
  10. #include "locale_service.h"
  11. #include "auth_brazil.h"
  12. #include "db.h"
  13.  
  14. #ifndef __WIN32__
  15. #include "limit_time.h"
  16. #endif
  17.  
  18. #include "utils.h"
  19.  
  20. // #define ENABLE_ACCOUNT_W_SPECIALCHARS
  21. bool FN_IS_VALID_LOGIN_STRING(const char *str)
  22. {
  23. const char* tmp;
  24.  
  25. if (!str || !*str)
  26. return false;
  27.  
  28. if (strlen(str) < 2)
  29. return false;
  30.  
  31. for (tmp = str; *tmp; ++tmp)
  32. {
  33.  
  34. if (isdigit(*tmp) || isalpha(*tmp))
  35. continue;
  36.  
  37. #ifdef ENABLE_ACCOUNT_W_SPECIALCHARS
  38.  
  39. switch (*tmp)
  40. {
  41. case ' ':
  42. case '_':
  43. case '-':
  44. case '.':
  45. case '!':
  46. case '@':
  47. case '#':
  48. case '$':
  49. case '%':
  50. case '^':
  51. case '&':
  52. case '*':
  53. case '(':
  54. case ')':
  55. continue;
  56. }
  57. #endif
  58. return false;
  59. }
  60.  
  61. return true;
  62. }
  63.  
  64. bool Login_IsInChannelService(const char* c_login)
  65. {
  66. if (c_login[0] == '[')
  67. return true;
  68. return false;
  69. }
  70.  
  71. CInputAuth::CInputAuth()
  72. {
  73. }
  74.  
  75. void CInputAuth::Login(LPDESC d, const char * c_pData)
  76. {
  77. TPacketCGLogin3 * pinfo = (TPacketCGLogin3 *) c_pData;
  78.  
  79. if (!g_bAuthServer)
  80. {
  81. sys_err ("CInputAuth class is not for game server. IP %s might be a hacker.",
  82. inet_ntoa(d->GetAddr().sin_addr));
  83. d->DelayedDisconnect(5);
  84. return;
  85. }
  86.  
  87.  
  88. char login[LOGIN_MAX_LEN + 1];
  89. trim_and_lower(pinfo->login, login, sizeof(login));
  90.  
  91. char passwd[PASSWD_MAX_LEN + 1];
  92. strlcpy(passwd, pinfo->passwd, sizeof(passwd));
  93.  
  94. sys_log(0, "InputAuth::Login : %s(%d) desc %p",
  95. login, strlen(login), get_pointer(d));
  96.  
  97. // check login string
  98. if (false == FN_IS_VALID_LOGIN_STRING(login))
  99. {
  100. sys_log(0, "InputAuth::Login : IS_NOT_VALID_LOGIN_STRING(%s) desc %p",
  101. login, get_pointer(d));
  102. LoginFailure(d, "NOID");
  103. return;
  104. }
  105.  
  106. if (g_bNoMoreClient)
  107. {
  108. TPacketGCLoginFailure failurePacket;
  109.  
  110. failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  111. strlcpy(failurePacket.szStatus, "SHUTDOWN", sizeof(failurePacket.szStatus));
  112.  
  113. d->Packet(&failurePacket, sizeof(failurePacket));
  114. return;
  115. }
  116.  
  117. if (DESC_MANAGER::instance().FindByLoginName(login))
  118. {
  119. LoginFailure(d, "ALREADY");
  120. return;
  121. }
  122.  
  123. DWORD dwKey = DESC_MANAGER::instance().CreateLoginKey(d);
  124. DWORD dwPanamaKey = dwKey ^ pinfo->adwClientKey[0] ^ pinfo->adwClientKey[1] ^ pinfo->adwClientKey[2] ^ pinfo->adwClientKey[3];
  125. d->SetPanamaKey(dwPanamaKey);
  126.  
  127. sys_log(0, "InputAuth::Login : key %u:0x%x login %s", dwKey, dwPanamaKey, login);
  128.  
  129. // BRAZIL_AUTH
  130. #ifdef ENABLE_BRAZIL_AUTH_FEATURE // @warme006
  131. if (!test_server)
  132. {
  133. int result = auth_brazil(login, passwd);
  134.  
  135. switch (result)
  136. {
  137. case AUTH_BRAZIL_SERVER_ERR:
  138. case AUTH_BRAZIL_NOID:
  139. LoginFailure(d, "NOID");
  140. return;
  141. case AUTH_BRAZIL_WRONGPWD:
  142. LoginFailure(d, "WRONGPWD");
  143. return;
  144. case AUTH_BRAZIL_FLASHUSER:
  145. LoginFailure(d, "FLASH");
  146. return;
  147. }
  148. }
  149. #endif
  150.  
  151. TPacketCGLogin3 * p = M2_NEW TPacketCGLogin3;
  152. thecore_memcpy(p, pinfo, sizeof(TPacketCGLogin3));
  153.  
  154. char szPasswd[PASSWD_MAX_LEN * 2 + 1];
  155. DBManager::instance().EscapeString(szPasswd, sizeof(szPasswd), passwd, strlen(passwd));
  156.  
  157. char szLogin[LOGIN_MAX_LEN * 2 + 1];
  158. DBManager::instance().EscapeString(szLogin, sizeof(szLogin), login, strlen(login));
  159.  
  160. // CHANNEL_SERVICE_LOGIN
  161. if (Login_IsInChannelService(szLogin))
  162. {
  163. sys_log(0, "ChannelServiceLogin [%s]", szLogin);
  164.  
  165. DBManager::instance().ReturnQuery(QID_AUTH_LOGIN, dwKey, p,
  166. "SELECT '%s', password, securitycode, social_id, id, status,"
  167. #ifdef __MULTI_LANGUAGE_SYSTEM__
  168. "language,"
  169. #endif
  170. "availDt - NOW() > 0,"
  171. "UNIX_TIMESTAMP(silver_expire),"
  172. "UNIX_TIMESTAMP(gold_expire),"
  173. "UNIX_TIMESTAMP(safebox_expire),"
  174. "UNIX_TIMESTAMP(autoloot_expire),"
  175. "UNIX_TIMESTAMP(fish_mind_expire),"
  176. "UNIX_TIMESTAMP(marriage_fast_expire),"
  177. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  178. "UNIX_TIMESTAMP(create_time)"
  179. " FROM account WHERE login='%s'",
  180.  
  181. szPasswd, szLogin);
  182. }
  183. // END_OF_CHANNEL_SERVICE_LOGIN
  184. else
  185. {
  186. #ifdef __WIN32__
  187. DBManager::instance().ReturnQuery(QID_AUTH_LOGIN, dwKey, p,
  188. "SELECT PASSWORD('%s'), password, securitycode, social_id, id, status,"
  189. #ifdef __MULTI_LANGUAGE_SYSTEM__
  190. "language,"
  191. #endif
  192. "availDt - NOW() > 0,"
  193. "UNIX_TIMESTAMP(silver_expire),"
  194. "UNIX_TIMESTAMP(gold_expire),"
  195. "UNIX_TIMESTAMP(safebox_expire),"
  196. "UNIX_TIMESTAMP(autoloot_expire),"
  197. "UNIX_TIMESTAMP(fish_mind_expire),"
  198. "UNIX_TIMESTAMP(marriage_fast_expire),"
  199. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  200. "UNIX_TIMESTAMP(create_time)"
  201. " FROM account WHERE login='%s'",
  202. szPasswd, szLogin);
  203. #else
  204. // @fixme138 1. PASSWORD('%s') -> %s 2. szPasswd wrapped inside Argon2PasswordHash(%s).c_str()
  205. DBManager::instance().ReturnQuery(QID_AUTH_LOGIN, dwKey, p,
  206. "SELECT '%s', password, securitycode, social_id, id, status,"
  207. #ifdef __MULTI_LANGUAGE_SYSTEM__
  208. "language,"
  209. #endif
  210. "availDt - NOW() > 0,"
  211. "UNIX_TIMESTAMP(silver_expire),"
  212. "UNIX_TIMESTAMP(gold_expire),"
  213. "UNIX_TIMESTAMP(safebox_expire),"
  214. "UNIX_TIMESTAMP(autoloot_expire),"
  215. "UNIX_TIMESTAMP(fish_mind_expire),"
  216. "UNIX_TIMESTAMP(marriage_fast_expire),"
  217. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  218. "UNIX_TIMESTAMP(create_time)"
  219. " FROM account WHERE login='%s'",
  220. DBManager::Instance().Argon2PasswordHash(szPasswd).c_str(), szLogin);
  221. #endif
  222. }
  223. }
  224.  
  225. void CInputAuth::LoginOpenID(LPDESC d, const char * c_pData)
  226. {
  227. //OpenID test code.
  228. TPacketCGLogin5 *tempInfo1 = (TPacketCGLogin5 *)c_pData;
  229.  
  230.  
  231. char* authKey = tempInfo1->authKey;
  232. char returnID[LOGIN_MAX_LEN + 1] = {0};
  233.  
  234. int test_url_get_protocol = auth_OpenID(authKey, inet_ntoa(d->GetAddr().sin_addr), returnID);
  235.  
  236.  
  237. if (0!=test_url_get_protocol)
  238. {
  239. LoginFailure(d, "OpenID Fail");
  240. return;
  241. }
  242.  
  243. TPacketCGLogin3 tempInfo2;
  244. strncpy(tempInfo2.login, returnID, LOGIN_MAX_LEN);
  245. strncpy(tempInfo2.passwd, "0000", PASSWD_MAX_LEN);
  246. for(int i=0;i<4;i++)
  247. tempInfo2.adwClientKey[i] = tempInfo1->adwClientKey[i];
  248. TPacketCGLogin3 * pinfo = &tempInfo2;
  249.  
  250. if (!g_bAuthServer)
  251. {
  252. sys_err ("CInputAuth class is not for game server. IP %s might be a hacker.",
  253. inet_ntoa(d->GetAddr().sin_addr));
  254. d->DelayedDisconnect(5);
  255. return;
  256. }
  257.  
  258.  
  259. char login[LOGIN_MAX_LEN + 1];
  260. trim_and_lower(pinfo->login, login, sizeof(login));
  261.  
  262. char passwd[PASSWD_MAX_LEN + 1];
  263. strlcpy(passwd, pinfo->passwd, sizeof(passwd));
  264.  
  265. sys_log(0, "InputAuth::Login : %s(%d) desc %p",
  266. login, strlen(login), get_pointer(d));
  267.  
  268. // check login string
  269. if (false == FN_IS_VALID_LOGIN_STRING(login))
  270. {
  271. sys_log(0, "InputAuth::Login : IS_NOT_VALID_LOGIN_STRING(%s) desc %p",
  272. login, get_pointer(d));
  273. LoginFailure(d, "NOID");
  274. return;
  275. }
  276.  
  277. if (g_bNoMoreClient)
  278. {
  279. TPacketGCLoginFailure failurePacket;
  280.  
  281. failurePacket.header = HEADER_GC_LOGIN_FAILURE;
  282. strlcpy(failurePacket.szStatus, "SHUTDOWN", sizeof(failurePacket.szStatus));
  283.  
  284. d->Packet(&failurePacket, sizeof(failurePacket));
  285. return;
  286. }
  287.  
  288. if (DESC_MANAGER::instance().FindByLoginName(login))
  289. {
  290. LoginFailure(d, "ALREADY");
  291. return;
  292. }
  293.  
  294. DWORD dwKey = DESC_MANAGER::instance().CreateLoginKey(d);
  295. DWORD dwPanamaKey = dwKey ^ pinfo->adwClientKey[0] ^ pinfo->adwClientKey[1] ^ pinfo->adwClientKey[2] ^ pinfo->adwClientKey[3];
  296. d->SetPanamaKey(dwPanamaKey);
  297.  
  298. sys_log(0, "InputAuth::Login : key %u:0x%x login %s", dwKey, dwPanamaKey, login);
  299.  
  300. // BRAZIL_AUTH
  301. #ifdef ENABLE_BRAZIL_AUTH_FEATURE // @warme006
  302. if (!test_server)
  303. {
  304. int result = auth_brazil(login, passwd);
  305.  
  306. switch (result)
  307. {
  308. case AUTH_BRAZIL_SERVER_ERR:
  309. case AUTH_BRAZIL_NOID:
  310. LoginFailure(d, "NOID");
  311. return;
  312. case AUTH_BRAZIL_WRONGPWD:
  313. LoginFailure(d, "WRONGPWD");
  314. return;
  315. case AUTH_BRAZIL_FLASHUSER:
  316. LoginFailure(d, "FLASH");
  317. return;
  318. }
  319. }
  320. #endif
  321. TPacketCGLogin3* p = M2_NEW TPacketCGLogin3;
  322. thecore_memcpy(p, pinfo, sizeof(TPacketCGLogin3));
  323.  
  324. char szPasswd[PASSWD_MAX_LEN * 2 + 1];
  325. DBManager::instance().EscapeString(szPasswd, sizeof(szPasswd), passwd, strlen(passwd));
  326.  
  327. char szLogin[LOGIN_MAX_LEN * 2 + 1];
  328. DBManager::instance().EscapeString(szLogin, sizeof(szLogin), login, strlen(login));
  329.  
  330. std::string hashedPassword = DBManager::instance().Argon2PasswordHash(szPasswd);
  331.  
  332. // CHANNEL_SERVICE_LOGIN
  333. if (Login_IsInChannelService(szLogin))
  334. {
  335. sys_log(0, "ChannelServiceLogin [%s]", szLogin);
  336.  
  337. DBManager::instance().ReturnQuery(QID_AUTH_LOGIN, dwKey, p,
  338. "SELECT '%s', password, securitycode, social_id, id, status, availDt - NOW() > 0,"
  339. "UNIX_TIMESTAMP(silver_expire),"
  340. "UNIX_TIMESTAMP(gold_expire),"
  341. "UNIX_TIMESTAMP(safebox_expire),"
  342. "UNIX_TIMESTAMP(autoloot_expire),"
  343. "UNIX_TIMESTAMP(fish_mind_expire),"
  344. "UNIX_TIMESTAMP(marriage_fast_expire),"
  345. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  346. "UNIX_TIMESTAMP(create_time)"
  347. " FROM account WHERE login='%s'",
  348. hashedPassword.c_str(), szLogin);
  349. }
  350. // END_OF_CHANNEL_SERVICE_LOGIN
  351. else
  352. {
  353. #ifdef __WIN32__
  354. DBManager::instance().ReturnQuery(QID_AUTH_LOGIN, dwKey, p,
  355. "SELECT PASSWORD('%s'), password, securitycode, social_id, id, status, availDt - NOW() > 0,"
  356. "UNIX_TIMESTAMP(silver_expire),"
  357. "UNIX_TIMESTAMP(gold_expire),"
  358. "UNIX_TIMESTAMP(safebox_expire),"
  359. "UNIX_TIMESTAMP(autoloot_expire),"
  360. "UNIX_TIMESTAMP(fish_mind_expire),"
  361. "UNIX_TIMESTAMP(marriage_fast_expire),"
  362. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  363. "UNIX_TIMESTAMP(create_time)"
  364. " FROM account WHERE login='%s'", szLogin);
  365. #else
  366. DBManager::instance().ReturnQuery(QID_AUTH_LOGIN, dwKey, p,
  367. "SELECT '%s', password, securitycode, social_id, id, status, availDt - NOW() > 0,"
  368. "UNIX_TIMESTAMP(silver_expire),"
  369. "UNIX_TIMESTAMP(gold_expire),"
  370. "UNIX_TIMESTAMP(safebox_expire),"
  371. "UNIX_TIMESTAMP(autoloot_expire),"
  372. "UNIX_TIMESTAMP(fish_mind_expire),"
  373. "UNIX_TIMESTAMP(marriage_fast_expire),"
  374. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  375. "UNIX_TIMESTAMP(create_time)"
  376. " FROM account WHERE login='%s'",
  377. DBManager::Instance().Argon2PasswordHash(szPasswd).c_str(), szLogin);
  378. #endif
  379.  
  380. extern void socket_timeout(socket_t s, long sec, long usec);
  381.  
  382. //OpenID
  383. int CInputAuth::auth_OpenID(const char *authKey, const char *ipAddr, char *rID)
  384. {
  385. //return value
  386. //0 : normal execution
  387. //1 : cannot connect to openid auth server
  388. //2 : socket_write failed
  389. //3 : openid auth server not reply
  390. //4 : Reply Error
  391. //5 : Incorrect auth key.
  392.  
  393. extern char openid_host[256];
  394. extern char openid_uri[256];
  395.  
  396. int port = 80;
  397.  
  398. socket_t fd = socket_connect(openid_host, port);
  399. if (fd < 0)
  400. {
  401. sys_err("[auth_OpenID] : could not connect to OpenID server(%s)", openid_host);
  402. return 1;
  403. }
  404.  
  405. socket_block(fd);
  406. socket_timeout(fd, 3, 0);
  407.  
  408. // send request
  409. {
  410. char request[512];
  411. int len = snprintf(request, sizeof(request),
  412. //"GET /kyw/gameauth.php?auth_key=%s&ip=%s HTTP/1.1\r\n"
  413. "GET %s?auth_key=%s&ip=%s HTTP/1.1\r\n"
  414. "Host: %s\r\n"
  415. "Connection: Close\r\n\r\n",
  416. //openid_uri, authKey,ipAddr);//"aaaaa", "202.31.212.73");
  417. //authKey,ipAddr);
  418. //"/kyw/gameauth.php", authKey, ipAddr);
  419. openid_uri, authKey, ipAddr, openid_host);
  420.  
  421. //#ifndef __WIN32__
  422. // if (write(fd, request, len) < 0)
  423. //#else
  424. if (socket_write(fd, request, len) < 0)
  425. //#endif
  426. {
  427. sys_err("[auth_OpenID] : could not send auth-request (%s)", authKey);
  428. socket_close(fd);
  429. return 2;
  430. }
  431. }
  432.  
  433. // read reply
  434. {
  435. char reply[1024] = {0};
  436. int len;
  437. //#ifndef __WIN32__
  438. // len = read(fd, reply, sizeof(reply));
  439. //#else
  440. len = socket_read(fd, reply, sizeof(reply));
  441. //#endif
  442. socket_close(fd);
  443.  
  444. if (len <= 0)
  445. {
  446. sys_err("[auth_OpenID] : could not recv auth-reply (%s)", authKey);
  447. return 3;
  448. }
  449.  
  450.  
  451. char buffer[1024];
  452. strcpy(buffer, reply);
  453.  
  454. const char *delim = "\r\n";
  455. //char *last = 0;
  456. char *v = strtok(buffer, delim);
  457. char *result = 0;
  458.  
  459. while (v)
  460. {
  461. result = v;
  462. v = strtok(NULL, delim);
  463. }
  464.  
  465.  
  466. char *id = strtok(result, "%");
  467. char *success = strtok(NULL, "%");
  468.  
  469. if (!*id || !*success)
  470. {
  471. sys_err("[auth_OpenID] : OpenID AuthServer Reply Error (%s)", reply);
  472. return 4;
  473. }
  474.  
  475. if (0 != strcmp("OK", success))
  476. {
  477. int returnNumber = 0;
  478. str_to_number(returnNumber, id);
  479. switch (returnNumber)
  480. {
  481. case 1:
  482. sys_err("[auth_OpenID] : AuthKey incorrect");
  483. break;
  484. case 2:
  485. sys_err("[auth_OpenID] : ip incorrect");
  486. break;
  487. case 3:
  488. sys_err("[auth_OpenID] : used AuthKey");
  489. break;
  490. case 4:
  491. sys_err("[auth_OpenID] : AuthKey not delivered");
  492. break;
  493. case 5:
  494. sys_err("[auth_OpenID] : ip not delivered");
  495. break;
  496. case 6:
  497. sys_err("[auth_OpenID] : AuthKey time over");
  498. break;
  499. default:
  500. break;
  501. }
  502.  
  503. return 5;
  504. }
  505.  
  506. strcpy(rID, id);
  507.  
  508. return 0;
  509. }
  510. }
  511.  
  512.  
  513. int CInputAuth::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
  514. {
  515.  
  516. if (!g_bAuthServer)
  517. {
  518. sys_err ("CInputAuth class is not for game server. IP %s might be a hacker.",
  519. inet_ntoa(d->GetAddr().sin_addr));
  520. d->DelayedDisconnect(5);
  521. return 0;
  522. }
  523.  
  524. int iExtraLen = 0;
  525.  
  526. if (test_server)
  527. sys_log(0, " InputAuth Analyze Header[%d] ", bHeader);
  528.  
  529. switch (bHeader)
  530. {
  531. case HEADER_CG_PONG:
  532. Pong(d);
  533. break;
  534.  
  535. case HEADER_CG_LOGIN3:
  536. Login(d, c_pData);
  537. break;
  538.  
  539. case HEADER_CG_LOGIN5_OPENID:
  540. if (openid_server)
  541. LoginOpenID(d, c_pData);
  542. else
  543. sys_err("HEADER_CG_LOGIN5_OPENID : wrong client access");
  544. break;
  545.  
  546. case HEADER_CG_PASSPOD_ANSWER:
  547. PasspodAnswer(d, c_pData);
  548. break;
  549.  
  550. case HEADER_CG_HANDSHAKE:
  551. break;
  552.  
  553. default:
  554. sys_err("This phase does not handle this header %d (0x%x)(phase: AUTH)", bHeader, bHeader);
  555. break;
  556. }
  557.  
  558. return iExtraLen;
  559. }
  560.  
  561. void CInputAuth::PasspodAnswer(LPDESC d, const char * c_pData)
  562. {
  563.  
  564. if (!g_bAuthServer)
  565. {
  566. sys_err ("CInputAuth class is not for game server. IP %s might be a hacker.",
  567. inet_ntoa(d->GetAddr().sin_addr));
  568. d->DelayedDisconnect(5);
  569. return;
  570. }
  571.  
  572. TPacketCGPasspod * packet = (TPacketCGPasspod*)c_pData;
  573.  
  574. RequestConfirmPasspod Confirm;
  575.  
  576. memcpy(Confirm.passpod, packet->szAnswer, MAX_PASSPOD + 1);
  577. memcpy(Confirm.login, d->GetAccountTable().login, LOGIN_MAX_LEN + 1);
  578.  
  579.  
  580. if (!d->GetAccountTable().id)
  581. {
  582. sys_err("HEADER_CG_PASSPOD_ANSWER received to desc with no account table binded");
  583. return;
  584. }
  585.  
  586. int ret_code = 1;
  587. sys_log(0, "Passpod start %s %s", d->GetAccountTable().login, packet->szAnswer);
  588. ret_code = CPasspod::instance().ConfirmPasspod(d->GetAccountTable().login, packet->szAnswer);
  589.  
  590. if (ret_code != 0)
  591. {
  592. sys_log(0, "PASSPOD: wrong answer: %s ret_code %d", d->GetAccountTable().login, ret_code);
  593.  
  594. LoginFailure(d, ERR_MESSAGE[ret_code]);
  595.  
  596. if (!d->CheckMatrixTryCount())
  597. {
  598. LoginFailure(d, "QUIT");
  599. d->SetPhase(PHASE_CLOSE);
  600. }
  601. }
  602. else
  603. {
  604. sys_log(0, "PASSPOD: success: %s", d->GetAccountTable().login);
  605. DBManager::instance().SendAuthLogin(d);
  606. }
  607. // g_PasspodDesc->DBPacket(HEADER_GP_CONFIRM_PASSPOD, 0, &Confirm, sizeof(Confirm));
  608.  
  609. // sys_log(0, "PASSPOD %s %d", Confirm.login, Confirm.passpod);
  610. }
  611.  
  612.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement