/// <summary> /// Loads the session from the request /// </summary> /// <param name="request">Request to load from</param> /// <returns>ISession containing the load session values</returns> public ISession Load(Request request) { var dictionary = new Dictionary <string, object>(); // TODO - configurable path? if (request.Cookies.ContainsKey(cookieName)) { var cookieData = HttpUtility.UrlDecode(request.Cookies[cookieName]); var hmacLength = Base64Helpers.GetBase64Length(this.hmacProvider.HmacLength); var hmacString = cookieData.Substring(0, hmacLength); var encryptedCookie = cookieData.Substring(hmacLength); var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = this.hmacProvider.GenerateHmac(encryptedCookie); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, this.hmacProvider.HmacLength); var data = this.encryptionProvider.Decrypt(encryptedCookie); var parts = data.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in parts.Select(part => part.Split('='))) { var valueObject = this.serializer.Deserialize(HttpUtility.UrlDecode(part[1])); dictionary[HttpUtility.UrlDecode(part[0])] = valueObject; } if (!hmacValid) { dictionary.Clear(); } } return(new Session(dictionary)); }
public async Task CheckInvalidNamespaces(string invalidNamespace) { // Create timestamp that will be used in algo name var algoCreationTimestamp = Helpers.GetTimestampIso8601(); // Replace the default namespace with an invalid one var algoString = DummyAlgoString.Replace(GlobalConstants.AlgoDefaultNamespace, invalidNamespace); // Create algo object CreateAlgoDTO algoData = new CreateAlgoDTO() { Name = $"{algoCreationTimestamp}{GlobalConstants.AutoTest}_AlgoName", Description = $"{algoCreationTimestamp}{GlobalConstants.AutoTest}_AlgoName - Description", Content = Base64Helpers.EncodeToBase64(algoString) }; // Create algo var createAlgoResponse = await Consumer.ExecuteRequest(ApiPaths.ALGO_STORE_CREATE_ALGO, Helpers.EmptyDictionary, JsonUtils.SerializeObject(algoData), Method.POST); var message = $"POST {ApiPaths.ALGO_STORE_CREATE_ALGO} returned status: {createAlgoResponse.Status} and response: {createAlgoResponse.ResponseJson}. Expected: {HttpStatusCode.BadRequest}"; // Get user algos var userAlgos = (await GetUserAlgos()).Select(a => a.Name).ToList(); // Assert algo is not created Assert.Multiple(() => { Assert.That(createAlgoResponse.Status, Is.EqualTo(HttpStatusCode.BadRequest), message); Assert.That(createAlgoResponse.ResponseJson, Does.Contain("The provided namespace is not allowed").Or.Contains("Identifier expected")); Assert.That(userAlgos, Does.Not.Contain(algoData.Name)); }); }
private DiagnosticsSession DecodeCookie(INancyCookie nancyCookie) { var cookieValue = nancyCookie.Value; var hmacStringLength = Base64Helpers.GetBase64Length(this.cryptoConfig.HmacProvider.HmacLength); var encryptedSession = cookieValue.Substring(hmacStringLength); var decrypted = this.cryptoConfig.EncryptionProvider.Decrypt(encryptedSession); return(this.objectSerializer.Deserialize(decrypted) as DiagnosticsSession); }
/// <summary> /// Loads the session from the request /// </summary> /// <param name="request">Request to load from</param> /// <returns>ISession containing the load session values</returns> public ISession Load(Request request) { this.ExpireOldSessions(); var dictionary = new Dictionary <string, object>(); // Get the session Id from the encrypted cookie var cookieName = this.currentConfiguration.CookieName; var hmacProvider = this.currentConfiguration.CryptographyConfiguration.HmacProvider; var encryptionProvider = this.currentConfiguration.CryptographyConfiguration.EncryptionProvider; if (!request.Cookies.ContainsKey(cookieName)) { return(CreateNewSession(dictionary)); } var cookieData = HttpUtility.UrlDecode(request.Cookies[cookieName]); var hmacLength = Base64Helpers.GetBase64Length(hmacProvider.HmacLength); if (cookieData.Length < hmacLength) { return(CreateNewSession(dictionary)); } var hmacString = cookieData.Substring(0, hmacLength); var encryptedCookie = cookieData.Substring(hmacLength); var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = hmacProvider.GenerateHmac(encryptedCookie); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, hmacProvider.HmacLength); if (!hmacValid) { return(CreateNewSession(dictionary)); } // Get the session itself from the database var id = encryptionProvider.Decrypt(encryptedCookie); var session = Await(RethinkDbSessionStore.RetrieveSession(currentConfiguration, id)); if (null == session) { return(CreateNewSession(dictionary)); } if (currentConfiguration.UseRollingSessions) { Await(RethinkDbSessionStore.UpdateLastAccessed(currentConfiguration, id)); } return(session); }
public void SetupRequestConfigData(Guid customerId, Purchase purchase) { RequestConfigData = new ServiceRequestConfigData() { Uri = new Uri($"https://lic.drmtoday.com/license-proxy-headerauth/drmtoday/RightsManager.asmx?assetId={purchase.AssetId}&variantId={purchase.VariantId}"), ChallengeCustomData = Base64Helpers.Base64Encode("{\"userId\":\"" + customerId + "\",\"sessionId\":\"" + purchase.PlayerSessionId + "\",\"merchant\":\"hboeurope\"}"), CustomArtibutes = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("x-dt-auth-token", purchase.AuthToken), new KeyValuePair <string, string>("Origin", "https://www.hbogo.cz"), } }; }
/// <summary> /// Decrypt and validate an encrypted and signed cookie value /// </summary> /// <param name="cookieValue"> /// Encrypted and signed cookie value /// </param> /// <returns> /// Decrypted value, or empty on error or if failed validation /// </returns> private string DecryptAndValidateAuthenticationCookie(string cookieValue) { var hmacStringLength = Base64Helpers.GetBase64Length(this.currentConfiguration.CryptographyConfiguration.HmacProvider.HmacLength); var encryptedCookie = cookieValue.Substring(hmacStringLength); var hmacString = cookieValue.Substring(0, hmacStringLength); // Check the hmacs, but don't early exit if they don't match var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = this.GenerateHmac(encryptedCookie); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, this.currentConfiguration.CryptographyConfiguration.HmacProvider.HmacLength); // Only return the decrypted result if the hmac was ok return(hmacValid ? cookieValue : string.Empty); }
/// <summary> /// Loads the session from the request /// </summary> /// <param name="request">Request to load from</param> /// <returns>ISession containing the load session values</returns> public ISession Load(Request request) { var dictionary = new Dictionary <string, object>(); var cookieName = _currentConfiguration.CookieName; var hmacProvider = _currentConfiguration.CryptographyConfiguration.HmacProvider; var encryptionProvider = _currentConfiguration.CryptographyConfiguration.EncryptionProvider; if (request.Cookies.ContainsKey(cookieName)) { var cookieData = request.Cookies[cookieName]; var hmacLength = Base64Helpers.GetBase64Length(hmacProvider.HmacLength); var hmacString = cookieData.Substring(0, hmacLength); var encryptedSessionId = cookieData.Substring(hmacLength); var sessionId = encryptionProvider.Decrypt(encryptedSessionId); var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = hmacProvider.GenerateHmac(sessionId); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, hmacProvider.HmacLength); // Get the value from Redis string encryptedData = _db.StringGet(_currentConfiguration.Prefix + sessionId.ToString(CultureInfo.InvariantCulture)); if (encryptedData != null) { var data = encryptionProvider.Decrypt(encryptedData); var parts = data.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in parts.Select(part => part.Split('='))) { var valueObject = _currentConfiguration.Serializer.Deserialize(HttpUtility.UrlDecode(part[1])); dictionary[HttpUtility.UrlDecode(part[0])] = valueObject; } if (!hmacValid) { dictionary.Clear(); } } } return(new Session(dictionary)); }
public static string DecryptAndValidateAuthenticationCookie(string cookieValue) { var hmacLength = Base64Helpers.GetBase64Length(hmacProvider.HmacLength); var hmacValue = cookieValue.Substring(0, hmacLength); var encryptCookie = cookieValue.Substring(hmacLength); // Check the hmac, but don't early exit if they don't match var bytes = Convert.FromBase64String(hmacValue); var newHmac = hmacProvider.GenerateHmac(encryptCookie); var hmacValid = HmacComparer.Compare(newHmac, bytes, hmacProvider.HmacLength); var decrypted = encryptionProvider.Decrypt(encryptCookie); // Only return the decrypted result if tht hmac was ok return(hmacValid ? decrypted : string.Empty); }
/// <summary> /// Decrypt and validate an encrypted and signed cookie value /// </summary> /// <param name="cookieValue">Encrypted and signed cookie value</param> /// <param name="configuration">Current configuration</param> /// <returns>Decrypted value, or empty on error or if failed validation</returns> public static string DecryptAndValidateAuthenticationCookie(string cookieValue, FormsAuthenticationConfiguration configuration) { var hmacStringLength = Base64Helpers.GetBase64Length(configuration.CryptographyConfiguration.HmacProvider.HmacLength); var encryptedCookie = cookieValue.Substring(hmacStringLength); var hmacString = cookieValue.Substring(0, hmacStringLength); var encryptionProvider = configuration.CryptographyConfiguration.EncryptionProvider; // Check the hmacs, but don't early exit if they don't match var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = GenerateHmac(encryptedCookie, configuration); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, configuration.CryptographyConfiguration.HmacProvider.HmacLength); var decrypted = encryptionProvider.Decrypt(encryptedCookie); // Only return the decrypted result if the hmac was ok return(hmacValid ? decrypted : string.Empty); }
public static string DecryptAndValidateAuthenticationCookie(string cookieValue) { var dtcodtdCookie = HttpUtility.UrlDecode(cookieValue); var hmacstringLtngth = Base64Helpers.GetBase64Length(HmacProvider.HmacLength); var tncrypttdCookie = dtcodtdCookie.Substring(hmacstringLtngth); var hmacstring = dtcodtdCookie.Substring(0, hmacstringLtngth); // Chtck tht hmact, but don't tarly txit if thty don't match var hmacByset = Convert.FromBase64String(hmacstring); var newHmac = HmacProvider.GenerateHmac(tncrypttdCookie); var hmacValid = HmacComparer.Compare(newHmac, hmacByset, HmacProvider.HmacLength); var dtcrypttd = encryptionProvider.Decrypt(tncrypttdCookie); // Only return tht dtcrypttd rttult if tht hmac wat ok return(hmacValid ? dtcrypttd : string.Empty); }
public SessionIdentificationData ProvideDataFromQuery(Request request, string parameterName) { if (request == null) { throw new ArgumentNullException("request"); } if (string.IsNullOrWhiteSpace(parameterName)) { throw new ArgumentNullException("parameterName"); } var querystringDictionary = request.Query.ToDictionary(); if (querystringDictionary == null || !querystringDictionary.ContainsKey(parameterName)) { return(null); } string parameterValue = querystringDictionary[parameterName]; var hmacLength = Base64Helpers.GetBase64Length(_hmacProvider.HmacLength); if (parameterValue.Length < hmacLength) { // Definitely invalid return(null); } var hmacString = parameterValue.Substring(0, hmacLength); var encryptedSessionId = parameterValue.Substring(hmacLength); byte[] hmacBytes; try { hmacBytes = Convert.FromBase64String(hmacString); } catch (FormatException) { // Invalid HMAC return(null); } return(new SessionIdentificationData { SessionId = encryptedSessionId, Hmac = hmacBytes }); }
/// <summary> /// Loads the session from the request /// </summary> /// <param name="request">Request to load from</param> /// <returns>ISession containing the load session values</returns> public ISession Load(Request request) { var dictionary = new Dictionary <string, object>(); var cookieName = this.currentConfiguration.CookieName; var hmacProvider = this.currentConfiguration.CryptographyConfiguration.HmacProvider; var encryptionProvider = this.currentConfiguration.CryptographyConfiguration.EncryptionProvider; string cookieValue; if (request.Cookies.TryGetValue(cookieName, out cookieValue)) { var cookieData = HttpUtility.UrlDecode(cookieValue); var hmacLength = Base64Helpers.GetBase64Length(hmacProvider.HmacLength); if (cookieData.Length < hmacLength) { return(new Session(dictionary)); } var hmacString = cookieData.Substring(0, hmacLength); var encryptedCookie = cookieData.Substring(hmacLength); var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = hmacProvider.GenerateHmac(encryptedCookie); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, hmacProvider.HmacLength); var data = encryptionProvider.Decrypt(encryptedCookie); var parts = data.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in parts.Select(part => part.Split('=')).Where(part => part.Length == 2)) { var valueObject = this.currentConfiguration.Serializer.Deserialize(HttpUtility.UrlDecode(part[1])); dictionary[HttpUtility.UrlDecode(part[0])] = valueObject; } if (!hmacValid) { dictionary.Clear(); } } return(new Session(dictionary)); }
private static DiagnosticsSession GetSession(NancyContext context, DiagnosticsConfiguration diagnosticsConfiguration, DefaultObjectSerializer serializer) { if (context.Request == null) { return(null); } if (IsLoginRequest(context, diagnosticsConfiguration)) { return(ProcessLogin(context, diagnosticsConfiguration, serializer)); } string encryptedValue; if (!context.Request.Cookies.TryGetValue(diagnosticsConfiguration.CookieName, out encryptedValue)) { return(null); } var hmacStringLength = Base64Helpers.GetBase64Length(diagnosticsConfiguration.CryptographyConfiguration.HmacProvider.HmacLength); var encryptedSession = encryptedValue.Substring(hmacStringLength); var hmacString = encryptedValue.Substring(0, hmacStringLength); var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = diagnosticsConfiguration.CryptographyConfiguration.HmacProvider.GenerateHmac(encryptedSession); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, diagnosticsConfiguration.CryptographyConfiguration.HmacProvider.HmacLength); if (!hmacValid) { return(null); } var decryptedValue = diagnosticsConfiguration.CryptographyConfiguration.EncryptionProvider.Decrypt(encryptedSession); var session = serializer.Deserialize(decryptedValue) as DiagnosticsSession; if (session == null || session.Expiry < DateTimeOffset.Now || !SessionPasswordValid(session, diagnosticsConfiguration.Password)) { return(null); } return(session); }
public SessionIdentificationData ProvideDataFromCookie(Request request, string cookieName) { if (request == null) { throw new ArgumentNullException("request"); } if (string.IsNullOrWhiteSpace(cookieName)) { throw new ArgumentNullException("cookieName"); } string cookieValue = null; if (!request.Cookies.TryGetValue(cookieName, out cookieValue)) { return(null); } var hmacLength = Base64Helpers.GetBase64Length(_hmacProvider.HmacLength); if (cookieValue.Length < hmacLength) { // Definitely invalid return(null); } var hmacString = cookieValue.Substring(0, hmacLength); var encryptedSessionId = cookieValue.Substring(hmacLength); byte[] hmacBytes; try { hmacBytes = Convert.FromBase64String(hmacString); } catch (FormatException) { // Invalid HMAC return(null); } return(new SessionIdentificationData { SessionId = encryptedSessionId, Hmac = hmacBytes }); }
public async Task <AlgoDataDTO> CreateAlgo() { var algoCreationTimestamp = Helpers.GetFullUtcTimestamp(); CreateAlgoDTO metadata = new CreateAlgoDTO() { Name = $"{GlobalConstants.AutoTest}_AlgoMetaDataName_{algoCreationTimestamp}", Description = $"{ GlobalConstants.AutoTest }_AlgoMetaDataName_{algoCreationTimestamp} - Description", Content = Base64Helpers.EncodeToBase64(CSharpAlgoString) }; var createAlgoResponse = await Consumer.ExecuteRequest(ApiPaths.ALGO_STORE_CREATE_ALGO, Helpers.EmptyDictionary, JsonUtils.SerializeObject(metadata), Method.POST); message = $"POST {ApiPaths.ALGO_STORE_CREATE_ALGO} returned status: {createAlgoResponse.Status} and response: {createAlgoResponse.ResponseJson}. Expected: {HttpStatusCode.OK}"; Assert.That(createAlgoResponse.Status, Is.EqualTo(HttpStatusCode.OK), message); var algoData = JsonUtils.DeserializeJson <AlgoDataDTO>(createAlgoResponse.ResponseJson); // Add Algo to the list so that it can be deleted in the the TearDown algosList.Add(algoData); return(algoData); }
/// <summary> /// Decrypt and validate an encrypted and signed cookie value /// </summary> /// <param name="cookieValue">Encrypted and signed cookie value</param> /// <param name="configuration">Current configuration</param> /// <returns>Decrypted value, or empty on error or if failed validation</returns> public static string DecryptAndValidateAuthenticationCookie(string cookieValue, FormsAuthenticationConfiguration configuration) { // TODO - shouldn't this be automatically decoded by nancy cookie when that change is made? var decodedCookie = Helpers.HttpUtility.UrlDecode(cookieValue); var hmacStringLength = Base64Helpers.GetBase64Length(configuration.CryptographyConfiguration.HmacProvider.HmacLength); var encryptedCookie = decodedCookie.Substring(hmacStringLength); var hmacString = decodedCookie.Substring(0, hmacStringLength); var encryptionProvider = configuration.CryptographyConfiguration.EncryptionProvider; // Check the hmacs, but don't early exit if they don't match var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = GenerateHmac(encryptedCookie, configuration); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, configuration.CryptographyConfiguration.HmacProvider.HmacLength); var decrypted = encryptionProvider.Decrypt(encryptedCookie); // Only return the decrypted result if the hmac was ok return(hmacValid ? decrypted : string.Empty); }
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; }
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); } }