diff options
| -rw-r--r-- | sql/base/auth_database.sql | 4 | ||||
| -rw-r--r-- | sql/updates/auth/master/2017_09_22_00_auth.sql | 3 | ||||
| -rw-r--r-- | src/server/bnetserver/REST/LoginRESTService.cpp | 168 | ||||
| -rw-r--r-- | src/server/bnetserver/REST/LoginRESTService.h | 21 | ||||
| -rw-r--r-- | src/server/bnetserver/Server/Session.cpp | 183 | ||||
| -rw-r--r-- | src/server/bnetserver/Server/Session.h | 12 | ||||
| -rw-r--r-- | src/server/bnetserver/Services/AuthenticationService.cpp | 11 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.cpp | 8 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.h | 2 |
9 files changed, 192 insertions, 220 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 17b06f7e640..7d8dcb23473 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -370,6 +370,8 @@ CREATE TABLE `battlenet_accounts` ( `locale` tinyint(3) unsigned NOT NULL DEFAULT '0', `os` varchar(4) NOT NULL DEFAULT '', `LastCharacterUndelete` int(10) unsigned NOT NULL DEFAULT '0', + `LoginTicket` varchar(64), + `LoginTicketExpiry` int(10) unsigned, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account System'; /*!40101 SET character_set_client = @saved_cs_client */; @@ -757,7 +759,7 @@ CREATE TABLE `updates` ( LOCK TABLES `updates` WRITE; /*!40000 ALTER TABLE `updates` DISABLE KEYS */; -INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','ARCHIVED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','ARCHIVED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_16_00_auth.sql','366AFFD1088762866091A81CE1EC64138B8B35F1','ARCHIVED','2015-11-08 00:46:02',62),('2015_10_17_00_auth.sql','AC0D45E905033F42093852D2C4476663BDACCB3D','ARCHIVED','2015-10-17 12:39:12',0),('2015_11_01_00_auth_2015_08_21_00.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-11-01 14:50:26',0),('2015_11_08_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',0),('2015_11_21_00_auth.sql','575A1D697CC6C7C517F7CCB950988267C99CE7FA','ARCHIVED','2015-11-21 21:25:38',0),('2015_12_07_00_auth.sql','24A07AC1F38E5D26A3599FC06D29E267418F69F3','ARCHIVED','2015-12-07 20:55:48',0),('2016_01_13_00_auth.sql','114527BCCB0DE286CBE6FDA3029DD0523D1037FA','ARCHIVED','2016-01-13 21:39:13',0),('2016_03_22_01_auth_2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-03-22 22:55:13',0),('2016_03_28_00_auth.sql','BA14D23D81FA24565F04A359090DE86C5E195209','ARCHIVED','2016-03-28 16:49:32',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',30),('2016_04_17_00_auth.sql','83399B64D1221B56F73A0FFB51889F11A70521BC','ARCHIVED','2016-04-17 00:22:05',0),('2016_05_07_00_auth.sql','7E36DCC4F06FCDCDA7155AF3C5EDF8D3A720565F','ARCHIVED','2016-05-07 01:00:21',0),('2016_05_19_00_auth.sql','FB52E6BF35682CE6FA667B552B551F4FBD72AC30','ARCHIVED','2016-05-19 22:18:06',0),('2016_07_19_00_auth.sql','D5498F28A1E21F4AD0E0D7C2B96FCF7292C14C4D','ARCHIVED','2016-07-19 14:00:28',0),('2016_07_19_01_auth.sql','EBFE5D7D7E7CFA0CDA76AC49A1E8D4FA461A12BE','ARCHIVED','2016-07-19 16:06:39',0),('2016_07_23_00_auth.sql','1048F6A922ACD9BFC2E4518A71AF7037F79A85C4','ARCHIVED','2016-07-23 14:39:21',0),('2016_07_23_01_auth.sql','5897C7D8B8DE15895286FBCD1535FC75E1B70F62','ARCHIVED','2016-07-23 17:35:11',0),('2016_07_30_00_auth.sql','0FD4147840F7F02E2F1828A904B269F5B66097E0','ARCHIVED','2016-07-30 15:07:02',0),('2016_08_07_00_auth.sql','D9DD23851822E32E1312FFABEE2DB721C8651443','ARCHIVED','2016-08-07 15:33:42',0),('2016_08_11_00_auth.sql','0C79A86A4DFC53746BECF3D8A145482F94AE5FC9','ARCHIVED','2016-08-11 17:02:20',0),('2016_08_13_00_auth.sql','ED2286C4FF3D80D0F4DEE3D3121BCC15544470BE','ARCHIVED','2016-08-13 01:11:49',0),('2016_08_26_00_auth.sql','3C566371B6026EFEEA19CD215EC9F02C6DA9EAB3','ARCHIVED','2016-08-26 14:09:52',19),('2016_08_27_00_auth.sql','65ABEF7ACBCEA974C744ED42F95FBBD29226917B','ARCHIVED','2016-08-27 07:02:45',0),('2016_08_30_00_auth.sql','E16C19A938FE6370921658D2B713EE28A633FD56','ARCHIVED','2016-08-30 00:00:00',0),('2016_09_02_00_auth.sql','08932DAC4BDE74D3C39A43DDE404522F23EDD035','ARCHIVED','2016-09-02 00:00:00',0),('2016_09_03_00_auth_2016_05_11_00_auth.sql','401EFD3586772BDED66B4A944C20A1AC18A22D3A','ARCHIVED','2016-09-03 11:29:38',0),('2016_09_03_01_auth.sql','08B5ABCB74BBF25A30D37AF639F0EA1B10640673','ARCHIVED','2016-09-03 13:24:32',0),('2016_09_03_02_auth_2016_06_06_00_auth.sql','A0A8D73A952D0618833416513D53F73A70E7EA25','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_03_03_auth.sql','9BF1C03EE39B6DC7E817BA46BE7D12A41AFBFDF7','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_15_00_auth.sql','CD65F822AF1B5B7776E39804D0362F3E34AA6445','ARCHIVED','2016-09-15 16:30:36',0),('2016_09_21_00_auth.sql','57219A16B88080240EED94CDD41FC2764B8A32C5','ARCHIVED','2016-09-21 17:08:43',0),('2016_09_25_00_auth.sql','E811EFD8CE92ABEC5B8C02A09E643035939CF96D','ARCHIVED','2016-09-25 15:56:58',0),('2016_10_01_00_auth.sql','7C444FF1B03BA3C83472BDA409854754D052D6FB','ARCHIVED','2016-10-01 13:32:43',0),('2016_10_06_00_auth.sql','6A415F9813EFB5B95EB2AA2B326E1A6791E25EDB','ARCHIVED','2016-10-06 23:16:24',0),('2016_10_12_00_auth.sql','671D57BBA183AC70B9580DEE19B7EC046AF2EA87','ARCHIVED','2016-10-12 00:01:05',0),('2016_10_17_00_auth.sql','A0EF594CD73690D46A46031137DB0E895F079235','ARCHIVED','2016-10-16 16:33:05',19),('2016_10_25_00_auth.sql','5743FB1AC3F564FE4192DCFA90260BAD5E501882','ARCHIVED','2016-10-25 19:27:02',0),('2016_10_28_00_auth.sql','C1B9B1DD20B2183C6CB44CAED9B91BA7C63B8C49','ARCHIVED','2016-10-28 00:07:48',0),('2016_11_04_00_auth.sql','3F4FE06DCE019EB3223B5A6E0F80E2239078967F','ARCHIVED','2016-11-04 20:25:23',0),('2016_11_09_00_auth.sql','56432F8AEC2943A398A5B8B77843138B5B704257','ARCHIVED','2016-11-09 18:46:48',0),('2016_11_17_00_auth.sql','18E8F8FC93CC38755AB571638960AAFB98C0F3F1','ARCHIVED','2016-11-17 23:47:51',0),('2016_12_04_00_auth.sql','B1623681EAB651D2A091E3F4D4D4E476CF6D3AEA','ARCHIVED','2016-12-04 00:41:36',0),('2016_12_11_00_auth.sql','24CA34537DB697962DDD69EEE4BB5E79D2A573DA','ARCHIVED','2016-12-11 18:18:59',0),('2016_12_18_00_auth.sql','7AB53E033680CF7439F142EF83CD13E6F5D0ACB9','ARCHIVED','2016-12-18 12:15:48',0),('2017_01_14_00_auth.sql','1B514D1364042DB4CE68929EB54A94F86983441D','ARCHIVED','2017-01-14 20:50:47',0),('2017_01_26_00_auth.sql','723E1B69981A32A2F28A67C64902BA1AE7E98E48','ARCHIVED','2017-01-26 17:10:15',0),('2017_01_29_00_auth.sql','B76C514678903F540302505AF66886F7D2C89E30','ARCHIVED','2017-01-29 00:00:00',0),('2017_03_11_00_auth.sql','2F2F67E51439346B212C27B7224E4614C00E1AEB','ARCHIVED','2017-03-11 00:00:00',0),('2017_03_17_00_auth.sql','4902E9B1B063F399F928C2DD7AFD60427738E227','ARCHIVED','2017-03-17 18:58:01',0),('2017_04_17_00_auth.sql','86299FAB21D895E84272286309CC8EE80F9DA8C7','ARCHIVED','2017-04-17 00:00:00',0),('2017_04_19_00_auth.sql','9903AAF50DF384F52E81F7E2892FE5271E000490','RELEASED','2017-04-18 23:16:18',32),('2017_04_22_00_auth.sql','843663B18D28FBA1EB12548500EC93953881E5F0','RELEASED','2017-04-22 19:28:22',0),('2017_04_27_00_auth.sql','308B797B47FA803D492C9C9A4C26DBEC546DBBD9','RELEASED','2017-04-28 09:10:11',0),('2017_05_14_00_auth.sql','B7E76CCDCC9A2C8103427DA4C43C7B0366ECE8B4','RELEASED','2017-05-14 12:00:00',0),('2017_06_15_00_auth.sql','DD71F25C1E61FD5F836931B02703BE3BD1B4F156','RELEASED','2017-06-15 15:20:50',0),('2017_06_18_00_auth.sql','7200968BFC2D76499149937B19F2153FD2ABC397','RELEASED','2017-06-18 22:13:37',0),('2017_06_25_00_auth.sql','A2DA6A64D4217992EF766915DEBD517DB0834E01','RELEASED','2017-06-25 00:54:10',0),('2017_06_28_00_auth.sql','6E58300D4D4DAAEE89107ECB3CB7DA8529DA738F','RELEASED','2017-06-28 19:11:09',0),('2017_06_30_00_auth.sql','C73BD277D211DBE1BB86BB1B443CA8F292D8ADEE','RELEASED','2017-06-30 16:18:51',0),('2017_08_04_00_auth.sql','2E994A704C64FECE3CE0883ED0CAC5E5A0E3A36C','RELEASED','2017-08-04 23:46:32',0),('2017_08_13_00_auth_2016_09_22_00_auth.sql','70047954E3556BFA430ADD5680EF8797F74A4B9E','RELEASED','2017-08-13 12:00:00',0); +INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','ARCHIVED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','ARCHIVED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_16_00_auth.sql','366AFFD1088762866091A81CE1EC64138B8B35F1','ARCHIVED','2015-11-08 00:46:02',62),('2015_10_17_00_auth.sql','AC0D45E905033F42093852D2C4476663BDACCB3D','ARCHIVED','2015-10-17 12:39:12',0),('2015_11_01_00_auth_2015_08_21_00.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-11-01 14:50:26',0),('2015_11_08_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',0),('2015_11_21_00_auth.sql','575A1D697CC6C7C517F7CCB950988267C99CE7FA','ARCHIVED','2015-11-21 21:25:38',0),('2015_12_07_00_auth.sql','24A07AC1F38E5D26A3599FC06D29E267418F69F3','ARCHIVED','2015-12-07 20:55:48',0),('2016_01_13_00_auth.sql','114527BCCB0DE286CBE6FDA3029DD0523D1037FA','ARCHIVED','2016-01-13 21:39:13',0),('2016_03_22_01_auth_2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-03-22 22:55:13',0),('2016_03_28_00_auth.sql','BA14D23D81FA24565F04A359090DE86C5E195209','ARCHIVED','2016-03-28 16:49:32',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',30),('2016_04_17_00_auth.sql','83399B64D1221B56F73A0FFB51889F11A70521BC','ARCHIVED','2016-04-17 00:22:05',0),('2016_05_07_00_auth.sql','7E36DCC4F06FCDCDA7155AF3C5EDF8D3A720565F','ARCHIVED','2016-05-07 01:00:21',0),('2016_05_19_00_auth.sql','FB52E6BF35682CE6FA667B552B551F4FBD72AC30','ARCHIVED','2016-05-19 22:18:06',0),('2016_07_19_00_auth.sql','D5498F28A1E21F4AD0E0D7C2B96FCF7292C14C4D','ARCHIVED','2016-07-19 14:00:28',0),('2016_07_19_01_auth.sql','EBFE5D7D7E7CFA0CDA76AC49A1E8D4FA461A12BE','ARCHIVED','2016-07-19 16:06:39',0),('2016_07_23_00_auth.sql','1048F6A922ACD9BFC2E4518A71AF7037F79A85C4','ARCHIVED','2016-07-23 14:39:21',0),('2016_07_23_01_auth.sql','5897C7D8B8DE15895286FBCD1535FC75E1B70F62','ARCHIVED','2016-07-23 17:35:11',0),('2016_07_30_00_auth.sql','0FD4147840F7F02E2F1828A904B269F5B66097E0','ARCHIVED','2016-07-30 15:07:02',0),('2016_08_07_00_auth.sql','D9DD23851822E32E1312FFABEE2DB721C8651443','ARCHIVED','2016-08-07 15:33:42',0),('2016_08_11_00_auth.sql','0C79A86A4DFC53746BECF3D8A145482F94AE5FC9','ARCHIVED','2016-08-11 17:02:20',0),('2016_08_13_00_auth.sql','ED2286C4FF3D80D0F4DEE3D3121BCC15544470BE','ARCHIVED','2016-08-13 01:11:49',0),('2016_08_26_00_auth.sql','3C566371B6026EFEEA19CD215EC9F02C6DA9EAB3','ARCHIVED','2016-08-26 14:09:52',19),('2016_08_27_00_auth.sql','65ABEF7ACBCEA974C744ED42F95FBBD29226917B','ARCHIVED','2016-08-27 07:02:45',0),('2016_08_30_00_auth.sql','E16C19A938FE6370921658D2B713EE28A633FD56','ARCHIVED','2016-08-30 00:00:00',0),('2016_09_02_00_auth.sql','08932DAC4BDE74D3C39A43DDE404522F23EDD035','ARCHIVED','2016-09-02 00:00:00',0),('2016_09_03_00_auth_2016_05_11_00_auth.sql','401EFD3586772BDED66B4A944C20A1AC18A22D3A','ARCHIVED','2016-09-03 11:29:38',0),('2016_09_03_01_auth.sql','08B5ABCB74BBF25A30D37AF639F0EA1B10640673','ARCHIVED','2016-09-03 13:24:32',0),('2016_09_03_02_auth_2016_06_06_00_auth.sql','A0A8D73A952D0618833416513D53F73A70E7EA25','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_03_03_auth.sql','9BF1C03EE39B6DC7E817BA46BE7D12A41AFBFDF7','ARCHIVED','2016-09-03 15:56:50',0),('2016_09_15_00_auth.sql','CD65F822AF1B5B7776E39804D0362F3E34AA6445','ARCHIVED','2016-09-15 16:30:36',0),('2016_09_21_00_auth.sql','57219A16B88080240EED94CDD41FC2764B8A32C5','ARCHIVED','2016-09-21 17:08:43',0),('2016_09_25_00_auth.sql','E811EFD8CE92ABEC5B8C02A09E643035939CF96D','ARCHIVED','2016-09-25 15:56:58',0),('2016_10_01_00_auth.sql','7C444FF1B03BA3C83472BDA409854754D052D6FB','ARCHIVED','2016-10-01 13:32:43',0),('2016_10_06_00_auth.sql','6A415F9813EFB5B95EB2AA2B326E1A6791E25EDB','ARCHIVED','2016-10-06 23:16:24',0),('2016_10_12_00_auth.sql','671D57BBA183AC70B9580DEE19B7EC046AF2EA87','ARCHIVED','2016-10-12 00:01:05',0),('2016_10_17_00_auth.sql','A0EF594CD73690D46A46031137DB0E895F079235','ARCHIVED','2016-10-16 16:33:05',19),('2016_10_25_00_auth.sql','5743FB1AC3F564FE4192DCFA90260BAD5E501882','ARCHIVED','2016-10-25 19:27:02',0),('2016_10_28_00_auth.sql','C1B9B1DD20B2183C6CB44CAED9B91BA7C63B8C49','ARCHIVED','2016-10-28 00:07:48',0),('2016_11_04_00_auth.sql','3F4FE06DCE019EB3223B5A6E0F80E2239078967F','ARCHIVED','2016-11-04 20:25:23',0),('2016_11_09_00_auth.sql','56432F8AEC2943A398A5B8B77843138B5B704257','ARCHIVED','2016-11-09 18:46:48',0),('2016_11_17_00_auth.sql','18E8F8FC93CC38755AB571638960AAFB98C0F3F1','ARCHIVED','2016-11-17 23:47:51',0),('2016_12_04_00_auth.sql','B1623681EAB651D2A091E3F4D4D4E476CF6D3AEA','ARCHIVED','2016-12-04 00:41:36',0),('2016_12_11_00_auth.sql','24CA34537DB697962DDD69EEE4BB5E79D2A573DA','ARCHIVED','2016-12-11 18:18:59',0),('2016_12_18_00_auth.sql','7AB53E033680CF7439F142EF83CD13E6F5D0ACB9','ARCHIVED','2016-12-18 12:15:48',0),('2017_01_14_00_auth.sql','1B514D1364042DB4CE68929EB54A94F86983441D','ARCHIVED','2017-01-14 20:50:47',0),('2017_01_26_00_auth.sql','723E1B69981A32A2F28A67C64902BA1AE7E98E48','ARCHIVED','2017-01-26 17:10:15',0),('2017_01_29_00_auth.sql','B76C514678903F540302505AF66886F7D2C89E30','ARCHIVED','2017-01-29 00:00:00',0),('2017_03_11_00_auth.sql','2F2F67E51439346B212C27B7224E4614C00E1AEB','ARCHIVED','2017-03-11 00:00:00',0),('2017_03_17_00_auth.sql','4902E9B1B063F399F928C2DD7AFD60427738E227','ARCHIVED','2017-03-17 18:58:01',0),('2017_04_17_00_auth.sql','86299FAB21D895E84272286309CC8EE80F9DA8C7','ARCHIVED','2017-04-17 00:00:00',0),('2017_04_19_00_auth.sql','9903AAF50DF384F52E81F7E2892FE5271E000490','RELEASED','2017-04-18 23:16:18',32),('2017_04_22_00_auth.sql','843663B18D28FBA1EB12548500EC93953881E5F0','RELEASED','2017-04-22 19:28:22',0),('2017_04_27_00_auth.sql','308B797B47FA803D492C9C9A4C26DBEC546DBBD9','RELEASED','2017-04-28 09:10:11',0),('2017_05_14_00_auth.sql','B7E76CCDCC9A2C8103427DA4C43C7B0366ECE8B4','RELEASED','2017-05-14 12:00:00',0),('2017_06_15_00_auth.sql','DD71F25C1E61FD5F836931B02703BE3BD1B4F156','RELEASED','2017-06-15 15:20:50',0),('2017_06_18_00_auth.sql','7200968BFC2D76499149937B19F2153FD2ABC397','RELEASED','2017-06-18 22:13:37',0),('2017_06_25_00_auth.sql','A2DA6A64D4217992EF766915DEBD517DB0834E01','RELEASED','2017-06-25 00:54:10',0),('2017_06_28_00_auth.sql','6E58300D4D4DAAEE89107ECB3CB7DA8529DA738F','RELEASED','2017-06-28 19:11:09',0),('2017_06_30_00_auth.sql','C73BD277D211DBE1BB86BB1B443CA8F292D8ADEE','RELEASED','2017-06-30 16:18:51',0),('2017_08_04_00_auth.sql','2E994A704C64FECE3CE0883ED0CAC5E5A0E3A36C','RELEASED','2017-08-04 23:46:32',0),('2017_08_13_00_auth_2016_09_22_00_auth.sql','70047954E3556BFA430ADD5680EF8797F74A4B9E','RELEASED','2017-08-13 12:00:00',0),('2017_09_22_00_auth.sql','9313CCE80A18212E6F0C78D83316DE8582AE8084','RELEASED','2017-09-22 18:05:17',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/auth/master/2017_09_22_00_auth.sql b/sql/updates/auth/master/2017_09_22_00_auth.sql new file mode 100644 index 00000000000..1b2fe2850a3 --- /dev/null +++ b/sql/updates/auth/master/2017_09_22_00_auth.sql @@ -0,0 +1,3 @@ +ALTER TABLE `battlenet_accounts` + ADD `LoginTicket` varchar(64), + ADD `LoginTicketExpiry` int(10) unsigned; diff --git a/src/server/bnetserver/REST/LoginRESTService.cpp b/src/server/bnetserver/REST/LoginRESTService.cpp index 8b84b1a86f5..9fd4b246df7 100644 --- a/src/server/bnetserver/REST/LoginRESTService.cpp +++ b/src/server/bnetserver/REST/LoginRESTService.cpp @@ -51,13 +51,10 @@ public: soap* GetClient() const { return _client.get(); } void SetCallback(std::unique_ptr<QueryCallback> callback) { _callback = std::move(callback); } - std::unique_ptr<Battlenet::Session::AccountInfo>& GetResult() { return _result; } - void SetResult(std::unique_ptr<Battlenet::Session::AccountInfo> result) { _result = std::move(result); } private: std::shared_ptr<soap> _client; std::unique_ptr<QueryCallback> _callback; - std::unique_ptr<Battlenet::Session::AccountInfo> _result; }; int32 handle_get_plugin(soap* soapClient) @@ -127,10 +124,6 @@ bool LoginRESTService::Start(boost::asio::io_service* ioService) input->set_type("submit"); input->set_label("Log In"); - _loginTicketCleanupTimer = new boost::asio::deadline_timer(*ioService); - _loginTicketCleanupTimer->expires_from_now(boost::posix_time::seconds(10)); - _loginTicketCleanupTimer->async_wait(std::bind(&LoginRESTService::CleanupLoginTickets, this, std::placeholders::_1)); - _thread = std::thread(std::bind(&LoginRESTService::Run, this)); return true; } @@ -138,7 +131,6 @@ bool LoginRESTService::Start(boost::asio::io_service* ioService) void LoginRESTService::Stop() { _stopped = true; - _loginTicketCleanupTimer->cancel(); _thread.join(); } @@ -277,49 +269,68 @@ int32 LoginRESTService::HandlePost(soap* soapClient) Utf8ToUpperOnlyLatin(login); Utf8ToUpperOnlyLatin(password); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_AUTHENTICATION); stmt->setString(0, login); std::string sentPasswordHash = CalculateShaPassHash(login, password); std::shared_ptr<AsyncLoginRequest> request = std::make_shared<AsyncLoginRequest>(*reinterpret_cast<std::shared_ptr<soap>*>(soapClient->user)); request->SetCallback(Trinity::make_unique<QueryCallback>(LoginDatabase.AsyncQuery(stmt) - .WithChainingPreparedCallback([request, login, sentPasswordHash](QueryCallback& callback, PreparedQueryResult result) + .WithChainingPreparedCallback([request, login, sentPasswordHash, this](QueryCallback& callback, PreparedQueryResult result) { if (result) { - std::string pass_hash = result->Fetch()[13].GetString(); - - request->SetResult(Trinity::make_unique<Battlenet::Session::AccountInfo>()); - request->GetResult()->LoadResult(result); + Field* fields = result->Fetch(); + uint32 accountId = fields[0].GetUInt32(); + std::string pass_hash = fields[1].GetString(); + uint32 failedLogins = fields[2].GetUInt32(); + std::string loginTicket = fields[3].GetString(); + uint32 loginTicketExpiry = fields[4].GetUInt32(); + bool isBanned = fields[5].GetUInt64() != 0; if (sentPasswordHash == pass_hash) { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID); - stmt->setUInt32(0, request->GetResult()->Id); - callback.SetNextQuery(LoginDatabase.AsyncQuery(stmt)); + if (loginTicket.empty() || loginTicketExpiry < time(nullptr)) + { + BigNumber ticket; + ticket.SetRand(20 * 8); + + loginTicket = "TC-" + ByteArrayToHexStr(ticket.AsByteArray(20).get(), 20); + } + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_AUTHENTICATION); + stmt->setString(0, loginTicket); + stmt->setUInt32(1, time(nullptr) + 3600); + stmt->setUInt32(2, accountId); + callback.WithPreparedCallback([request, loginTicket](PreparedQueryResult) + { + Battlenet::JSON::Login::LoginResult loginResult; + loginResult.set_authentication_state(Battlenet::JSON::Login::DONE); + loginResult.set_login_ticket(loginTicket); + sLoginService.SendResponse(request->GetClient(), loginResult); + }).SetNextQuery(LoginDatabase.AsyncQuery(stmt)); return; } - else if (!request->GetResult()->IsBanned) + else if (!isBanned) { std::string ip_address = boost::asio::ip::address_v4(request->GetClient()->ip).to_string(); uint32 maxWrongPassword = uint32(sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0)); if (sConfigMgr->GetBoolDefault("WrongPass.Logging", false)) - TC_LOG_DEBUG("server.rest", "[%s, Account %s, Id %u] Attempted to connect with wrong password!", ip_address.c_str(), login.c_str(), request->GetResult()->Id); + TC_LOG_DEBUG("server.rest", "[%s, Account %s, Id %u] Attempted to connect with wrong password!", ip_address.c_str(), login.c_str(), accountId); if (maxWrongPassword) { SQLTransaction trans = LoginDatabase.BeginTransaction(); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); - stmt->setUInt32(0, request->GetResult()->Id); + stmt->setUInt32(0, accountId); trans->Append(stmt); - ++request->GetResult()->FailedLogins; + ++failedLogins; - TC_LOG_DEBUG("server.rest", "MaxWrongPass : %u, failed_login : %u", maxWrongPassword, request->GetResult()->Id); + TC_LOG_DEBUG("server.rest", "MaxWrongPass : %u, failed_login : %u", maxWrongPassword, accountId); - if (request->GetResult()->FailedLogins >= maxWrongPassword) + if (failedLogins >= maxWrongPassword) { BanMode banType = BanMode(sConfigMgr->GetIntDefault("WrongPass.BanType", uint16(BanMode::BAN_IP))); int32 banTime = sConfigMgr->GetIntDefault("WrongPass.BanTime", 600); @@ -327,7 +338,7 @@ int32 LoginRESTService::HandlePost(soap* soapClient) if (banType == BanMode::BAN_ACCOUNT) { stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ACCOUNT_AUTO_BANNED); - stmt->setUInt32(0, request->GetResult()->Id); + stmt->setUInt32(0, accountId); } else { @@ -339,7 +350,7 @@ int32 LoginRESTService::HandlePost(soap* soapClient) trans->Append(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_RESET_FAILED_LOGINS); - stmt->setUInt32(0, request->GetResult()->Id); + stmt->setUInt32(0, accountId); trans->Append(stmt); } @@ -350,52 +361,6 @@ int32 LoginRESTService::HandlePost(soap* soapClient) Battlenet::JSON::Login::LoginResult loginResult; loginResult.set_authentication_state(Battlenet::JSON::Login::DONE); sLoginService.SendResponse(request->GetClient(), loginResult); - }) - .WithChainingPreparedCallback([request](QueryCallback& callback, PreparedQueryResult characterCountsResult) - { - if (characterCountsResult) - { - do - { - Field* fields = characterCountsResult->Fetch(); - request->GetResult()->GameAccounts[fields[0].GetUInt32()] - .CharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8(); - - } while (characterCountsResult->NextRow()); - } - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS); - stmt->setUInt32(0, request->GetResult()->Id); - callback.SetNextQuery(LoginDatabase.AsyncQuery(stmt)); - }) - .WithPreparedCallback([request](PreparedQueryResult lastPlayerCharactersResult) - { - if (lastPlayerCharactersResult) - { - do - { - Field* fields = lastPlayerCharactersResult->Fetch(); - Battlenet::RealmHandle realmId{ fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt32() }; - Battlenet::Session::LastPlayedCharacterInfo& lastPlayedCharacter = request->GetResult()->GameAccounts[fields[0].GetUInt32()] - .LastPlayedCharacters[realmId.GetSubRegionAddress()]; - - lastPlayedCharacter.RealmId = realmId; - lastPlayedCharacter.CharacterName = fields[4].GetString(); - lastPlayedCharacter.CharacterGUID = fields[5].GetUInt64(); - lastPlayedCharacter.LastPlayedTime = fields[6].GetUInt32(); - - } while (lastPlayerCharactersResult->NextRow()); - } - - BigNumber ticket; - ticket.SetRand(20 * 8); - - Battlenet::JSON::Login::LoginResult loginResult; - loginResult.set_authentication_state(Battlenet::JSON::Login::DONE); - loginResult.set_login_ticket("TC-" + ByteArrayToHexStr(ticket.AsByteArray(20).get(), 20)); - sLoginService.SendResponse(request->GetClient(), loginResult); - - sLoginService.AddLoginTicket(loginResult.login_ticket(), std::move(request->GetResult())); }))); _ioService->post(std::bind(&LoginRESTService::HandleAsyncRequest, this, std::move(request))); @@ -433,68 +398,9 @@ std::string LoginRESTService::CalculateShaPassHash(std::string const& name, std: return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true); } -std::unique_ptr<Battlenet::Session::AccountInfo> LoginRESTService::VerifyLoginTicket(std::string const& id) -{ - std::unique_lock<std::mutex> lock(_loginTicketMutex); - - auto itr = _validLoginTickets.find(id); - if (itr != _validLoginTickets.end()) - { - if (itr->second.ExpiryTime > time(nullptr)) - { - std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo = std::move(itr->second.Account); - _validLoginTickets.erase(itr); - return accountInfo; - } - } - - return std::unique_ptr<Battlenet::Session::AccountInfo>(); -} - -void LoginRESTService::AddLoginTicket(std::string const& id, std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo) -{ - std::unique_lock<std::mutex> lock(_loginTicketMutex); - - _validLoginTickets[id] = { id, std::move(accountInfo), time(nullptr) + 10 }; -} - -void LoginRESTService::CleanupLoginTickets(boost::system::error_code const& error) -{ - if (error) - return; - - time_t now = time(nullptr); - - { - std::unique_lock<std::mutex> lock(_loginTicketMutex); - for (auto itr = _validLoginTickets.begin(); itr != _validLoginTickets.end();) - { - if (itr->second.ExpiryTime < now) - itr = _validLoginTickets.erase(itr); - else - ++itr; - } - } - - _loginTicketCleanupTimer->expires_from_now(boost::posix_time::seconds(10)); - _loginTicketCleanupTimer->async_wait(std::bind(&LoginRESTService::CleanupLoginTickets, this, std::placeholders::_1)); -} - -LoginRESTService::LoginTicket& LoginRESTService::LoginTicket::operator=(LoginTicket&& right) -{ - if (this != &right) - { - Id = std::move(right.Id); - Account = std::move(right.Account); - ExpiryTime = right.ExpiryTime; - } - - return *this; -} - Namespace namespaces[] = { - { NULL, NULL, NULL, NULL } + { nullptr, nullptr, nullptr, nullptr } }; LoginRESTService& LoginRESTService::Instance() diff --git a/src/server/bnetserver/REST/LoginRESTService.h b/src/server/bnetserver/REST/LoginRESTService.h index ff9729e3333..e3a74d92907 100644 --- a/src/server/bnetserver/REST/LoginRESTService.h +++ b/src/server/bnetserver/REST/LoginRESTService.h @@ -24,9 +24,7 @@ #include <boost/asio/io_service.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/address.hpp> -#include <boost/asio/deadline_timer.hpp> #include <atomic> -#include <mutex> #include <thread> class AsyncLoginRequest; @@ -42,7 +40,7 @@ enum class BanMode class LoginRESTService { public: - LoginRESTService() : _ioService(nullptr), _stopped(false), _port(0), _loginTicketCleanupTimer(nullptr) { } + LoginRESTService() : _ioService(nullptr), _stopped(false), _port(0) { } static LoginRESTService& Instance(); @@ -51,8 +49,6 @@ public: boost::asio::ip::tcp::endpoint const& GetAddressForClient(boost::asio::ip::address const& address) const; - std::unique_ptr<Battlenet::Session::AccountInfo> VerifyLoginTicket(std::string const& id); - private: void Run(); @@ -68,18 +64,6 @@ private: std::string CalculateShaPassHash(std::string const& name, std::string const& password); - void AddLoginTicket(std::string const& id, std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo); - void CleanupLoginTickets(boost::system::error_code const& error); - - struct LoginTicket - { - LoginTicket& operator=(LoginTicket&& right); - - std::string Id; - std::unique_ptr<Battlenet::Session::AccountInfo> Account; - std::time_t ExpiryTime; - }; - struct ResponseCodePlugin { static char const* const PluginId; @@ -110,9 +94,6 @@ private: int32 _port; boost::asio::ip::tcp::endpoint _externalAddress; boost::asio::ip::tcp::endpoint _localAddress; - std::mutex _loginTicketMutex; - std::unordered_map<std::string, LoginTicket> _validLoginTickets; - boost::asio::deadline_timer* _loginTicketCleanupTimer; }; #define sLoginService LoginRESTService::Instance() diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 1c7d4aed521..bc6c4dfb92a 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -30,14 +30,14 @@ void Battlenet::Session::AccountInfo::LoadResult(PreparedQueryResult result) { - // ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab WHERE email = ? + // ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.LoginTicketExpiry, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab WHERE email = ? Field* fields = result->Fetch(); Id = fields[0].GetUInt32(); Login = fields[1].GetString(); IsLockedToIP = fields[2].GetBool(); LockCountry = fields[3].GetString(); LastIP = fields[4].GetString(); - FailedLogins = fields[5].GetUInt32(); + LoginTicketExpiry = fields[5].GetUInt32(); IsBanned = fields[6].GetUInt64() != 0; IsPermanenetlyBanned = fields[7].GetUInt64() != 0; @@ -206,7 +206,7 @@ void Battlenet::Session::SendRequest(uint32 serviceHash, uint32 methodId, pb::Me AsyncWrite(&packet); } -uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* logonRequest) +uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* logonRequest, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& /*continuation*/) { if (logonRequest->program() != "WoW") { @@ -228,6 +228,7 @@ uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* l _locale = logonRequest->locale(); _os = logonRequest->platform(); + _build = logonRequest->application_version(); boost::asio::ip::tcp::endpoint const& endpoint = sLoginService.GetAddressForClient(GetRemoteIpAddress()); @@ -238,77 +239,152 @@ uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* l return ERROR_OK; } -uint32 Battlenet::Session::HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* verifyWebCredentialsRequest) +uint32 Battlenet::Session::HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* verifyWebCredentialsRequest, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) { - authentication::v1::LogonResult logonResult; - logonResult.set_error_code(0); - _accountInfo = sLoginService.VerifyLoginTicket(verifyWebCredentialsRequest->web_credentials()); - if (!_accountInfo) - return ERROR_DENIED; + return VerifyWebCredentials(verifyWebCredentialsRequest->web_credentials(), continuation); +} - std::string ip_address = GetRemoteIpAddress().to_string(); +uint32 Battlenet::Session::VerifyWebCredentials(std::string const& webCredentials, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); + stmt->setString(0, webCredentials); - // If the IP is 'locked', check that the player comes indeed from the correct IP address - if (_accountInfo->IsLockedToIP) + std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)> asyncContinuation = std::move(continuation); + std::shared_ptr<AccountInfo> accountInfo = std::make_shared<AccountInfo>(); + _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithChainingPreparedCallback([this, accountInfo, asyncContinuation](QueryCallback& callback, PreparedQueryResult result) { - TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to IP - '%s' is logging in from '%s'", - _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str()); + if (!result) + { + asyncContinuation(&Battlenet::Services::Authentication(this), ERROR_DENIED, &NoData()); + return; + } - if (_accountInfo->LastIP != ip_address) - return ERROR_RISK_ACCOUNT_LOCKED; - } - else + accountInfo->LoadResult(result); + + if (accountInfo->LoginTicketExpiry < time(nullptr)) + { + asyncContinuation(&Battlenet::Services::Authentication(this), ERROR_TIMED_OUT, &NoData()); + return; + } + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID); + stmt->setUInt32(0, accountInfo->Id); + callback.SetNextQuery(LoginDatabase.AsyncQuery(stmt)); + }) + .WithChainingPreparedCallback([accountInfo](QueryCallback& callback, PreparedQueryResult characterCountsResult) { - TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to ip", _accountInfo->Login.c_str()); - if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00") - TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to country", _accountInfo->Login.c_str()); - else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty()) + if (characterCountsResult) { - TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to country: '%s' Player country is '%s'", - _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str()); + do + { + Field* fields = characterCountsResult->Fetch(); + accountInfo->GameAccounts[fields[0].GetUInt32()] + .CharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8(); - if (_ipCountry != _accountInfo->LockCountry) - return ERROR_RISK_ACCOUNT_LOCKED; + } while (characterCountsResult->NextRow()); } - } - // If the account is banned, reject the logon attempt - if (_accountInfo->IsBanned) + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS); + stmt->setUInt32(0, accountInfo->Id); + callback.SetNextQuery(LoginDatabase.AsyncQuery(stmt)); + }) + .WithPreparedCallback([this, accountInfo, asyncContinuation](PreparedQueryResult lastPlayerCharactersResult) { - if (_accountInfo->IsPermanenetlyBanned) + if (lastPlayerCharactersResult) + { + do + { + Field* fields = lastPlayerCharactersResult->Fetch(); + Battlenet::RealmHandle realmId{ fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt32() }; + Battlenet::Session::LastPlayedCharacterInfo& lastPlayedCharacter = accountInfo->GameAccounts[fields[0].GetUInt32()] + .LastPlayedCharacters[realmId.GetSubRegionAddress()]; + + lastPlayedCharacter.RealmId = realmId; + lastPlayedCharacter.CharacterName = fields[4].GetString(); + lastPlayedCharacter.CharacterGUID = fields[5].GetUInt64(); + lastPlayedCharacter.LastPlayedTime = fields[6].GetUInt32(); + + } while (lastPlayerCharactersResult->NextRow()); + } + + _accountInfo = accountInfo; + + std::string ip_address = GetRemoteIpAddress().to_string(); + + // If the IP is 'locked', check that the player comes indeed from the correct IP address + if (_accountInfo->IsLockedToIP) { - TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str()); - return ERROR_GAME_ACCOUNT_BANNED; + TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to IP - '%s' is logging in from '%s'", + _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str()); + + if (_accountInfo->LastIP != ip_address) + { + asyncContinuation(&Battlenet::Services::Authentication(this), ERROR_RISK_ACCOUNT_LOCKED, &NoData()); + return; + } } else { - TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Temporarily banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str()); - return ERROR_GAME_ACCOUNT_SUSPENDED; + TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to ip", _accountInfo->Login.c_str()); + if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00") + TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to country", _accountInfo->Login.c_str()); + else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty()) + { + TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to country: '%s' Player country is '%s'", + _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str()); + + if (_ipCountry != _accountInfo->LockCountry) + { + asyncContinuation(&Battlenet::Services::Authentication(this), ERROR_RISK_ACCOUNT_LOCKED, &NoData()); + return; + } + } } - } - logonResult.mutable_account_id()->set_low(_accountInfo->Id); - logonResult.mutable_account_id()->set_high(UI64LIT(0x100000000000000)); - for (auto itr = _accountInfo->GameAccounts.begin(); itr != _accountInfo->GameAccounts.end(); ++itr) - { - if (!itr->second.IsBanned) + // If the account is banned, reject the logon attempt + if (_accountInfo->IsBanned) { - EntityId* gameAccountId = logonResult.add_game_account_id(); - gameAccountId->set_low(itr->second.Id); - gameAccountId->set_high(UI64LIT(0x200000200576F57)); + if (_accountInfo->IsPermanenetlyBanned) + { + TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str()); + asyncContinuation(&Battlenet::Services::Authentication(this), ERROR_GAME_ACCOUNT_BANNED, &NoData()); + return; + } + else + { + TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Temporarily banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str()); + asyncContinuation(&Battlenet::Services::Authentication(this), ERROR_GAME_ACCOUNT_SUSPENDED, &NoData()); + return; + } } - } - if (!_ipCountry.empty()) - logonResult.set_geoip_country(_ipCountry); + authentication::v1::LogonResult logonResult; + logonResult.set_error_code(0); + logonResult.mutable_account_id()->set_low(_accountInfo->Id); + logonResult.mutable_account_id()->set_high(UI64LIT(0x100000000000000)); + for (auto itr = _accountInfo->GameAccounts.begin(); itr != _accountInfo->GameAccounts.end(); ++itr) + { + if (!itr->second.IsBanned) + { + EntityId* gameAccountId = logonResult.add_game_account_id(); + gameAccountId->set_low(itr->second.Id); + gameAccountId->set_high(UI64LIT(0x200000200576F57)); + } + } + + if (!_ipCountry.empty()) + logonResult.set_geoip_country(_ipCountry); + + BigNumber k; + k.SetRand(8 * 64); + logonResult.set_session_key(k.AsByteArray(64).get(), 64); - BigNumber k; - k.SetRand(8 * 64); - logonResult.set_session_key(k.AsByteArray(64).get(), 64); + _authed = true; - _authed = true; + asyncContinuation(&Battlenet::Services::Authentication(this), ERROR_OK, &NoData()); + Service<authentication::v1::AuthenticationListener>(this).OnLogonComplete(&logonResult); + })); - Service<authentication::v1::AuthenticationListener>(this).OnLogonComplete(&logonResult); return ERROR_OK; } @@ -425,6 +501,7 @@ uint32 Battlenet::Session::GetRealmListTicket(std::unordered_map<std::string, Va if (!_gameAccountInfo) return ERROR_UTIL_SERVER_INVALID_IDENTITY_ARGS; + bool clientInfoOk = false; if (Variant const* clientInfo = GetParam(params, "Param_ClientInfo")) { ::JSON::RealmList::RealmListTicketClientInformation data; @@ -433,13 +510,13 @@ uint32 Battlenet::Session::GetRealmListTicket(std::unordered_map<std::string, Va { if (_clientSecret.size() == data.info().secret().size()) { - _build = data.info().version().versionbuild(); + clientInfoOk = true; memcpy(_clientSecret.data(), data.info().secret().data(), _clientSecret.size()); } } } - if (!_build) + if (!clientInfoOk) return ERROR_WOW_SERVICES_DENIED_REALM_LIST_TICKET; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO); diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 99a0ec088a1..398ca176840 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -34,6 +34,8 @@ using boost::asio::ip::tcp; namespace pb = google::protobuf; +class ServiceBase; + namespace bgs { namespace protocol @@ -114,7 +116,7 @@ namespace Battlenet bool IsLockedToIP; std::string LockCountry; std::string LastIP; - uint32 FailedLogins; + uint32 LoginTicketExpiry; bool IsBanned; bool IsPermanenetlyBanned; @@ -141,8 +143,8 @@ namespace Battlenet void SendRequest(uint32 serviceHash, uint32 methodId, pb::Message const* request); - uint32 HandleLogon(authentication::v1::LogonRequest const* logonRequest); - uint32 HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* verifyWebCredentialsRequest); + uint32 HandleLogon(authentication::v1::LogonRequest const* logonRequest, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation); + uint32 HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* verifyWebCredentialsRequest, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation); uint32 HandleGetAccountState(account::v1::GetAccountStateRequest const* request, account::v1::GetAccountStateResponse* response); uint32 HandleGetGameAccountState(account::v1::GetGameAccountStateRequest const* request, account::v1::GetGameAccountStateResponse* response); uint32 HandleProcessClientRequest(game_utilities::v1::ClientRequest const* request, game_utilities::v1::ClientResponse* response); @@ -164,6 +166,8 @@ namespace Battlenet void CheckIpCallback(PreparedQueryResult result); + uint32 VerifyWebCredentials(std::string const& webCredentials, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation); + typedef uint32(Session::*ClientRequestHandler)(std::unordered_map<std::string, Variant const*> const&, game_utilities::v1::ClientResponse*); static std::unordered_map<std::string, ClientRequestHandler> const ClientRequestHandlers; @@ -176,7 +180,7 @@ namespace Battlenet MessageBuffer _headerBuffer; MessageBuffer _packetBuffer; - std::unique_ptr<AccountInfo> _accountInfo; + std::shared_ptr<AccountInfo> _accountInfo; GameAccountInfo* _gameAccountInfo; // Points at selected game account (inside _gameAccounts) std::string _locale; diff --git a/src/server/bnetserver/Services/AuthenticationService.cpp b/src/server/bnetserver/Services/AuthenticationService.cpp index 45e9a0920f2..6fe9b481907 100644 --- a/src/server/bnetserver/Services/AuthenticationService.cpp +++ b/src/server/bnetserver/Services/AuthenticationService.cpp @@ -22,17 +22,12 @@ Battlenet::Services::Authentication::Authentication(Session* session) : Authenti { } -uint32 Battlenet::Services::Authentication::HandleLogon(authentication::v1::LogonRequest const* request, NoData* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) +uint32 Battlenet::Services::Authentication::HandleLogon(authentication::v1::LogonRequest const* request, NoData* /*response*/, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) { - uint32 status = _session->HandleLogon(request); - // turning this into async call will be done by stealing the continuation and calling it when done - // just a test here - continuation(this, status, response); - continuation = nullptr; - return status; + return _session->HandleLogon(request, continuation); } uint32 Battlenet::Services::Authentication::HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* request, NoData* /*response*/, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) { - return _session->HandleVerifyWebCredentials(request); + return _session->HandleVerifyWebCredentials(request, continuation); } diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index 7c49b1846fd..dba35a7c906 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -116,12 +116,14 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_ACCOUNT_MUTED, "DELETE FROM account_muted WHERE guid = ?", CONNECTION_ASYNC); -#define BnetAccountInfo "ba.id, UPPER(ba.email), ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate" +#define BnetAccountInfo "ba.id, UPPER(ba.email), ba.locked, ba.lock_country, ba.last_ip, ba.LoginTicketExpiry, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate" #define BnetGameAccountInfo "a.id, a.username, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, aa.gmlevel" - PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT " BnetAccountInfo ", " BnetGameAccountInfo ", ba.sha_pass_hash" + PrepareStatement(LOGIN_SEL_BNET_AUTHENTICATION, "SELECT ba.id, ba.sha_pass_hash, ba.failed_logins, ba.LoginTicket, ba.LoginTicketExpiry, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id WHERE email = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_BNET_AUTHENTICATION, "UPDATE battlenet_accounts SET LoginTicket = ?, LoginTicketExpiry = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT " BnetAccountInfo ", " BnetGameAccountInfo "" " FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account" - " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ? ORDER BY a.id", CONNECTION_ASYNC); + " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.LoginTicket = ? ORDER BY a.id", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID, "SELECT rc.acctid, rc.numchars, r.id, r.Region, r.Battlegroup FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index b58630b4ae5..dae89a9fb3a 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -110,6 +110,8 @@ enum LoginDatabaseStatements : uint32 LOGIN_SEL_ACCOUNT_MUTE_INFO, LOGIN_DEL_ACCOUNT_MUTED, + LOGIN_SEL_BNET_AUTHENTICATION, + LOGIN_UPD_BNET_AUTHENTICATION, LOGIN_SEL_BNET_ACCOUNT_INFO, LOGIN_UPD_BNET_LAST_LOGIN_INFO, LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO, |
