Exemple #1
0
 private async Task Process(EncryptStringRequest args)
 {
     SendCommand(new EncryptStringDone()
     {
         StringToEncrypt = args.StringToEncrypt, EncryptedString = RsaSignatures.Encrypt(args.StringToEncrypt, args.ServerPubKey)
     });
 }
Exemple #2
0
 private async Task Process(SignStringRequest args)
 {
     SendCommand(new SignStringDone()
     {
         StringToSign = args.StringToSign, SignedString = RsaSignatures.Sign(args.StringToSign, args.PrivKey)
     });
 }
        public void TestRsaSignatures()
        {
            var keys = RsaSignatures.GenerateKeys();

            Assert.AreNotEqual(keys.PrivKey, keys.PubKey);

            Assert.IsTrue(keys.PubKey.Length < keys.PrivKey.Length);

            var dataToSign = "some super secret data we need to sign";

            var signature = RsaSignatures.Sign(dataToSign, keys.PrivKey);


            var resultOk = RsaSignatures.VerifySignature(dataToSign, signature, keys.PubKey);

            Assert.AreEqual(true, resultOk);


            var resultFail = RsaSignatures.VerifySignature(dataToSign + "modify", signature, keys.PubKey);

            Assert.AreEqual(false, resultFail);


            var dataToEncrypt = "some super secret data we need to encrypt";

            var encrypted = RsaSignatures.Encrypt(dataToEncrypt, keys.PubKey);

            Assert.AreNotEqual(encrypted, dataToEncrypt);

            var decrypted = RsaSignatures.Decrypt(encrypted, keys.PrivKey);

            Assert.AreEqual(decrypted, dataToEncrypt);
        }
Exemple #4
0
        private async Task Process(GenerateKeysRequest args)
        {
            var keys = RsaSignatures.GenerateKeys();

            SendCommand(new GenerateKeysDone()
            {
                PrivKey = keys.PrivKey, PubKey = keys.PubKey
            });
        }
Exemple #5
0
        public LoginChecker(ZkLobbyServer server, string geoipPath)
        {
            this.server = server;
            geoIP       = new DatabaseReader(Path.Combine(geoipPath, "GeoLite2-Country.mmdb"), FileAccessMode.Memory);

            var keys = RsaSignatures.GenerateKeys();

            ServerPubKey      = keys.PubKey;
            passwordDecryptor = new RsaSignatures(keys.PrivKey);
        }
