private TimeSpan MeasurePartial(int iterations) { var elapsed = TimeSpan.Zero; for (var iteration = 0; iteration < iterations; ++iteration) { var length = 0; var algorithm = new NetAESEncryption(Peer); while (length++ < LoremIpsum.Length) { var substring = LoremIpsum.Substring(0, length); var outMessage = Peer.CreateMessage(); outMessage.Write(substring); var outBits = outMessage.LengthBits; var stopwatch = Stopwatch.StartNew(); var encryptSuccess = outMessage.Encrypt(algorithm); stopwatch.Stop(); elapsed += stopwatch.Elapsed; if (!encryptSuccess) { throw new Exception($"Failed to encrypt [length={length}]"); } var inMessage = outMessage.ToIncomingMessage(); if ((inMessage?.Data?.Length ?? -1) < 1) { throw new Exception("Incoming message empty."); } var decryptSuccess = inMessage.Decrypt(algorithm); if (!decryptSuccess) { throw new Exception($"Failed to decrypt"); } if ((inMessage?.Data?.Length ?? -1) < 1) { throw new Exception("Incoming message empty."); } if (outBits != inMessage.LengthBits) { throw new Exception($"Expected {outBits}b, received {inMessage.LengthBits}"); } var inText = inMessage.ReadString(); if (!string.Equals(substring, inText, StringComparison.Ordinal)) { throw new Exception($"Expected '{substring}' received '{inText}'."); } } } return(elapsed); }
static void Main(string[] args) { var config = new NetPeerConfiguration("enctest"); var client = new NetClient(config); client.Start(); System.Threading.Thread.Sleep(100); // give server time to start up client.Connect("localhost", 14242); var encryption = new NetAESEncryption(client, "Hallonpalt"); // loop forever while (true) { // read messages var inc = client.ReadMessage(); if (inc != null) { switch (inc.MessageType) { case NetIncomingMessageType.DebugMessage: case NetIncomingMessageType.WarningMessage: case NetIncomingMessageType.VerboseDebugMessage: case NetIncomingMessageType.ErrorMessage: Console.WriteLine(inc.ReadString()); break; case NetIncomingMessageType.StatusChanged: var status = (NetConnectionStatus)inc.ReadByte(); Console.WriteLine(inc.SenderConnection + " (" + status + ") " + inc.ReadString()); break; } } // if we're connected, get input and send if (client.ServerConnection != null && client.ServerConnection.Status == NetConnectionStatus.Connected) { Console.WriteLine("Type a message:"); var input = Console.ReadLine(); var msg = client.CreateMessage(); msg.Write(input); encryption.Encrypt(msg); var ok = client.SendMessage(msg, NetDeliveryMethod.ReliableOrdered); Console.WriteLine("Message sent: " + ok); } } }
private void CreateAes() { if (NetConnection == null) { throw new ArgumentNullException(); } if (mAesKey == null) { throw new ArgumentNullException(); } Aes = new NetAESEncryption(NetConnection.Peer, mAesKey, 0, mAesKey.Length); }
/// <summary> /// Loads this instance. /// </summary> public static void Load() { if (Loaded) { return; } RegisteredPackets = new List <Packet>(); BuiltInPackets = new List <Packet>(); ConnectedPlayers = new List <Obj_AI_Hero>(); try { var config = new NetPeerConfiguration(AppIdentifier); client = new NetClient(config); // Create encryption EncryptionAlgorithm = new NetAESEncryption(client, "NXKXrhFYtMNa"); // Bind to socket client.Start(); // Connect to server client.Connect(ServerIp, ServerPort); // Send Connect Packet var connectPacket = new ConnectPacket(client.CreateMessage()); connectPacket.Send(client); BuiltInPackets.AddRange( Assembly.GetAssembly(typeof(Live)) .GetTypes() .Where(x => x.IsClass && !x.IsAbstract && x.IsSubclassOf(typeof(Packet))) .Select(x => (Packet)DynamicInitializer.NewInstance(x))); Game.OnUpdate += Game_OnUpdate; Game.OnEnd += Game_OnEnd; AppDomain.CurrentDomain.DomainUnload += CurrentDomainDomainUnload; AppDomain.CurrentDomain.ProcessExit += CurrentDomainDomainUnload; Process.GetCurrentProcess().Exited += CurrentDomainDomainUnload; Loaded = true; } catch (Exception e) { Notifications.AddNotification("LeagueSharp.Live is down :'(", 5000); Loaded = false; Console.WriteLine("\nLeagueSharp.Live encountered an error trying to start.\n\n{0}", e); } }
/// <summary> /// MessagePipe /// </summary> public MessagePipe(NetPeer socket) { AesEncryption = new NetAESEncryption(socket, EncryptionKey); this.eventHandlers = new List <KeyValuePair <string, Func <string, NetConnection, NetPipeMessage, bool> > >(); // FIX for unity types not transcoding across messsage MessagePipe due to infinite references JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Formatting = Newtonsoft.Json.Formatting.None, // Indented is useful for debugging, turn off on production build ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Error, TypeNameHandling = TypeNameHandling.All }; }
static void Main(string[] args) { var config = new NetPeerConfiguration("enctest"); config.MaximumConnections = 1; config.Port = 14242; var server = new NetServer(config); server.Start(); var encryption = new NetAESEncryption(server, "Hallonpalt"); // loop forever while (true) { var inc = server.ReadMessage(); if (inc != null) { switch (inc.MessageType) { case NetIncomingMessageType.DebugMessage: case NetIncomingMessageType.WarningMessage: case NetIncomingMessageType.VerboseDebugMessage: case NetIncomingMessageType.ErrorMessage: Console.WriteLine(inc.ReadString()); break; case NetIncomingMessageType.StatusChanged: var status = (NetConnectionStatus)inc.ReadByte(); Console.WriteLine(inc.SenderConnection + " (" + status + ") " + inc.ReadString()); break; case NetIncomingMessageType.Data: var ok = inc.Decrypt(encryption); Console.WriteLine("Data (decrypted: " + (ok ? "ok" : "fail") + ") " + inc.ReadString()); break; } } System.Threading.Thread.Sleep(1); } }
public void TestPaddingBytes(bool forceNewTransform) { if (!forceNewTransform) { Assert.Ignore(); } var bytes = Encoding.UTF8.GetBytes(LoremIpsum); var length = 0; var algorithm = new NetAESEncryption(Peer) { ForceNewTransform = forceNewTransform }; while (length++ < bytes.Length) { var outMessage = Peer.CreateMessage(); outMessage.Write(bytes, 0, length); var outBits = outMessage.LengthBits; Assert.AreEqual(length << 3, outBits, $"Input data was {length}B ({length << 3}b), message is {outBits}b."); Assert.IsTrue(outMessage.Encrypt(algorithm), $"Failed to encrypt [length={length}]"); var inMessage = outMessage.ToIncomingMessage(); Assert.IsNotNull(inMessage.Data); Assert.IsNotEmpty(inMessage.Data); Assert.IsTrue(inMessage.Decrypt(algorithm), "Failed to decrypt"); Assert.IsNotNull(inMessage.Data); Assert.IsNotEmpty(inMessage.Data); Assert.AreEqual(outBits, inMessage.LengthBits); var inData = inMessage.PeekDataBuffer(); for (var index = 0; index < length; ++index) { Assert.AreEqual(bytes[index], inData[index], $"Arrays differed at index {index} (out of {length}).\nExpected: {BitConverter.ToString(bytes)}\nReceived: {BitConverter.ToString(inData)}"); } } }
public void TestPaddingText(bool forceNewTransform) { if (!forceNewTransform) { Assert.Ignore(); } var length = 0; var algorithm = new NetAESEncryption(Peer) { ForceNewTransform = forceNewTransform }; while (length++ < LoremIpsum.Length) { var substring = LoremIpsum.Substring(0, length); var outMessage = Peer.CreateMessage(); outMessage.Write(substring); var outBits = outMessage.LengthBits; var encryptSuccess = outMessage.Encrypt(algorithm); Assert.IsTrue(encryptSuccess, $"Failed to encrypt [length={length}]"); var inMessage = outMessage.ToIncomingMessage(); Assert.IsNotNull(inMessage.Data); Assert.IsNotEmpty(inMessage.Data); var decryptSuccess = inMessage.Decrypt(algorithm); Assert.IsTrue(decryptSuccess, "Failed to decrypt"); Assert.IsNotNull(inMessage.Data); Assert.IsNotEmpty(inMessage.Data); Assert.AreEqual(outBits, inMessage.LengthBits); var inText = inMessage.ReadString(); Assert.AreEqual(substring, inText, $"Expected '{substring}' received '{inText}'."); } }
private async void HandleHandshake(NetPeerData peer, NetConnection connection) { try { var incPacket = await AwaitData(connection); var msgLogin = new MsgLoginStart(); msgLogin.ReadFromBuffer(incPacket); var ip = connection.RemoteEndPoint.Address; var isLocal = IPAddress.IsLoopback(ip) && _config.GetCVar(CVars.AuthAllowLocal); var canAuth = msgLogin.CanAuth; var needPk = msgLogin.NeedPubKey; var authServer = _config.GetSecureCVar <string>("auth.server"); if (Auth == AuthMode.Required && !isLocal) { if (!canAuth) { connection.Disconnect("Connecting to this server requires authentication"); return; } } NetEncryption?encryption = null; NetUserId userId; string userName; LoginType type; var padSuccessMessage = true; if (canAuth && Auth != AuthMode.Disabled) { var verifyToken = new byte[4]; RandomNumberGenerator.Fill(verifyToken); var msgEncReq = new MsgEncryptionRequest { PublicKey = needPk ? RsaPublicKey : Array.Empty <byte>(), VerifyToken = verifyToken }; var outMsgEncReq = peer.Peer.CreateMessage(); outMsgEncReq.Write(false); outMsgEncReq.WritePadBits(); msgEncReq.WriteToBuffer(outMsgEncReq); peer.Peer.SendMessage(outMsgEncReq, connection, NetDeliveryMethod.ReliableOrdered); incPacket = await AwaitData(connection); var msgEncResponse = new MsgEncryptionResponse(); msgEncResponse.ReadFromBuffer(incPacket); byte[] verifyTokenCheck; byte[] sharedSecret; try { verifyTokenCheck = _authRsaPrivateKey !.Decrypt( msgEncResponse.VerifyToken, RSAEncryptionPadding.OaepSHA256); sharedSecret = _authRsaPrivateKey !.Decrypt( msgEncResponse.SharedSecret, RSAEncryptionPadding.OaepSHA256); } catch (CryptographicException) { // Launcher gives the client the public RSA key of the server BUT // that doesn't persist if the server restarts. // In that case, the decrypt can fail here. connection.Disconnect("Token decryption failed./nPlease reconnect to this server from the launcher."); return; } if (!verifyToken.SequenceEqual(verifyTokenCheck)) { connection.Disconnect("Verify token is invalid"); return; } encryption = new NetAESEncryption(peer.Peer, sharedSecret, 0, sharedSecret.Length); var authHashBytes = MakeAuthHash(sharedSecret, RsaPublicKey !); var authHash = Base64Helpers.ConvertToBase64Url(authHashBytes); var client = new HttpClient(); var url = $"{authServer}api/session/hasJoined?hash={authHash}&userId={msgEncResponse.UserId}"; var joinedResp = await client.GetAsync(url); joinedResp.EnsureSuccessStatusCode(); var joinedRespJson = JsonConvert.DeserializeObject <HasJoinedResponse>( await joinedResp.Content.ReadAsStringAsync()); if (!joinedRespJson.IsValid) { connection.Disconnect("Failed to validate login"); return; } userId = new NetUserId(joinedRespJson.UserData !.UserId); userName = joinedRespJson.UserData.UserName; padSuccessMessage = false; type = LoginType.LoggedIn; } else { var reqUserName = msgLogin.UserName; if (!UsernameHelpers.IsNameValid(reqUserName, out var reason)) { connection.Disconnect($"Username is invalid ({reason.ToText()})."); return; } // If auth is set to "optional" we need to avoid conflicts between real accounts and guests, // so we explicitly prefix guests. var origName = Auth == AuthMode.Disabled ? reqUserName : (isLocal ? $"localhost@{reqUserName}" : $"guest@{reqUserName}"); var name = origName; var iterations = 1; while (_assignedUsernames.ContainsKey(name)) { // This is shit but I don't care. name = $"{origName}_{++iterations}"; } userName = name; (userId, type) = await AssignUserIdAsync(name); } var endPoint = connection.RemoteEndPoint; var connect = await OnConnecting(endPoint, userId, userName, type); if (connect.IsDenied) { connection.Disconnect($"Connection denied: {connect.DenyReason}"); return; } // Well they're in. Kick a connected client with the same GUID if we have to. if (_assignedUserIds.TryGetValue(userId, out var existing)) { existing.Disconnect("Another connection has been made with your account."); // Have to wait until they're properly off the server to avoid any collisions. await AwaitDisconnectAsync(existing); } var msg = peer.Peer.CreateMessage(); var msgResp = new MsgLoginSuccess { UserId = userId.UserId, UserName = userName, Type = type }; if (padSuccessMessage) { msg.Write(true); msg.WritePadBits(); } msgResp.WriteToBuffer(msg); encryption?.Encrypt(msg); peer.Peer.SendMessage(msg, connection, NetDeliveryMethod.ReliableOrdered); Logger.InfoS("net", "Approved {ConnectionEndpoint} with username {Username} user ID {userId} into the server", connection.RemoteEndPoint, userName, userId); // Handshake complete! HandleInitialHandshakeComplete(peer, connection, userId, userName, encryption, type); } catch (ClientDisconnectedException) { Logger.InfoS("net", $"Peer {NetUtility.ToHexString(connection.RemoteUniqueIdentifier)} disconnected while handshake was in-progress."); } catch (Exception e) { connection.Disconnect("Unknown server error occured during handshake."); Logger.ErrorS("net", "Exception during handshake with peer {0}:\n{1}", NetUtility.ToHexString(connection.RemoteUniqueIdentifier), e); } }
private async void HandleHandshake(NetPeerData peer, NetConnection connection) { try { var incPacket = await AwaitData(connection); var msgLogin = new MsgLoginStart(); msgLogin.ReadFromBuffer(incPacket); var ip = connection.RemoteEndPoint.Address; var isLocal = IPAddress.IsLoopback(ip) && _config.GetCVar(CVars.AuthAllowLocal); var canAuth = msgLogin.CanAuth; var needPk = msgLogin.NeedPubKey; var authServer = _config.GetCVar(CVars.AuthServer); if (Auth == AuthMode.Required && !isLocal) { if (!canAuth) { connection.Disconnect("Connecting to this server requires authentication"); return; } } NetEncryption?encryption = null; NetUserData userData; LoginType type; var padSuccessMessage = true; if (canAuth && Auth != AuthMode.Disabled) { var verifyToken = new byte[4]; RandomNumberGenerator.Fill(verifyToken); var msgEncReq = new MsgEncryptionRequest { PublicKey = needPk ? RsaPublicKey : Array.Empty <byte>(), VerifyToken = verifyToken }; var outMsgEncReq = peer.Peer.CreateMessage(); outMsgEncReq.Write(false); outMsgEncReq.WritePadBits(); msgEncReq.WriteToBuffer(outMsgEncReq); peer.Peer.SendMessage(outMsgEncReq, connection, NetDeliveryMethod.ReliableOrdered); incPacket = await AwaitData(connection); var msgEncResponse = new MsgEncryptionResponse(); msgEncResponse.ReadFromBuffer(incPacket); byte[] verifyTokenCheck; byte[] sharedSecret; try { verifyTokenCheck = _authRsaPrivateKey !.Decrypt( msgEncResponse.VerifyToken, RSAEncryptionPadding.OaepSHA256); sharedSecret = _authRsaPrivateKey !.Decrypt( msgEncResponse.SharedSecret, RSAEncryptionPadding.OaepSHA256); } catch (CryptographicException) { // Launcher gives the client the public RSA key of the server BUT // that doesn't persist if the server restarts. // In that case, the decrypt can fail here. connection.Disconnect( "Token decryption failed.\nPlease reconnect to this server from the launcher."); return; } if (!verifyToken.SequenceEqual(verifyTokenCheck)) { connection.Disconnect("Verify token is invalid"); return; } if (msgLogin.Encrypt) { encryption = new NetAESEncryption(peer.Peer, sharedSecret, 0, sharedSecret.Length); } var authHashBytes = MakeAuthHash(sharedSecret, RsaPublicKey !); var authHash = Base64Helpers.ConvertToBase64Url(authHashBytes); var client = new HttpClient(); var url = $"{authServer}api/session/hasJoined?hash={authHash}&userId={msgEncResponse.UserId}"; var joinedRespJson = await client.GetFromJsonAsync <HasJoinedResponse>(url); if (joinedRespJson is not { IsValid : true }) { connection.Disconnect("Failed to validate login"); return; } var userId = new NetUserId(joinedRespJson.UserData !.UserId); userData = new NetUserData(userId, joinedRespJson.UserData.UserName) { PatronTier = joinedRespJson.UserData.PatronTier, HWId = msgLogin.HWId }; padSuccessMessage = false; type = LoginType.LoggedIn; }