Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- RealmSocket::RealmSocket(SocketHandler &h) : TcpSocket(h)
- {
- N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
- g.SetDword(7);
- _authed = false;
- acct = NULL;
- }
- RealmSocket::~RealmSocket()
- {
- }
- void RealmSocket::OnAccept()
- {
- TcpSocket::OnAccept();
- Log.Text("[REALMLIST] Connection accepted from %s", GetRemoteAddress().c_str());
- s.SetRand(s_BYTE_SIZE * 8);
- }
- void RealmSocket::OnRead()
- {
- TcpSocket::OnRead();
- if(!ibuf.GetLength())
- return; // abort on no data
- unsigned char cmdid = 0;
- ibuf.SoftRead((char*)&cmdid, sizeof(unsigned char));
- switch(cmdid)
- {
- case 0x00: // CLIENT LOGON CHALLENGE
- this->_HandleLogonChallenge();
- break;
- case 0x01: // CLIENT LOGON PROOF
- this->_HandleLogonProof();
- break;
- case 0x10: // CLIENT REALM LIST
- this->_HandleRealmList();
- break;
- default:
- Log.Text("[REALMLIST] Received unknown cmdid: %d of size %u", cmdid, ibuf.GetLength());
- break;
- }
- }
- void RealmSocket::_HandleLogonChallenge()
- {
- if(ibuf.GetLength() < 4)
- return; // wtf?
- std::vector<uint8> buf;
- buf.resize(4);
- ibuf.Read((char*)&buf[0], 4);
- uint16 r = ((sAuthLogonChallenge_C *)&buf[0])->size;
- Log.Text("[REALMLIST] Got Auth Challenge Header. Body is %u bytes.", r);
- if(ibuf.GetLength() < r)
- return; // incomplete packet
- buf.resize(r+ buf.size() + 1);
- buf[buf.size() - 1] = 0;
- ibuf.Read((char *)&buf[4], r);
- sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];
- Log.Text("[REALMLIST] Got full packet. Client is build %u.", ch->build);
- Log.Text(" Username: %s", (const char*)ch->I);
- acct = AccountMgr.GetAccount((const char*)ch->I);
- if(!acct)
- {
- acct = AccountMgr.AddAccount((const char*)ch->I, "NOPASS");
- }
- ByteBuffer outpacket;
- if(!acct)
- {
- outpacket << uint8(AUTH_LOGON_CHALLENGE);
- outpacket << uint8(0);
- outpacket << uint8(0x04);
- }
- else
- {
- outpacket << uint8(AUTH_LOGON_CHALLENGE);
- outpacket << uint8(0);
- outpacket << uint8(0x00);
- password = acct->password;
- username = acct->username;
- Sha1Hash I;
- std::string sI = username + ":" + password;
- I.UpdateData(sI);
- I.Finalize();
- Sha1Hash sha;
- sha.UpdateData(s.AsByteArray(), s.GetNumBytes());
- sha.UpdateData(I.GetDigest(), SHA_DIGEST_LENGTH);
- sha.Finalize();
- BigNumber x;
- x.SetBinary(sha.GetDigest(), sha.GetLength());
- v = g.ModExp(x, N);
- b.SetRand(19 * 8);
- BigNumber gmod = g.ModExp(b, N);
- B = ((v * 3) + gmod) % N;
- ASSERT(gmod.GetNumBytes() <= 32);
- BigNumber unk3;
- unk3.SetRand(16*8);
- outpacket.append(B.AsByteArray(), 32);
- outpacket // g_len, g
- << (uint8)1;
- outpacket.append(g.AsByteArray(), 1);
- // N_len, N
- outpacket << (uint8)32;
- outpacket.append(N.AsByteArray(), 32);
- outpacket.append(s.AsByteArray(), s.GetNumBytes());
- outpacket.append(unk3.AsByteArray(), 16);
- outpacket << uint8(0x00); // new in 1.11
- }
- SendBuf(((char*)outpacket.contents()), outpacket.size());
- }
- void RealmSocket::_HandleLogonProof()
- {
- Log.Text("[REALMLIST] Got Logon Proof. Checking.");
- sAuthLogonProof_C lp;
- ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));
- BigNumber A;
- A.SetBinary(lp.A, 32);
- 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);
- 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(username);
- sha.Finalize();
- BigNumber t4;
- t4.SetBinary(sha.GetDigest(), 20);
- sha.Initialize();
- sha.UpdateBigNumbers(&t3, &t4, &s, &A, &B, &K, NULL);
- sha.Finalize();
- BigNumber M;
- M.SetBinary(sha.GetDigest(), 20);
- if (!memcmp(M.AsByteArray(), lp.M1, 20))
- {
- Log.Text(" Successful.");
- //memcpy(acct->sessionkey, K.AsHexStr(), 40);
- acct->sessionkey = K.AsHexStr();
- sha.Initialize();
- sha.UpdateBigNumbers(&A, &M, &K, NULL);
- sha.Finalize();
- sAuthLogonProof_S proof;
- memcpy(proof.M2, sha.GetDigest(), 20);
- proof.cmd = AUTH_LOGON_PROOF;
- proof.error = 0;
- proof.unk2 = 0;
- proof.unk203 = 0;
- proof.unk203_more = 0;
- SendBuf((char *)&proof, sizeof(proof));
- }
- else
- {
- ByteBuffer pkt;
- pkt << (uint8) AUTH_LOGON_PROOF;
- pkt << (uint8) 4; // bad password
- pkt << (uint32) 3;
- SendBuf((char *)pkt.contents(), pkt.size());
- }
- }
- void RealmSocket::_HandleRealmList()
- {
- // static realmlist for now.
- ByteBuffer pkt;
- if (ibuf.GetLength() < 5)
- return;
- ibuf.Remove(5);
- pkt << uint8(REALM_LIST);
- pkt << uint16(0); // size placeholder
- pkt << uint32(0);
- pkt << uint16(1);
- pkt << uint8(1);//type
- pkt << uint8(0);//lock
- pkt << uint8(0);//offline
- pkt << "Burlex WotLK Sandbox";
- pkt << "127.0.0.1:3725";
- pkt << float(1.6); //pop
- pkt << uint8(1); //ch count
- pkt << uint8(1); //realm category
- pkt << uint8(6); //unk
- pkt << uint8(0); //unk
- pkt << uint8(0x17);//unk
- *(uint16*)&pkt.contents()[1] = (pkt.size() - 3);
- SendBuf((char*)pkt.contents(), pkt.size());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement