private static void DoClientAuth(object stateo) { var state = (ClientAuthstate)stateo; // obtain key auth try { var npticket = DWTickets.ParseNPTicket(state.Ticket); // /validate/:token/:ip/:server/:username var url = "http://127.0.0.1:6378/validate/" + npticket.SessionID + "/0/false/" + npticket.NickName; //var url = "http://server.repziw4.de/check_session.php?sid=" + npticket.SessionID; var wc = new WebClient(); var webString = wc.DownloadString(url); var authData = webString.Split(' '); Log.Debug(webString); Log.Debug(authData[0]); if (authData[0] == "1") { var userID = int.Parse(authData[1]); if ((uint)(npticket.SteamID & 0xFFFFFFFF) == userID) { var ivBase = BitConverter.ToUInt32(DWCrypto.GenerateRandom(4), 0); var iv = DWCrypto.CalculateInitialVector(ivBase); var key = npticket.EncryptionKey; var globalKey = DWCrypto.GenerateRandom(24); var gameTicket = DWTickets.BuildGameTicket(globalKey, state.GameID, npticket.NickName, 0); var lsgTicket = DWTickets.BuildLSGTicket(globalKey, npticket.SteamID, userID, npticket.NickName); var encryptedGameTicket = DWCrypto.Encrypt(iv, key, gameTicket); var reply = state.Packet.MakeReply(29, true); reply.BitBuffer.UseDataTypes = false; reply.BitBuffer.WriteBoolean(false); reply.BitBuffer.WriteUInt32(700); reply.BitBuffer.WriteUInt32(ivBase); reply.BitBuffer.WriteBytes(encryptedGameTicket); reply.BitBuffer.WriteBytes(lsgTicket); reply.Send(false); Log.Debug("user " + userID + " authenticated client: " + state.Source + ""); return; } } wc.Dispose(); } catch (Exception e) { Log.Debug("Exception: " + e.ToString()); } }
private static void DoServerAuth(object stateo) { var state = (ServerAuthstate)stateo; // obtain key auth try { // /validate/:token/:ip/:server/:username //var url = "http://server.repziw4.de/check_key.php?key=" + state.KeyData.ToString("x16"); var url = "http://127.0.0.1:6378/validate/" + state.KeyData.ToString("x16") + "/0/true/0"; var wc = new WebClient(); var resultData = wc.DownloadString(url); var authData = resultData.Split(' '); if (authData[0] == "1") { var licenseType = int.Parse(authData[1]); var userID = int.Parse(authData[3]); var key = Extensions.SwapBytes64(Extensions.ParseHexString(authData[2])); // generate iv var ivBase = BitConverter.ToUInt32(DWCrypto.GenerateRandom(4), 0); var iv = DWCrypto.CalculateInitialVector(ivBase); // blah var globalKey = DWCrypto.GenerateRandom(24); var gameTicket = DWTickets.BuildGameTicket(globalKey, state.GameID, "", (byte)licenseType); // 4: official var lsgTicket = DWTickets.BuildLSGTicket(globalKey, state.KeyData, userID, ""); var encryptedGameTicket = DWCrypto.Encrypt(iv, key, gameTicket); var reply = state.Packet.MakeReply(13, true); reply.BitBuffer.UseDataTypes = false; reply.BitBuffer.WriteBoolean(false); reply.BitBuffer.WriteUInt32(700); reply.BitBuffer.WriteUInt32(ivBase); reply.BitBuffer.WriteBytes(encryptedGameTicket); reply.BitBuffer.WriteBytes(lsgTicket); reply.Send(false); Log.Debug("user " + userID + " authenticated server"); return; } } catch (Exception e) { Log.Debug("Exception: " + e.ToString()); } }
private static void DoIW5ServerAuth(object stateo) { var state = (ServerAuthstate)stateo; // obtain key auth try { var query = Query.EQ("keyHash", (long)state.KeyData); var result = Database.AServerKeys.Find(query); if (result.Count() > 0) { var keyEntry = result.First(); var keyString = keyEntry.key; var thash = new TigerHash(); var key = thash.ComputeHash(Encoding.ASCII.GetBytes(keyString)); // generate iv var ivBase = BitConverter.ToUInt32(DWCrypto.GenerateRandom(4), 0); var iv = DWCrypto.CalculateInitialVector(ivBase); // blah var globalKey = DWCrypto.GenerateRandom(24); var gameTicket = DWTickets.BuildGameTicket(globalKey, state.GameID, "", 0); // 4: official var lsgTicket = DWTickets.BuildLSGTicket(globalKey, state.KeyData, 1, ""); var encryptedGameTicket = DWCrypto.Encrypt(iv, key, gameTicket); var reply = state.Packet.MakeReply(13, true); reply.BitBuffer.UseDataTypes = false; reply.BitBuffer.WriteBoolean(false); reply.BitBuffer.WriteUInt32(700); reply.BitBuffer.WriteUInt32(ivBase); reply.BitBuffer.WriteBytes(encryptedGameTicket); reply.BitBuffer.WriteBytes(lsgTicket); reply.Send(false); return; } } catch (Exception e) { Log.Debug("Exception: " + e.ToString()); } }
public void Send(bool encrypted) { var buffer = (BitBuffer != null) ? BitBuffer.Bytes : ByteBuffer.Bytes; byte[] array = null; if (!encrypted) { array = new byte[buffer.Length + 6]; Array.Copy(BitConverter.GetBytes(buffer.Length + 2), 0, array, 0, 4); array[4] = 0; array[5] = (byte)Data.Get <int>("type"); Array.Copy(buffer, 0, array, 6, buffer.Length); } else { array = new byte[buffer.Length + 4 + 4 + 1]; Array.Copy(BitConverter.GetBytes(buffer.Length + 5), 0, array, 0, 4); array[4] = 1; Array.Copy(BitConverter.GetBytes(0x13371337), 0, array, 5, 4); var iv = DWCrypto.CalculateInitialVector(0x13371337); var key = DWRouter.GetGlobalKey(Data); var crypted = DWCrypto.Encrypt(iv, key, buffer); Array.Resize(ref array, crypted.Length + 4 + 4 + 1); Array.Copy(BitConverter.GetBytes(array.Length - 4), 0, array, 0, 4); Array.Copy(crypted, 0, array, 9, crypted.Length); } //Log.Debug("sending a reply"); Data.Arguments["handled"] = true; MessageData message = new MessageData("none"); message["data"] = array; message["cid"] = Data["cid"]; TCPHandler.Net_TcpSend(message); }
public void handlePacket(MessageData data) { var buffer = data.Get <byte[]>("data"); var source = data.Get <EndPoint>("source"); var stream = new MemoryStream(buffer); var reader = new BinaryReader(stream); var time = data.Get <DateTime>("time"); var delay = (DateTime.Now - time).TotalMilliseconds; var delay2 = DateTime.Now; try { while (stream.Position < stream.Length) { var origin = 0; var len = 0; if (_bytesRead == 0) { _totalBytes = 0; try { _totalBytes = reader.ReadInt32(); } catch { _totalBytes = 0; } //Log.Info("GOT A PACKET OF SIZE " + _totalBytes.ToString("X")); if (_totalBytes == 0xC8) { _totalBytes = 0; break; } if (_totalBytes > (256 * 1024)) { Log.Error("LENGTH IS XBOX"); break; } if (_totalBytes == 0 || _totalBytes < 0) { //TCPHandler.sendPacket(message, client); MessageData packet = new MessageData("none"); packet["data"] = new byte[4]; packet["cid"] = data.Get <string>("cid"); TCPHandler.Net_TcpSend(packet); continue; } _messageBuffer = new MemoryStream(); origin += 4; len -= 4; } len += Math.Min((buffer.Length - (int)stream.Position), (_totalBytes - _bytesRead)); var newBytes = reader.ReadBytes(len); _messageBuffer.Write(newBytes, 0, len); _bytesRead += len; if (_bytesRead > _totalBytes) { //Debugger.Break(); } if (_bytesRead >= _totalBytes) { _bytesRead = 0; _messageBuffer.Position = 0; var breader = new BinaryReader(_messageBuffer); _totalBytes--; var pdtype = breader.ReadByte(); var encrypted = (pdtype == 1); // can be 0, 1 and 0xFF var ptype = 0xFF; byte[] pdata = null; if (pdtype == 0xFF) { // TODO: handle this one Log.Debug("Got a 0xFF pdtype!"); //return; continue; } var initTime = DateTime.Now; if (!encrypted) { ptype = breader.ReadByte(); _totalBytes -= 1; pdata = breader.ReadBytes(_totalBytes); } else { try { var key = GetGlobalKey(data); var iv = DWCrypto.CalculateInitialVector(breader.ReadUInt32()); var edata = breader.ReadBytes(_totalBytes - 4); var ddata = DWCrypto.Decrypt(iv, key, edata); var dstream = new MemoryStream(ddata); var dreader = new BinaryReader(dstream); // TODO: find out why this hash isn't just truncated SHA-1 var hash = dreader.ReadUInt32(); ptype = dreader.ReadByte(); pdata = dreader.ReadBytes((int)(dstream.Length - 5)); dreader.Close(); dstream.Close(); } catch { } } var initTime2 = DateTime.Now; var delay3 = (DateTime.Now - delay2).TotalMilliseconds; //Log.Debug("Received a " + _totalBytes + " byte packet (type " + ptype + ") from DemonWare - delay " + delay + "ms. delay after reading " + delay3 + "ms."); /* * var message = Messages.NewMessage("dw.packet-received"); * message["data"] = pdata; * message["type"] = ptype; * message["crypt"] = encrypted; * message["source"] = source; * message["cid"] = data["cid"]; * message["delay"] = delay; * message["time"] = DateTime.Now; * message.SendNow(); */ MessageData message = new MessageData("none"); message["data"] = pdata; message["type"] = ptype; message["crypt"] = encrypted; message["source"] = source; message["cid"] = data["cid"]; message["ci"] = data["ci"]; message["delay"] = delay; message["time"] = DateTime.Now; redirectPacket(message); /*var msec = (int)((DateTime.Now - initTime).TotalMilliseconds); * var state = GetPerfState(ptype); * state.Add(msec); * * msec = (int)((DateTime.Now - initTime2).TotalMilliseconds); * var state2 = GetPerfState(ptype + 1000); * state2.Add(msec); * * Log.Debug("service " + ptype + " min " + state.Min + "/" + state2.Min + " max " + state.Max + "/" + state2.Max);*/ } } } catch (Exception ex) { Log.Error(ex.ToString()); // disconnect to prevent further pollution of system TCPHandler.ForceDisconnect(data); } reader.Close(); }
private static void CreateIW5ServerKey(object stateo) { var state = (IW5ServerAuthstate)stateo; // obtain key auth try { Log.Debug("got a request for a new IW5 dedi key; seems fun to me"); // actually the advanced RSA stuff should be used but that might be incompatible with the .NET implementation of RSA var passGen = new PasswordGenerator(); passGen.Maximum = 20; passGen.Minimum = 20; var key = passGen.Generate(); key = string.Format("X{0}-{1}-{2}-{3}-{4}", key.Substring(1, 3), key.Substring(4, 4), key.Substring(8, 4), key.Substring(12, 4), key.Substring(16, 4)); var thash = new TigerHash(); var hash = thash.ComputeHash(Encoding.ASCII.GetBytes(key)); var keyHash = BitConverter.ToInt64(hash, 0); var keyEntry = new ServerKey(); keyEntry.key = key; keyEntry.keyHash = keyHash; keyEntry.unkInt = new Random().Next(); Database.AServerKeys.Save(keyEntry); var keyStuff = new byte[86]; Array.Copy(Encoding.ASCII.GetBytes(key), keyStuff, key.Length); var obfuscationKey = "43FCB2ACF2D72593DD7CD1C69E0F03C07229F4C83166F7B05BA0C5FE3AA3A2D93EK2495783KDKN92939DK"; var i = 0; foreach (var character in obfuscationKey) { keyStuff[i] ^= (byte)character; i++; } // generate iv var ivBase = BitConverter.ToUInt32(DWCrypto.GenerateRandom(4), 0); var iv = DWCrypto.CalculateInitialVector(ivBase); // blah var globalKey = DWCrypto.GenerateRandom(24); var gameTicket = DWTickets.BuildGameTicket(globalKey, state.GameID, "", (byte)0); // 4: official var lsgTicket = DWTickets.BuildLSGTicket(globalKey, (ulong)keyHash, 1, ""); var encryptedGameTicket = DWCrypto.Encrypt(iv, hash, gameTicket); var reply = state.Packet.MakeReply(25, true); reply.BitBuffer.UseDataTypes = false; reply.BitBuffer.WriteBoolean(false); reply.BitBuffer.WriteUInt32(700); reply.BitBuffer.WriteUInt32(ivBase); reply.BitBuffer.WriteBytes(encryptedGameTicket); reply.BitBuffer.WriteBytes(lsgTicket); reply.BitBuffer.WriteBytes(keyStuff); reply.BitBuffer.WriteInt32(keyEntry.unkInt); reply.Send(false); } catch (Exception e) { Log.Debug("Exception: " + e.ToString()); } }