Exemple #6
0
        public async Task <LoginCheckerResponse> DoLogin(Login login, string ip, List <ulong> dlc, string challengeToken)
        {
            var limit = MiscVar.ZklsMaxUsers;

            if (limit > 0 && server.ConnectedUsers.Count >= limit)
            {
                return(new LoginCheckerResponse(LoginResponse.Code.ServerFull));
            }
            await semaphore.WaitAsync();

            try
            {
                var userID       = login.UserID;
                var installID    = login.InstallID;
                var lobbyVersion = login.LobbyVersion;

                using (var db = new ZkDataContext())
                {
                    if (!VerifyIp(ip))
                    {
                        return(new LoginCheckerResponse(LoginResponse.Code.BannedTooManyConnectionAttempts));
                    }

                    if (!string.IsNullOrEmpty(login.ClientPubKey) || !string.IsNullOrEmpty(login.SignedChallengeToken))
                    {
                        if (!RsaSignatures.VerifySignature(challengeToken, login.SignedChallengeToken, login.ClientPubKey))
                        {
                            return(new LoginCheckerResponse(LoginResponse.Code.InvalidRsaSignature));
                        }
                    }

                    if (!string.IsNullOrEmpty(login.EncryptedPasswordHash))
                    {
                        login.PasswordHash = passwordDecryptor.Decrypt(login.EncryptedPasswordHash); // a bit hacky but preserves other code
                    }


                    SteamWebApi.PlayerInfo info = null;
                    if (!string.IsNullOrEmpty(login.SteamAuthToken))
                    {
                        info = await server.SteamWebApi.VerifyAndGetAccountInformation(login.SteamAuthToken);

                        if (info == null)
                        {
                            Trace.TraceWarning("Failed to verify steam token {0} for account {1}", login.SteamAuthToken, login.Name);               // we ignore it and wait RSA check below
                        }
                    }

                    Account accBySteamID = null;
                    Account accByLogin   = null;
                    if (info != null)
                    {
                        accBySteamID = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.SteamID == info.steamid);
                    }
                    if (!string.IsNullOrEmpty(login.Name))
                    {
                        accByLogin = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name) ?? db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name.Equals(login.Name, StringComparison.CurrentCultureIgnoreCase));
                    }

                    if (accBySteamID == null)
                    {
                        if (accByLogin == null)
                        {
                            LogIpFailure(ip);
                            if (!string.IsNullOrEmpty(login.Name))
                            {
                                return(new LoginCheckerResponse(LoginResponse.Code.InvalidName));
                            }
                            else
                            {
                                return(new LoginCheckerResponse(LoginResponse.Code.SteamNotLinkedAndLoginMissing));
                            }
                        }


                        // here we have account by login, but no verified steam
                        if (string.IsNullOrEmpty(login.PasswordHash))  // login attempted but with no password, check RSA signature
                        {
                            if (string.IsNullOrEmpty(accByLogin.LastPubKey) || accByLogin.LastPubKey != login.ClientPubKey)
                            {
                                return(new LoginCheckerResponse(LoginResponse.Code.RsaSignatureCouldNotBeVerified));
                            }
                        }
                        else if (!accByLogin.VerifyPassword(login.PasswordHash))
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.InvalidPassword));
                        }
                    }
                    var acc = accBySteamID ?? accByLogin;

                    var ret = new LoginCheckerResponse(LoginResponse.Code.Ok);
                    ret.LoginResponse.Name = acc.Name;
                    var user = ret.User;

                    acc.Country = ResolveCountry(ip);
                    if ((acc.Country == null) || string.IsNullOrEmpty(acc.Country))
                    {
                        acc.Country = "??";
                    }
                    acc.LobbyVersion = lobbyVersion;
                    acc.LastLogin    = DateTime.UtcNow;
                    acc.LastPubKey   = login.ClientPubKey;

                    if (info != null)
                    {
                        if (db.Accounts.Any(x => x.SteamID == info.steamid && x.Name != acc.Name))
                        {
                            LogIpFailure(ip);
                            return(new LoginCheckerResponse(LoginResponse.Code.SteamLinkedToDifferentAccount));
                        }
                        acc.SteamID   = info.steamid;
                        acc.SteamName = info.personaname;
                    }

                    user.LobbyVersion = login.LobbyVersion;
                    user.IpAddress    = ip;

                    acc.VerifyAndAddDlc(dlc);

                    UpdateUserFromAccount(user, acc);
                    LogIP(db, acc, ip);
                    LogUserID(db, acc, userID, installID);

                    if (String.IsNullOrEmpty(installID) && !acc.HasVpnException)
                    {
                        await server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("{0} just logged in with an unsupported lobby https://zero-k.info/Users/AdminUserDetail/{1}", acc.Name, acc.AccountID));
                    }

                    db.SaveChanges();

                    ret.LoginResponse.SessionToken = Guid.NewGuid().ToString(); // create session token

                    var banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, installID, x => x.BanLobby);

                    if (banPenalty != null)
                    {
                        return
                            (BlockLogin(
                                 $"Banned until {banPenalty.BanExpires} (match to {banPenalty.AccountByAccountID.Name}), reason: {banPenalty.Reason}",
                                 acc,
                                 ip,
                                 userID,
                                 installID));
                    }

                    if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled)
                    {
                        if (HasVpn(ip, acc, db))
                        {
                            return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID, installID));
                        }
                    }

                    return(ret);
                }
            }
            finally
            {
                semaphore.Release();
            }
        }