private void Save(FileInfo file) { byte[] usernameBytes = Encoding.Unicode.GetBytes(Username); byte[] passwordBytes = new byte[SecureStringHelper.GetSecureStringByteCount(Password, Encoding.Unicode)]; SecureStringHelper.SecureStringToBytes(Password, passwordBytes, 0, Encoding.Unicode); try { byte[] entropy = GenerateEntropy(); byte[] protectedUsernameBytes = ProtectedData.Protect(usernameBytes, entropy, DataProtectionScope.CurrentUser); byte[] protectedPasswordBytes = ProtectedData.Protect(passwordBytes, entropy, DataProtectionScope.CurrentUser); var template = new CredentialsExportTemplate() { Entropy = Convert.ToBase64String(entropy), ProtectedUsername = Convert.ToBase64String(protectedUsernameBytes), ProtectedPassword = Convert.ToBase64String(protectedPasswordBytes), }; JsonHelper.Serialize(template, file); } finally { SecureStringHelper.DestroySecureByteArray(passwordBytes); } }
/// <summary> /// Logs in at the api. /// </summary> /// <param name="username">The username.</param> /// <param name="password">The users password.</param> /// <param name="info">Out. The login token generated by the server and the users name.</param> /// <returns>Returns false if the login failed, otherwise true.</returns> public static bool LogIn(string username, SecureString password, out AuthenticationInfo info) { const string loginPage = "https://auth.factorio.com/api-login"; info = null; string part1 = $"api_version=2&require_game_ownership=true&username={username}&password="; int part1Length = Encoding.UTF8.GetByteCount(part1); byte[] passwordBytes = SecureStringHelper.SecureStringToBytes(password); string part2 = HttpUtility.UrlEncode(passwordBytes); byte[] content = new byte[part1Length + part2.Length]; Encoding.UTF8.GetBytes(part1, 0, part1.Length, content, 0); Encoding.UTF8.GetBytes(part2, 0, part2.Length, content, part1Length); try { string document = WebHelper.GetDocument(loginPage, content); if (string.IsNullOrWhiteSpace(document)) { return(false); } info = JsonHelper.Deserialize <AuthenticationInfo>(document); if ((info == null) || string.IsNullOrWhiteSpace(info.Token) || string.IsNullOrWhiteSpace(info.Username)) { return(false); } return(true); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.ProtocolError) { return(false); } else { throw; } } finally { SecureStringHelper.DestroySecureByteArray(content); } }
/// <summary> /// Logs in at the api. /// </summary> /// <param name="username">The username.</param> /// <param name="password">The users password.</param> /// <param name="token">Out. The login token generated by the server.</param> /// <returns>Returns false if the login failed, otherwise true.</returns> public static bool LogIn(string username, SecureString password, out string token) { const string loginPage = "https://auth.factorio.com/api-login"; const string pattern = "[0-9a-f]{30}"; token = null; string part1 = $"require_game_ownership=True&username={username}&password="; int part1Length = Encoding.UTF8.GetByteCount(part1); int part2Length = SecureStringHelper.GetSecureStringByteCount(password); byte[] content = new byte[part1Length + part2Length]; Encoding.UTF8.GetBytes(part1, 0, part1.Length, content, 0); SecureStringHelper.SecureStringToBytes(password, content, part1Length); try { string document = WebHelper.GetDocument(loginPage, null, content); MatchCollection matches = Regex.Matches(document, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); if (matches.Count != 1) { return(false); } token = matches[0].Value; return(true); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.ProtocolError) { return(false); } else { throw; } } finally { SecureStringHelper.DestroySecureByteArray(content); } }
/// <summary> /// Logs in at the website. /// </summary> /// <param name="container">The cookie container to store the session cookie in.</param> /// <param name="username">The username.</param> /// <param name="password">The users password.</param> /// <returns>Returns false if the login failed, otherwise true.</returns> public static bool LogIn(CookieContainer container, string username, SecureString password) { const string loginPage = "https://www.factorio.com/login"; const string pattern = "[0-9]{10}##[0-9a-f]{40}"; // Get a csrf token. string document = WebHelper.GetDocument(loginPage, container); MatchCollection matches = Regex.Matches(document, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); if (matches.Count != 1) { return(false); } string csrfToken = matches[0].Value; // Log in using the token and credentials. string part1 = $"csrf_token={csrfToken}&username_or_email={username}&password="******"&action=Login"; int part3Length = Encoding.UTF8.GetByteCount(part3); byte[] content = new byte[part1Length + part2Length + part3Length]; Encoding.UTF8.GetBytes(part1, 0, part1.Length, content, 0); SecureStringHelper.SecureStringToBytes(password, content, part1Length); Encoding.UTF8.GetBytes(part3, 0, part3.Length, content, part1Length + part2Length); try { document = WebHelper.GetDocument(loginPage, container, content); if (!document.Contains("logout")) { return(false); } return(true); } finally { SecureStringHelper.DestroySecureByteArray(content); } }
private void Load(FileInfo file) { CredentialsExportTemplate template = JsonHelper.Deserialize <CredentialsExportTemplate>(file); byte[] entropy = Convert.FromBase64String(template.Entropy); byte[] protectedUsernameBytes = Convert.FromBase64String(template.ProtectedUsername); byte[] protectedPasswordBytes = Convert.FromBase64String(template.ProtectedPassword); byte[] usernameBytes = ProtectedData.Unprotect(protectedUsernameBytes, entropy, DataProtectionScope.CurrentUser); byte[] passwordBytes = ProtectedData.Unprotect(protectedPasswordBytes, entropy, DataProtectionScope.CurrentUser); try { username = Encoding.Unicode.GetString(usernameBytes); password = SecureStringHelper.SecureStringFromBytes(passwordBytes, Encoding.Unicode); } finally { SecureStringHelper.DestroySecureByteArray(passwordBytes); } }