void AccountMgr::UpdateAccount(Account * acct, Field * field) { uint32 id = field[0].GetUInt32(); if(id != acct->AccountId) { //printf("Account %u `%s` is a duplicate.\n", id, acct->Username.c_str()); sLog.outColor(TYELLOW, " >> deleting duplicate account %u [%s]...", id, acct->Username.c_str()); sLog.outColor(TNORMAL, "\n"); sLogonSQL->Execute("DELETE FROM accounts WHERE acct=%u", id); return; } acct->AccountId = field[0].GetUInt32(); acct->Username = field[1].GetString(); acct->Password = field[2].GetString(); acct->GMFlags = field[3].GetString(); acct->AccountFlags = field[4].GetUInt32(); acct->Banned = field[5].GetUInt32(); // Convert username/password to uppercase. this is needed ;) transform(acct->Username.begin(), acct->Username.end(), acct->Username.begin(), towupper); transform(acct->Password.begin(), acct->Password.end(), acct->Password.begin(), towupper); Sha1Hash hash; hash.UpdateData((acct->Username + ":" + acct->Password)); hash.Finalize(); memcpy(acct->SrpHash, hash.GetDigest(), 20); }
void AuthSocket::SendProof(Sha1Hash sha) { switch(_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 { sAuthLogonProof_S_BUILD_6005 proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk2 = 0x00; SendBuf((char *)&proof, sizeof(proof)); break; } case 8606: // 2.4.3 case 10505: // 3.2.2a default: // or later { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk1 = 0x00800000; proof.unk2 = 0x00; proof.unk3 = 0x00; SendBuf((char *)&proof, sizeof(proof)); break; } } }
LogonCommHandler::LogonCommHandler() { idhigh = 1; next_request = 1; pings = !Config.MainConfig.GetBoolDefault("LogonServer", "DisablePings", false); string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3"); // sha1 hash it Sha1Hash hash; hash.UpdateData(logon_pass); hash.Finalize(); memset(sql_passhash, 0, 20); memcpy(sql_passhash, hash.GetDigest(), 20); // player limit pLimit = Config.MainConfig.GetIntDefault("Server", "PlayerLimit", 500); if (pLimit == 0) pLimit = 1; server_population = 0; _realmType = 0; // cleanup servers.clear(); realms.clear(); }
void LogonCommHandler::TestConsoleLogon(string& username, string& password, uint32 requestnum) { string newuser = username; string newpass = password; string srpstr; arcemu_TOUPPER(newuser); arcemu_TOUPPER(newpass); srpstr = newuser + ":" + newpass; // Send request packet to server. map<LogonServer*, LogonCommClientSocket*>::iterator itr = logons.begin(); if(logons.size() == 0 || itr->second == 0) { // No valid logonserver is connected. return; } Sha1Hash hash; hash.UpdateData(srpstr); hash.Finalize(); WorldPacket data(RCMSG_TEST_CONSOLE_LOGIN, 100); data << requestnum; data << newuser; data.append(hash.GetDigest(), 20); itr->second->SendPacket(&data, false); }
void ClusterInterface::ConnectToRealmServer() { _lastConnectTime = UNIXTIME; string hostname; int port; string strkey; if(!Config.MainConfig.GetString("Cluster", "RSHostName", &hostname) || !Config.MainConfig.GetInt("Cluster", "RSPort", &port) || !Config.MainConfig.GetString("Cluster", "Key", &strkey)) { Log.Error("ClusterInterface", "Could not get necessary fields from config file. Please fix and rehash."); return; } /* hash the key */ Sha1Hash k; k.UpdateData(strkey); k.Finalize(); memcpy(key, k.GetDigest(), 20); Log.Notice("ClusterInterface", "Connecting to %s port %u", hostname.c_str(), port); WSClient * s = ConnectTCPSocket<WSClient>(hostname.c_str(), port); if(!s) { Log.Error("ClusterInterface", "Could not connect to %s:%u", hostname.c_str(), port); return; } Log.Success("ClusterInterface", "Connected to %s:%u", hostname.c_str(), port); _clientSocket = s; m_latency = getMSTime(); m_connected = true; }
void AuthSocket::SendProof(Sha1Hash sha) { switch (_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 case 6141: // 1.12.3 { sAuthLogonProof_S_BUILD_6005 proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = CMD_AUTH_LOGON_PROOF; proof.error = 0; proof.unk2 = 0x00; send((char*)&proof, sizeof(proof)); break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11723: // 3.3.3a case 12340: // 3.3.5a case 13623: // 4.0.6a case 15050: // 4.3.0 case 15595: // 4.3.4 case 16357: // 5.1.0 case 16992: // 5.3.0 case 17055: // 5.3.0 case 17116: // 5.3.0 case 17128: // 5.3.0 case 17538: // 5.4.1 case 17658: // 5.4.2 case 17688: // 5.4.2a case 17898: // 5.4.7 case 17930: // 5.4.7 case 17956: // 5.4.7 case 18019: // 5.4.7 case 18291: // 5.4.8 case 18414: // 5.4.8 default: // or later { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = CMD_AUTH_LOGON_PROOF; proof.error = 0; proof.accountFlags = ACCOUNT_FLAG_PROPASS; proof.surveyId = 0x00000000; proof.unkFlags = 0x0000; send((char*)&proof, sizeof(proof)); break; } } }
LogonCommHandler::LogonCommHandler() { idhigh = 1; next_request = 1; pings = !Config.MainConfig.GetBoolDefault("LogonServer", "DisablePings", false); string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3"); // sha1 hash it Sha1Hash hash; hash.UpdateData(logon_pass); hash.Finalize(); memcpy(sql_passhash, hash.GetDigest(), 20); }
int ZeroState::Find(const Sha1Hash &root_hash) { //fprintf(stderr,"swift: zero: Got request for %s\n",root_hash.hex().c_str() ); //std::string file_name = "content.avi"; std::string file_name = contentdir_+FILE_SEP+root_hash.hex(); uint32_t chunk_size=SWIFT_DEFAULT_CHUNK_SIZE; dprintf("%s #0 zero find %s from %s\n",tintstr(),file_name.c_str(), getcwd_utf8().c_str() ); std::string reqfilename = file_name; int ret = file_exists_utf8(reqfilename); if (ret < 0 || ret == 0 || ret == 2) return -1; reqfilename = file_name+".mbinmap"; ret = file_exists_utf8(reqfilename); if (ret < 0 || ret == 0 || ret == 2) return -1; reqfilename = file_name+".mhash"; ret = file_exists_utf8(reqfilename); if (ret < 0 || ret == 0 || ret == 2) return -1; // Open as ZeroState SwarmID swarmid(root_hash); return swift::Open(file_name, swarmid, "", false, POPT_CONT_INT_PROT_MERKLE, true); }
//Peer_id 为返回对方peer_id; bool parse_handshake_info(const t_byte* pbuf, Sha1Hash &info_hash, PeerID &peer_id, t_byte ext_info[8]) { assert(pbuf != 0); if(pbuf[0] != PROTOCOL_LENGTH) { DEBUG_PRINT0("invalid protocol length\n"); return false; } //DEBUG_PRINT1("%s\n", (const char*)&pbuf[1]); if(memcmp(&pbuf[1], PROTOCOL_STRING, PROTOCOL_LENGTH) == 0) { //DEBUG_PRINT0("invalid protocol string\n"); memcpy(ext_info, &pbuf[20], 8); info_hash.Reset(&pbuf[28]); peer_id.Reset(&pbuf[48]); return true; }else { DEBUG_PRINT0("invalid protocol string\n"); return false; } }
void AuthSocket::SendProof(Sha1Hash sha) { switch(_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 { sAuthLogonProof_S_BUILD_6005 proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk2 = 0x00; send((char *)&proof, sizeof(proof)); break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11573: // 3.3.3-11573 case 11643: // 3.3.3-11643 case 11655: // 3.3.3-11655 case 11685: // 3.3.3-11685 case 11723: // 3.3.3a-11723 case 11927: // 4.0.0-11927 case 12025: // 4.0.0-12025 case 12065: // 4.0.0-12065 case 12122: // 4.0.0-12122 case 12164: // 4.0.0-12164 case 12232: // 4.0.0-12232 default: // or later { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk1 = 0x00800000; proof.unk2 = 0x00; proof.unk3 = 0x00; send((char *)&proof, sizeof(proof)); break; } } }
std::vector<t_byte> build_hand_shake(const Sha1Hash &info_hash, const PeerID &local_peer_id) { std::vector<t_byte> buf(68, 0); buf[0] = PROTOCOL_LENGTH; memcpy(&buf[1], PROTOCOL_STRING, (t_uint32)PROTOCOL_LENGTH); memcpy(&buf[28], info_hash.GetRawData(), 20); memcpy(&buf[48], local_peer_id.GetRawData(), 20); return buf; }
void AccountMgr::AddAccount() { Account* acct = new Account; Sha1Hash hash; string Username = "******"; string Password = "******"; acct->AccountId = 1; acct->AccountFlags = 1; acct->Banned = 1; if((uint32)UNIXTIME > acct->Banned && acct->Banned != 0 && acct->Banned != 1) //1 = perm ban? { //Accounts should be unbanned once the date is past their set expiry date. acct->Banned = 0; //me go boom :( //printf("Account %s's ban has expired.\n",acct->UsernamePtr->c_str()); //sLogonSQL->Execute("UPDATE accounts SET banned = 0 WHERE acct=%u", acct->AccountId); } acct->SetGMFlags("test"); acct->Locale[0] = 'e'; acct->Locale[1] = 'n'; acct->Locale[2] = 'U'; acct->Locale[3] = 'S'; acct->forcedLocale = false; acct->Muted = 1; if((uint32)UNIXTIME > acct->Muted && acct->Muted != 0 && acct->Muted != 1) //1 = perm ban? { //Accounts should be unbanned once the date is past their set expiry date. acct->Muted = 0; //LOG_DEBUG("Account %s's mute has expired.",acct->UsernamePtr->c_str()); //sLogonSQL->Execute("UPDATE accounts SET muted = 0 WHERE acct=%u", acct->AccountId); } // Convert username/password to uppercase. this is needed ;) mnet_TOUPPER(Username); mnet_TOUPPER(Password); // prefer encrypted passwords over nonencrypted // Prehash the I value. hash.UpdateData((Username + ":" + Password)); hash.Finalize(); memcpy(acct->SrpHash, hash.GetDigest(), 20); AccountDatabase[Username] = acct; }
void CmdGwSendINFOHashChecking(cmd_gw_t* req, Sha1Hash root_hash) { // Send INFO DLSTATUS_HASHCHECKING message. char cmd[MAX_CMD_MESSAGE]; sprintf(cmd,"INFO %s %d %lli/%lli %lf %lf %u %u\r\n",root_hash.hex().c_str(),DLSTATUS_HASHCHECKING,(uint64_t)0,(uint64_t)0,0.0,0.0,0,0); //fprintf(stderr,"cmd: SendINFO: %s", cmd); send(req->cmdsock,cmd,strlen(cmd),0); }
void CmdGwGotMAXSPEED(Sha1Hash &want_hash, data_direction_t ddir, double speed) { // Set maximum speed on the specified download fprintf(stderr,"cmd: GotMAXSPEED: %s %d %lf\n",want_hash.hex().c_str(),ddir,speed); cmd_gw_t* req = CmdGwFindRequestByRootHash(want_hash); if (req == NULL) return; FileTransfer *ft = FileTransfer::file(req->transfer); ft->SetMaxSpeed(ddir,speed); }
void AuthSocket::SendProof(Sha1Hash sha) { switch(_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 { sAuthLogonProof_S_BUILD_6005 proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = CMD_AUTH_LOGON_PROOF; proof.error = 0; proof.unk2 = 0x00; send((char *)&proof, sizeof(proof)); break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11723: // 3.3.3a case 12340: // 3.3.5a case 15050: // 4.3.0a case 15354: // 4.3.3 case 15464: // 5.0.1 Beta case 15508: // 5.0.1 Beta default: // or later { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = CMD_AUTH_LOGON_PROOF; proof.error = 0; proof.accountFlags = ACCOUNT_FLAG_PROPASS; proof.surveyId = 0x00000000; proof.unkFlags = 0x0000; send((char *)&proof, sizeof(proof)); break; } } }
FileTransfer::FileTransfer(int td, std::string filename, const Sha1Hash& root_hash, bool force_check_diskvshash, popt_cont_int_prot_t cipm, uint32_t chunk_size, bool zerostate) : ContentTransfer(FILE_TRANSFER), availability_(NULL), zerostate_(zerostate) { td_ = td; Handshake hs; hs.cont_int_prot_ = cipm; SetDefaultHandshake(hs); std::string destdir; int ret = file_exists_utf8(filename); if (ret == 2 && root_hash != Sha1Hash::ZERO) { // Filename is a directory, download root_hash there destdir = filename; filename = destdir+FILE_SEP+root_hash.hex(); } else { destdir = dirname_utf8(filename); if (destdir == "") destdir = "."; } // MULTIFILE storage_ = new Storage(filename,destdir,td_,0); std::string hash_filename; hash_filename.assign(filename); hash_filename.append(".mhash"); std::string binmap_filename; binmap_filename.assign(filename); binmap_filename.append(".mbinmap"); // Arno, 2013-02-25: Create HashTree even when PROT_NONE to enable // automatic size determination via peak hashes. if (!zerostate_) { hashtree_ = (HashTree *)new MmapHashTree(storage_,root_hash,chunk_size,hash_filename,force_check_diskvshash,binmap_filename); availability_ = new Availability(SWIFT_MAX_OUTGOING_CONNECTIONS); if (ENABLE_VOD_PIECEPICKER) picker_ = new VodPiecePicker(this); else picker_ = new RFPiecePicker(this); picker_->Randomize(rand()&63); } else { // ZEROHASH hashtree_ = (HashTree *)new ZeroHashTree(storage_,root_hash,chunk_size,hash_filename,binmap_filename); } UpdateOperational(); }
std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& password) { Sha1Hash sha; sha.Initialize(); sha.UpdateData(name); sha.UpdateData(":"); sha.UpdateData(password); sha.Finalize(); std::string encoded; hexEncodeByteArray(sha.GetDigest(), sha.GetLength(), encoded); return encoded; }
/// Make the SRP6 calculation from hash in dB void AuthSocket::_SetVSFields(const std::string& rI) { s.SetRand(s_BYTE_SIZE * 8); BigNumber I; I.SetHexStr(rI.c_str()); // In case of leading zeros in the rI hash, restore them uint8 mDigest[SHA_DIGEST_LENGTH]; memset(mDigest, 0, SHA_DIGEST_LENGTH); if (I.GetNumBytes() <= SHA_DIGEST_LENGTH) memcpy(mDigest, I.AsByteArray(), I.GetNumBytes()); std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH); Sha1Hash sha; sha.UpdateData(s.AsByteArray(), s.GetNumBytes()); sha.UpdateData(mDigest, SHA_DIGEST_LENGTH); sha.Finalize(); BigNumber x; x.SetBinary(sha.GetDigest(), sha.GetLength()); v = g.ModExp(x, N); // No SQL injection (username escaped) const char* v_hex, *s_hex; v_hex = v.AsHexStr(); s_hex = s.AsHexStr(); LoginDatabase.PExecute("UPDATE account SET v = '%s', s = '%s' WHERE username = '******'", v_hex, s_hex, _safelogin.c_str()); OPENSSL_free((void*)v_hex); OPENSSL_free((void*)s_hex); }
void AccountMgr::AddAccount(Field* field) { Account acct; Sha1Hash hash; acct.AccountId = field[0].GetUInt32(); acct.Username = field[1].GetString(); acct.Password = field[2].GetString(); acct.GMFlags = field[3].GetString(); acct.AccountFlags = field[4].GetUInt32(); acct.Banned = field[5].GetUInt32(); // Convert username/password to uppercase. this is needed ;) transform(acct.Username.begin(), acct.Username.end(), acct.Username.begin(), towupper); transform(acct.Password.begin(), acct.Password.end(), acct.Password.begin(), towupper); // Prehash the I value. hash.UpdateData((acct.Username + ":" + acct.Password)); hash.Finalize(); memcpy(acct.SrpHash, hash.GetDigest(), 20); AccountDatabase[acct.Username] = acct; }
void AuthSocket::SendProof(Sha1Hash sha) { switch (_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 case 6141: // 1.12.3 { sAuthLogonProof_S_BUILD_6005 proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = CMD_AUTH_LOGON_PROOF; proof.error = 0; proof.unk2 = 0x00; send((char *)&proof, sizeof(proof)); break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11723: // 3.3.3a case 12340: // 3.3.5a default: // or later { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = CMD_AUTH_LOGON_PROOF; proof.error = 0; proof.unk1 = 0x00800000; proof.unk2 = 0x00; proof.unk3 = 0x00; send((char *)&proof, sizeof(proof)); break; } } }
void AuthSocket::HandleReconnectProof() { if( m_account == NULL ) return; // Load sessionkey from account database. QueryResult * result = sLogonSQL->Query ("SELECT SessionKey FROM accounts WHERE acct = %u", m_account->AccountId); if(result) { Field * field = result->Fetch(); K.SetHexStr(field[0].GetString ()); delete result; } else { // Disconnect if the sessionkey invalid or not found DEBUG_LOG("AuthReConnectProof","No matching SessionKey found while user %s tried to login.", AccountName.c_str()); Disconnect(); return; } if(GetReadBuffer().GetSize() < sizeof(sAuthLogonProofKey_C)) return; sAuthLogonProofKey_C lp; GetReadBuffer().Read(&lp, sizeof(sAuthLogonProofKey_C)); BigNumber A; A.SetBinary(lp.R1, 16); Sha1Hash sha; sha.Initialize(); sha.UpdateData(AccountName); sha.UpdateBigNumbers(&A, &rs, &K, 0); sha.Finalize(); if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) { ///- Sending response ByteBuffer pkt; pkt << (uint8) 0x03; //ReconnectProof pkt << (uint8) 0x00; pkt << (uint16) 0x00; // 2 bytes zeros Send(pkt.contents(), pkt.size()); // we're authenticated now :) m_authenticated = true; DEBUG_LOG("AuthReConnectProof","Authentication Success."); } else DEBUG_LOG("AuthReConnectProof","Authentication Failed."); }
void AuthSocket::SendProof(Sha1Hash sha) { switch(_build) { case 12319: // We support only 4.0.0.12319 { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk1 = 0x00800000; proof.unk2 = 0x00; proof.unk3 = 0x00; send((char *)&proof, sizeof(proof)); break; } } }
void CmdGwGotREMOVE(Sha1Hash &want_hash, bool removestate, bool removecontent) { // Remove the specified download fprintf(stderr,"cmd: GotREMOVE: %s %d %d\n",want_hash.hex().c_str(),removestate,removecontent); cmd_gw_t* req = CmdGwFindRequestByRootHash(want_hash); if (req == NULL) return; FileTransfer *ft = FileTransfer::file(req->transfer); fprintf(stderr, "%s @%i remove transfer %i\n",tintstr(),req->id,req->transfer); dprintf("%s @%i remove transfer %i\n",tintstr(),req->id,req->transfer); swift::Close(req->transfer); // Delete content + .mhash from filesystem, if desired if (removecontent) remove(req->contentfilename); if (removestate) { char *mhashfilename = (char *)malloc(strlen(req->contentfilename)+strlen(".mhash")+1); strcpy(mhashfilename,req->contentfilename); strcat(mhashfilename,".mhash"); remove(mhashfilename); free(mhashfilename); // Arno, 2012-01-10: .mbinmap gots to go too. char *mbinmapfilename = (char *)malloc(strlen(req->contentfilename)+strlen(".mbinmap")+1); strcpy(mbinmapfilename,req->contentfilename); strcat(mbinmapfilename,".mbinmap"); remove(mbinmapfilename); free(mbinmapfilename); } CmdGwFreeRequest(req); *req = cmd_requests[--cmd_gw_reqs_open]; }
void CmdGwGotCHECKPOINT(Sha1Hash &want_hash) { // Checkpoint the specified download fprintf(stderr,"cmd: GotCHECKPOINT: %s\n",want_hash.hex().c_str()); cmd_gw_t* req = CmdGwFindRequestByRootHash(want_hash); if (req == NULL) return; FileTransfer *ft = FileTransfer::file(req->transfer); std::string binmap_filename = ft->file().filename(); binmap_filename.append(".mbinmap"); fprintf(stderr,"cmdgw: GotCHECKPOINT: checkpointing to %s\n", binmap_filename.c_str() ); FILE *fp = fopen(binmap_filename.c_str(),"wb"); if (!fp) { print_error("cannot open mbinmap for writing"); return; } if (ft->file().serialize(fp) < 0) print_error("writing to mbinmap"); fclose(fp); }
/// Reconnect Proof command handler bool AuthSocket::_HandleReconnectProof() { DEBUG_LOG("Entering _HandleReconnectProof"); ///- Read the packet sAuthReconnectProof_C lp; if (!recv((char*)&lp, sizeof(sAuthReconnectProof_C))) { return false; } if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) { return false; } BigNumber t1; t1.SetBinary(lp.R1, 16); Sha1Hash sha; sha.Initialize(); sha.UpdateData(_login); sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL); sha.Finalize(); if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) { ///- Sending response ByteBuffer pkt; pkt << (uint8) CMD_AUTH_RECONNECT_PROOF; pkt << (uint8) 0x00; //If we keep from sending this we don't receive Session Expired on the client when //changing realms after being logged on to the world if (_build > 6141) // Last vanilla, 1.12.3 pkt << (uint16) 0x00; // 2 bytes zeros send((char const*)pkt.contents(), pkt.size()); ///- Set _authed to true! _authed = true; return true; } else { sLog.outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str()); close_connection(); return false; } }
/// Reconnect Proof command handler bool AuthSocket::_HandleReconnectProof() { DEBUG_LOG("Entering _HandleReconnectProof"); ///- Read the packet sAuthReconnectProof_C lp; if(!recv((char *)&lp, sizeof(sAuthReconnectProof_C))) return false; if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) return false; BigNumber t1; t1.SetBinary(lp.R1, 16); Sha1Hash sha; sha.Initialize(); sha.UpdateData(_login); sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL); sha.Finalize(); if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) { ///- Sending response ByteBuffer pkt; pkt << uint8(CMD_AUTH_RECONNECT_PROOF); pkt << uint8(0x00); pkt << uint16(0x00); // 2 bytes zeros send((char const*)pkt.contents(), pkt.size()); ///- Set _authed to true! _authed = true; return true; } else { sLog.outLog(LOG_DEFAULT, "ERROR: [ERROR] user %s tried to login, but session invalid.", _login.c_str()); close_connection(); return false; } }
/// Reconnect Proof command handler bool AuthSocket::_HandleReconnectProof() { DEBUG_LOG("Entering _HandleReconnectProof"); ///- Read the packet if (ibuf.GetLength() < sizeof(sAuthReconnectProof_C)) return false; if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) return false; sAuthReconnectProof_C lp; ibuf.Read((char *)&lp, sizeof(sAuthReconnectProof_C)); BigNumber t1; t1.SetBinary(lp.R1, 16); Sha1Hash sha; sha.Initialize(); sha.UpdateData(_login); sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL); sha.Finalize(); if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) { ///- Sending response ByteBuffer pkt; pkt << (uint8) AUTH_RECONNECT_PROOF; pkt << (uint8) 0x00; pkt << (uint16) 0x00; // 2 bytes zeros SendBuf((char const*)pkt.contents(), pkt.size()); ///- Set _authed to true! _authed = true; return true; } else { sLog.outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str()); SetCloseAndDelete(); return false; } }
/// Make the SRP6 calculation from hash in dB void AuthSocket::_SetVSFields(std::string rI) { BigNumber I; I.SetHexStr(rI.c_str()); //In case of leading zeroes in the rI hash, restore them uint8 mDigest[SHA_DIGEST_LENGTH]; memset(mDigest,0,SHA_DIGEST_LENGTH); if (I.GetNumBytes() <= SHA_DIGEST_LENGTH) memcpy(mDigest,I.AsByteArray(),I.GetNumBytes()); std::reverse(mDigest,mDigest+SHA_DIGEST_LENGTH); Sha1Hash sha; sha.UpdateData(s.AsByteArray(), s.GetNumBytes()); sha.UpdateData(mDigest, SHA_DIGEST_LENGTH); sha.Finalize(); BigNumber x; x.SetBinary(sha.GetDigest(), sha.GetLength()); v = g.ModExp(x, N); // No SQL injection (username escaped) dbRealmServer.PExecute("UPDATE `account` SET `v` = '%s', `s` = '%s' WHERE UPPER(`username`)= UPPER('%s')",v.AsHexStr(),s.AsHexStr(), _safelogin.c_str() ); }
/// Logon Proof command handler bool AuthSocket::_HandleLogonProof() { DEBUG_LOG("Entering _HandleLogonProof"); ///- Read the packet sAuthLogonProof_C lp; if (!recv((char*)&lp, sizeof(sAuthLogonProof_C))) return false; ///- Check if the client has one of the expected version numbers bool valid_version = FindBuildInfo(_build) != NULL; /// <ul><li> If the client has no valid version if (!valid_version) { if (this->patch_ != ACE_INVALID_HANDLE) return false; ///- Check if we have the apropriate patch on the disk // file looks like: 65535enGB.mpq char tmp[64]; snprintf(tmp, 24, "./patches/%d%s.mpq", _build, _localizationName.c_str()); char filename[PATH_MAX]; if (ACE_OS::realpath(tmp, filename) != NULL) { patch_ = ACE_OS::open(filename, GENERIC_READ | FILE_FLAG_SEQUENTIAL_SCAN); } if (patch_ == ACE_INVALID_HANDLE) { // no patch found ByteBuffer pkt; pkt << (uint8) CMD_AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; pkt << (uint8) WOW_FAIL_VERSION_INVALID; DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build); DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp); send((char const*)pkt.contents(), pkt.size()); return true; } XFER_INIT xferh; ACE_OFF_T file_size = ACE_OS::filesize(this->patch_); if (file_size == -1) { close_connection(); return false; } if (!PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5)) { // calculate patch md5, happens if patch was added while realmd was running PatchCache::instance()->LoadPatchMD5(tmp); PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5); } uint8 data[2] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_VERSION_UPDATE}; send((const char*)data, sizeof(data)); memcpy(&xferh, "0\x05Patch", 7); xferh.cmd = CMD_XFER_INITIATE; xferh.file_size = file_size; send((const char*)&xferh, sizeof(xferh)); return true; } /// </ul> ///- Continue the SRP6 calculation based on data received from the client BigNumber A; A.SetBinary(lp.A, 32); // SRP safeguard: abort if A==0 if (A.isZero()) return false; Sha1Hash sha; sha.UpdateBigNumbers(&A, &B, NULL); sha.Finalize(); BigNumber u; u.SetBinary(sha.GetDigest(), 20); BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); uint8 t[32]; uint8 t1[16]; uint8 vK[40]; memcpy(t, S.AsByteArray(32), 32); for (int i = 0; i < 16; ++i) { t1[i] = t[i * 2]; } sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) { vK[i * 2] = sha.GetDigest()[i]; } for (int i = 0; i < 16; ++i) { t1[i] = t[i * 2 + 1]; } sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) { vK[i * 2 + 1] = sha.GetDigest()[i]; } K.SetBinary(vK, 40); uint8 hash[20]; sha.Initialize(); sha.UpdateBigNumbers(&N, NULL); sha.Finalize(); memcpy(hash, sha.GetDigest(), 20); sha.Initialize(); sha.UpdateBigNumbers(&g, NULL); sha.Finalize(); for (int i = 0; i < 20; ++i) { hash[i] ^= sha.GetDigest()[i]; } BigNumber t3; t3.SetBinary(hash, 20); sha.Initialize(); sha.UpdateData(_login); sha.Finalize(); uint8 t4[SHA_DIGEST_LENGTH]; memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); sha.Initialize(); sha.UpdateBigNumbers(&t3, NULL); sha.UpdateData(t4, SHA_DIGEST_LENGTH); sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); sha.Finalize(); BigNumber M; M.SetBinary(sha.GetDigest(), 20); ///- Check if SRP6 results match (password is correct), else send an error if (!memcmp(M.AsByteArray(), lp.M1, 20)) { BASIC_LOG("User '%s' successfully authenticated", _login.c_str()); ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account // No SQL injection (escaped user name) and IP address as received by socket const char* K_hex = K.AsHexStr(); LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '******'", K_hex, get_remote_address().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str()); OPENSSL_free((void*)K_hex); ///- Finish SRP6 and send the final result to the client sha.Initialize(); sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.Finalize(); SendProof(sha); ///- Set _authed to true! _authed = true; } else { if (_build > 6005) // > 1.12.2 { char data[4] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0}; send(data, sizeof(data)); } else { // 1.x not react incorrectly at 4-byte message use 3 as real error char data[2] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT}; send(data, sizeof(data)); } BASIC_LOG("[AuthChallenge] account %s tried to login with wrong password!", _login.c_str()); uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0); if (MaxWrongPassCount > 0) { // Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP LoginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '******'", _safelogin.c_str()); if (QueryResult* loginfail = LoginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str())) { Field* fields = loginfail->Fetch(); uint32 failed_logins = fields[1].GetUInt32(); if (failed_logins >= MaxWrongPassCount) { uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600); bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false); if (WrongPassBanType) { uint32 acc_id = fields[0].GetUInt32(); LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)", acc_id, WrongPassBanTime); BASIC_LOG("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", _login.c_str(), WrongPassBanTime, failed_logins); } else { std::string current_ip = get_remote_address(); LoginDatabase.escape_string(current_ip); LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')", current_ip.c_str(), WrongPassBanTime); BASIC_LOG("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); } } delete loginfail; } } } return true; }
void WorldSocket::InformationRetreiveCallback(WorldPacket & recvData, uint32 requestid) { if(requestid != mRequestID) return; uint32 error; recvData >> error; if(error != 0) { // something happened wrong @ the logon server OutPacket(SMSG_AUTH_RESPONSE, 1, "\x0D"); return; } // Extract account information from the packet. string AccountName; uint32 AccountID; string GMFlags; uint32 AccountFlags; recvData >> AccountID >> AccountName >> GMFlags >> AccountFlags; sLog.outDebug( " >> got information packet from logon: `%s` ID %u (request %u)", AccountName.c_str(), AccountID, mRequestID); // sLog.outColor(TNORMAL, "\n"); mRequestID = 0; // Pull the session key. uint8 K[40]; recvData.read(K, 40); BigNumber BNK; BNK.SetBinary(K, 40); // Initialize crypto. _crypt.SetKey(K, 40); _crypt.Init(); Session * session = sClientMgr.CreateSession(AccountID); if(session == NULL) { /* we are already logged in. send auth failed. (if anyone has a better error lemme know :P) */ OutPacket(SMSG_AUTH_RESPONSE, 1, "\x0D"); return; } m_session = session; session->m_socket = this; Sha1Hash sha; uint8 digest[20]; pAuthenticationPacket->read(digest, 20); uint32 t = 0; sha.UpdateData(AccountName); sha.UpdateData((uint8 *)&t, 4); sha.UpdateData((uint8 *)&mClientSeed, 4); sha.UpdateData((uint8 *)&mSeed, 4); sha.UpdateBigNumbers(&BNK, NULL); sha.Finalize(); if (memcmp(sha.GetDigest(), digest, 20)) { // AUTH_UNKNOWN_ACCOUNT = 21 OutPacket(SMSG_AUTH_RESPONSE, 1, "\x15"); return; } // Allocate session m_session->m_accountFlags = AccountFlags; m_session->m_GMPermissions = GMFlags; m_session->m_accountId = AccountID; m_session->m_latency = _latency; m_session->m_accountName = AccountName; Log.Notice("Auth", "%s from %s:%u [%ums]", AccountName.c_str(), GetRemoteIP().c_str(), GetRemotePort(), _latency); Authenticate(); }