Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
        private void CreateAes()
        {
            if (NetConnection == null)
            {
                throw new ArgumentNullException();
            }

            if (mAesKey == null)
            {
                throw new ArgumentNullException();
            }

            Aes = new NetAESEncryption(NetConnection.Peer, mAesKey, 0, mAesKey.Length);
        }
Esempio n. 4
0
        /// <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);
            }
        }
Esempio n. 5
0
        /// <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
            };
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
        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)}");
                }
            }
        }
Esempio n. 8
0
        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;
                }