public bool Negotiate() { DataBuffer init = new DataBuffer(); init.InsertByte(4); init.InsertByte(1); byte[] port = BitConverter.GetBytes(m_profile.Gateway.ServerPort); init.InsertByte(port[1]); init.InsertByte(port[0]); init.InsertByteArray(m_con.ResolveEndPoint(m_profile.Gateway.ServerHost, m_profile.Gateway.ServerPort).Address.GetAddressBytes()); init.InsertCString("*****@*****.**"); m_con.Send(init.UnderlyingBuffer, 0, init.Count); byte[] result = new byte[8]; result = m_con.Receive(result, 0, 8); return result[1] == 0x5a; }
internal void Send(DataBuffer packet) { Send(packet.UnderlyingBuffer, 0, packet.Count); BattleNetClientResources.OutgoingBufferPool.FreeBuffer(packet.UnderlyingBuffer); }
public override void ExecuteRequest() { DataBuffer buf1 = new DataBuffer(); buf1.InsertInt16(20); buf1.InsertInt16(0x0200); buf1.InsertDwordString("IX86"); buf1.InsertDwordString(Product); if (m_ad) { buf1.InsertInt32(m_adId); buf1.InsertDwordString(m_adExt); } else { buf1.InsertInt64(0); } Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sck.Connect(Server, 6112); sck.Send(new byte[] { 2 }); sck.Send(buf1.UnderlyingBuffer, 0, buf1.Count, SocketFlags.None); NetworkStream ns = new NetworkStream(sck, false); DataReader rdr = new DataReader(ns, 4); int serverToken = rdr.ReadInt32(); DataBuffer buf2 = new DataBuffer(); buf2.InsertInt32(0); // no resuming if (FileTime.HasValue) { buf2.InsertInt64(FileTime.Value.ToFileTimeUtc()); } else { buf2.InsertInt64(0); } int clientToken = new Random().Next(); buf2.InsertInt32(clientToken); buf2.InsertInt32(m_key.Key.Length); buf2.InsertInt32(m_key.Product); buf2.InsertInt32(m_key.Value1); buf2.InsertInt32(0); buf2.InsertByteArray(m_key.GetHash(clientToken, serverToken)); buf2.InsertCString(FileName); sck.Send(buf2.UnderlyingBuffer, 0, buf2.Count, SocketFlags.None); rdr = new DataReader(ns, 4); int msg2Size = rdr.ReadInt32() - 4; rdr = new DataReader(ns, msg2Size); this.FileSize = rdr.ReadInt32(); rdr.Seek(8); long fileTime = rdr.ReadInt64(); DateTime time = DateTime.FromFileTimeUtc(fileTime); string name = rdr.ReadCString(); if (string.Compare(name, FileName, StringComparison.OrdinalIgnoreCase) != 0 || FileSize == 0) { throw new FileNotFoundException(Resources.bnftp_filenotfound); } byte[] data = ReceiveLoop(sck, FileSize); sck.Close(); FileStream fs = new FileStream(LocalFileName, FileMode.OpenOrCreate, FileAccess.Write); fs.Write(data, 0, FileSize); fs.Flush(); fs.Close(); }
/// <summary> /// Executes the BnFTP request, downloading the file to where <see cref="BnFtpRequestBase.LocalFileName">LocalFileName</see> /// specifies, and closes the connection. /// </summary> /// <remarks> /// <para>By default, <c>LocalFileName</c> is the same name as the remote file, which will cause the file /// to be saved in the local application path. The desired location of the file must be set before /// <b>ExecuteRequest</b> is called.</para> /// </remarks> /// <exception cref="IOException">Thrown if the local file cannot be written.</exception> /// <exception cref="SocketException">Thrown if the remote host closes the connection prematurely.</exception> public override void ExecuteRequest() { DataBuffer buffer = new DataBuffer(); buffer.InsertInt16((short)(33 + FileName.Length)); buffer.InsertInt16(0x0100); buffer.InsertDwordString("IX86"); buffer.InsertDwordString(Product); if (m_ad) { buffer.InsertInt32(m_adId); buffer.InsertDwordString(m_adExt); } else { buffer.InsertInt64(0); } // currently resuming is not supported buffer.InsertInt32(0); if (FileTime.HasValue) { buffer.InsertInt64(FileTime.Value.ToFileTimeUtc()); } else { buffer.InsertInt64(0); } buffer.InsertCString(FileName); Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sck.Connect(Server, 6112); sck.Send(new byte[] { 2 }); sck.Send(buffer.UnderlyingBuffer, 0, buffer.Count, SocketFlags.None); BattleNetClientResources.OutgoingBufferPool.FreeBuffer(buffer.UnderlyingBuffer); byte[] hdrLengthBytes = new byte[2]; sck.Receive(hdrLengthBytes, 2, SocketFlags.None); int hdrLen = BitConverter.ToInt16(hdrLengthBytes, 0); Debug.WriteLine(hdrLen, "Header Length"); byte[] hdrBytes = new byte[hdrLen - 2]; sck.Receive(hdrBytes, hdrLen - 2, SocketFlags.None); DataReader rdr = new DataReader(hdrBytes); rdr.Seek(2); int fileSize = rdr.ReadInt32(); this.FileSize = fileSize; rdr.Seek(8); long fileTime = rdr.ReadInt64(); string name = rdr.ReadCString(); if (string.Compare(name, FileName, StringComparison.OrdinalIgnoreCase) != 0 || FileSize == 0) { throw new FileNotFoundException(Resources.bnftp_filenotfound); } Debug.WriteLine(fileSize, "File Size"); byte[] data = ReceiveLoop(sck, fileSize); sck.Close(); FileStream fs = new FileStream(LocalFileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); fs.SetLength(fileSize); fs.Write(data, 0, fileSize); fs.Flush(); fs.Close(); DateTime time = DateTime.FromFileTimeUtc(fileTime); File.SetLastWriteTimeUtc(LocalFileName, time); }
/// <summary> /// Adds the account login proof (for SID_AUTH_ACCOUNTLOGONPROOF) /// to the specified packet. /// </summary> /// <param name="logonProofPacket">The BNCS packet to which to add the account logon data.</param> /// <param name="serverSalt">The salt value, sent from the server /// in SID_AUTH_ACCOUNTLOGON.</param> /// <param name="serverKey">The server key, sent from the server /// in SID_AUTH_ACCOUNTLOGON.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown if /// the salt or server key values are not exactly 32 bytes.</exception> /// <exception cref="InvalidOperationException">Thrown if the object has not /// yet been initialized.</exception> /// <remarks> /// <para>This method should be called after the <see cref="LoginAccount(DataBuffer)">LoginAccount</see> method.</para> /// </remarks> /// <returns>The total number of bytes written to the buffer.</returns> public int LoginProof(DataBuffer logonProofPacket, byte[] serverSalt, byte[] serverKey) { byte[] temp = new byte[20]; int len = LoginProof(temp, 0, 20, serverSalt, serverKey); logonProofPacket.Insert(temp); return len; }
/// <summary> /// Adds the account login information (for SID_AUTH_ACCOUNTLOGON) /// to the specified packet. /// </summary> /// <param name="loginPacket">The packet to which to add the login information.</param> /// <exception cref="InvalidOperationException">Thrown if the object has not /// yet been initialized.</exception> /// <remarks> /// <para>This method may be called first after creating the instance, or after the /// <see cref="CreateAccount(DataBuffer)">CreateAccount</see> method.</para> /// </remarks> /// <returns>The total number of bytes written to the buffer.</returns> public int LoginAccount(DataBuffer loginPacket) { byte[] temp = new byte[33 + userNameAscii.Length]; int len = LoginAccount(temp, 0, temp.Length); loginPacket.Insert(temp); return len; }
/// <summary> /// Adds the account creation information (for SID_AUTH_ACCOUNTCREATE) /// to the specified packet. /// </summary> /// <param name="acctPacket">The packet to which to add the account creation information.</param> /// <exception cref="InvalidOperationException">Thrown if the object has not /// yet been initialized.</exception> /// <remarks> /// <para>This method must be called first if you are creating a new account.</para> /// </remarks> /// <returns>The total number of bytes written to the buffer.</returns> public int CreateAccount(DataBuffer acctPacket) { byte[] temp = new byte[65 + userName.Length]; int len = CreateAccount(temp, 0, temp.Length); acctPacket.InsertByteArray(temp); return len; }
private void Send(DataBuffer buf) { m_connection.Send(buf); }
private void HandleAuthInfo(ParseData data) { try { DataReader dr = new DataReader(data.Data); if (m_pingPck != null) { Send(m_pingPck); m_pingPck = null; } m_received0x50 = true; m_loginType = dr.ReadUInt32(); m_srvToken = dr.ReadUInt32(); m_udpVal = dr.ReadUInt32(); m_mpqFiletime = dr.ReadInt64(); m_versioningFilename = dr.ReadCString(); m_usingLockdown = m_versioningFilename.StartsWith("LOCKDOWN", StringComparison.OrdinalIgnoreCase); int crResult = -1, exeVer = -1; string exeInfo = null; if (!m_usingLockdown) { m_valString = dr.ReadCString(); int mpqNum = CheckRevision.ExtractMPQNumber(m_versioningFilename); crResult = CheckRevision.DoCheckRevision(m_valString, new string[] { m_settings.GameExe, m_settings.GameFile2, m_settings.GameFile3 }, mpqNum); exeVer = CheckRevision.GetExeInfo(m_settings.GameExe, out exeInfo); } else { m_ldValStr = dr.ReadNullTerminatedByteArray(); string dllName = m_versioningFilename.Replace(".mpq", ".dll"); BnFtpVersion1Request req = new BnFtpVersion1Request(m_settings.Client, m_versioningFilename, null); req.Server = m_settings.Gateway.ServerHost; req.LocalFileName = Path.Combine(Path.GetTempPath(), m_versioningFilename); req.ExecuteRequest(); string ldPath = null; using (MpqArchive arch = MpqServices.OpenArchive(req.LocalFileName)) { if (arch.ContainsFile(dllName)) { ldPath = Path.Combine(Path.GetTempPath(), dllName); arch.SaveToPath(dllName, Path.GetTempPath(), false); } } m_ldDigest = CheckRevision.DoLockdownCheckRevision(m_ldValStr, new string[] { m_settings.GameExe, m_settings.GameFile2, m_settings.GameFile3 }, ldPath, m_settings.ImageFile, ref exeVer, ref crResult); } m_prodCode = m_settings.Client; if (m_prodCode == "WAR3" || m_prodCode == "W3XP") { m_w3srv = dr.ReadByteArray(128); if (!NLS.ValidateServerSignature(m_w3srv, RemoteEP.Address.GetAddressBytes())) { OnError(new ErrorEventArgs(ErrorType.Warcraft3ServerValidationFailure, Strings.War3ServerValidationFailed, false)); //Close(); //return; } } BattleNetClientResources.IncomingBufferPool.FreeBuffer(data.Data); CdKey key1, key2 = null; key1 = new CdKey(m_settings.CdKey1); if (m_prodCode == "D2XP" || m_prodCode == "W3XP") { key2 = new CdKey(m_settings.CdKey2); } m_clientToken = unchecked((uint)new Random().Next()); byte[] key1Hash = key1.GetHash(m_clientToken, m_srvToken); if (m_warden != null) { try { if (!m_warden.InitWarden(BitConverter.ToInt32(key1Hash, 0))) { m_warden.UninitWarden(); OnError(new ErrorEventArgs(ErrorType.WardenModuleFailure, "The Warden module failed to initialize. You will not be immediately disconnected; however, you may be disconnected after a short period of time.", false)); m_warden = null; } } catch (Win32Exception we) { OnError(new ErrorEventArgs(ErrorType.WardenModuleFailure, "The Warden module failed to initialize. You will not be immediately disconnected; however, you may be disconnected after a short period of time.", false)); OnError(new ErrorEventArgs(ErrorType.WardenModuleFailure, string.Format(CultureInfo.CurrentCulture, "Additional information: {0}", we.Message), false)); m_warden.UninitWarden(); m_warden = null; } } BncsPacket pck0x51 = new BncsPacket((byte)BncsPacketId.AuthCheck); pck0x51.Insert(m_clientToken); pck0x51.Insert(exeVer); pck0x51.Insert(crResult); if (m_prodCode == "D2XP" || m_prodCode == "W3XP") pck0x51.Insert(2); else pck0x51.Insert(1); pck0x51.Insert(false); pck0x51.Insert(key1.Key.Length); pck0x51.Insert(key1.Product); pck0x51.Insert(key1.Value1); pck0x51.Insert(0); pck0x51.Insert(key1Hash); if (key2 != null) { pck0x51.Insert(key2.Key.Length); pck0x51.Insert(key2.Product); pck0x51.Insert(key2.Value1); pck0x51.Insert(0); pck0x51.Insert(key2.GetHash(m_clientToken, m_srvToken)); } if (m_usingLockdown) { pck0x51.InsertByteArray(m_ldDigest); pck0x51.InsertByte(0); } else pck0x51.InsertCString(exeInfo); pck0x51.InsertCString(m_settings.CdKeyOwner); Send(pck0x51); } catch (Exception ex) { OnError(new ErrorEventArgs(ErrorType.General, "There was an error while initializing your client. Refer to the exception message for more information.\n" + ex.ToString(), true)); Close(); } }
private void HandlePing(ParseData data) { DataReader dr = new DataReader(data.Data); BncsPacket pck0x25 = new BncsPacket((byte)BncsPacketId.Ping); pck0x25.Insert(dr.ReadUInt32()); if (Settings.PingMethod == PingType.Normal) { Send(pck0x25); m_pingPck = null; } BattleNetClientResources.IncomingBufferPool.FreeBuffer(data.Data); }
private void ResetConnectionState() { m_adTmr.Stop(); m_tmr.Stop(); m_news.Clear(); m_channelName = null; m_firstChannelList = false; m_received0x50 = false; if (m_pingPck != null) { BattleNetClientResources.OutgoingBufferPool.FreeBuffer(m_pingPck.UnderlyingBuffer); m_pingPck = null; } m_loginType = m_srvToken = m_udpVal = m_clientToken = 0; m_mpqFiletime = 0; m_versioningFilename = null; m_prodCode = null; m_usingLockdown = false; if (m_warden != null) { m_warden.UninitWarden(); m_warden = null; } m_ldDigest = null; m_ldValStr = null; m_uniqueUN = null; m_w3srv = null; m_valString = null; m_closing = false; ResetFriendsState(); ResetClanState(); m_warcraftProfileRequests.Clear(); }