/// <summary> /// Unlink selected account /// </summary> private void unlinkAuthenticator_Click(object sender, EventArgs e) { if (accountCurrent != null) { /*We want to confirm the user is unlinking the right account, and not the wrong one by accident*/ InputForm confirmForm = new InputForm("Enter the username of the account you want to unlink to proceed."); confirmForm.ShowDialog(); if (!confirmForm.inputCancelled) { if (confirmForm.inputText.Text.ToLower() == accountCurrent.AccountName.ToLower()) { DialogResult dialogResult = MessageBox.Show(string.Format("This action will unlink the authenticator for the account: {0}\n" + "Are you sure you want to proceed?", accountCurrent.AccountName), "Confirm selection", MessageBoxButtons.YesNo); if (dialogResult == DialogResult.Yes) { if (accountCurrent.DeactivateAuthenticator()) { MessageBox.Show("Authenticator has been unlinked.", "Success"); confirmTimer.Stop(); Thread.Sleep(1000); FileHandler.DeleteSGAFile(accountCurrent); loadAccounts(); confirmTimer.Start(); } else { MessageBox.Show("Unable to unlink authenticator. Please try again.", "Error"); return; } } } else { MessageBox.Show("Confirmation failed", "Boop beep."); } } } }
/// <summary> /// Login button /// </summary> private void loginButton_Click(object sender, EventArgs e) { string susername = usernameText.Text; string spassword = passwordText.Text; if (susername.Length > 0 && spassword.Length > 0) { userLogin = new UserLogin(susername, spassword); LoginResult loginres = LoginResult.BadCredentials; while ((loginres = userLogin.DoLogin()) != LoginResult.LoginOkay) { /*We need to enter the email code to access the account*/ if (loginres == LoginResult.NeedEmail) { InputForm emailForm = new InputForm("Enter the code sent to the email account associated with the account."); emailForm.ShowDialog(); if (emailForm.inputCancelled) { Close(); return; } userLogin.EmailCode = emailForm.inputText.Text; continue; } /*We need the captcha ...*/ if (loginres == LoginResult.NeedCaptcha) { Process.Start(string.Format("{0}/public/captcha.php?gid={1}", APIEndpoints.COMMUNITY_BASE, userLogin.CaptchaGID)); InputForm captchaForm = new InputForm("Enter the captcha code that is showing in your browser."); captchaForm.ShowDialog(); if (captchaForm.inputCancelled) { Close(); return; } userLogin.CaptchaText = captchaForm.inputText.Text; continue; } /*We need mobile auth code ...*/ /*The user needs to remove existing authenticator before we can proceed, so we'll just bail out*/ if (loginres == LoginResult.Need2FA) { MessageBox.Show("Please remove the existing authenticator device you have attatched to your account to in order to proceed."); Close(); return; } /*Incorrect password or similar*/ if (loginres == LoginResult.GeneralFailure) { MessageBox.Show("Trouble logging in.\nWrong password?"); Close(); return; } } /*Login successful, proceed*/ SessionData sessionData = userLogin.Session; AuthenticatorLinker authLinker = new AuthenticatorLinker((sessionData)); AuthenticatorLinker.LinkResult authResult = AuthenticatorLinker.LinkResult.GeneralFailure; while ((authResult = authLinker.AddAuthenticator()) != AuthenticatorLinker.LinkResult.AwaitingFinalization) { /*We need phone number to proceed*/ if (authResult == AuthenticatorLinker.LinkResult.MustProvidePhoneNumber) { string phoneNumber = string.Empty; while (!ValidPhoneNumberInput(phoneNumber)) { InputForm phoneNumberForm = new InputForm("Enter your phone number in the following format:\n+1 123-456-7890"); phoneNumberForm.inputText.Text = "+1 "; phoneNumberForm.ShowDialog(); if (phoneNumberForm.inputCancelled) { Close(); return; } phoneNumber = FilterPhoneNumber(phoneNumberForm.inputText.Text); } authLinker.PhoneNumber = phoneNumber; continue; } /*Remove previous number attatched to the account*/ if (authResult == AuthenticatorLinker.LinkResult.MustRemovePhoneNumber) { authLinker.PhoneNumber = string.Empty; continue; } /*Oops*/ if (authResult == AuthenticatorLinker.LinkResult.GeneralFailure) { MessageBox.Show("Something bad happened..."); Close(); return; } } /*Taking a pause to save the information that we've gathered thus far*/ if (!FileHandler.SaveSGAFile(authLinker.LinkedAccount)) { MessageBox.Show("Unable to save the current data. The authenticator has not been linked.", "Error"); Close(); return; } /*Final checks*/ AuthenticatorLinker.FinalizeResult finalRes = AuthenticatorLinker.FinalizeResult.GeneralFailure; while (finalRes != AuthenticatorLinker.FinalizeResult.Success) { /*Get SMS code that was sent to users phone, providing the number was correct*/ InputForm smsForm = new InputForm("Enter the SMS code you received on your phone."); smsForm.ShowDialog(); if (smsForm.inputCancelled) { /*Delete file here*/ FileHandler.DeleteSGAFile(authLinker.LinkedAccount); Close(); return; } /*Finalize the process and check last things*/ finalRes = authLinker.FinalizeAddAuthenticator(smsForm.inputText.Text); /*Check if the SMS code was bad*/ if (finalRes == AuthenticatorLinker.FinalizeResult.BadSMSCode) { MessageBox.Show("Incorrect SMS code. Try again."); continue; } /*General failure number one*/ if (finalRes == AuthenticatorLinker.FinalizeResult.UnableToGenerateCorrectCodes || finalRes == AuthenticatorLinker.FinalizeResult.GeneralFailure) { MessageBox.Show(string.Format("Unable to generate correct codes.\nThe authenticator has not been linked.\n\n" + "However, please write the revocation code down just incase:\n\n {0}", authLinker.LinkedAccount.RevocationCode), "Error"); /*Delete file here*/ FileHandler.DeleteSGAFile(authLinker.LinkedAccount); Close(); return; } } /*Finally done - save everything*/ if (!FileHandler.SaveSGAFile(authLinker.LinkedAccount)) { MessageBox.Show("Save failed."); //Do something about it } MessageBox.Show("Mobile authenticator successfully linked.\nRevocation code: " + authLinker.LinkedAccount.RevocationCode, "Success!"); Close(); } else { MessageBox.Show("Missing login details."); } }
/// <summary> /// Form load event /// </summary> private void Form1_Load(object sender, EventArgs e) { /*Instance classes*/ gitHub = new GitHub(); accountList = new List <SteamGuardAccount>(); popupForms = new List <PopupForm>(); confirmationList = new List <Config.ConfirmationClass>(); confirmForm = new ConfirmForm(); settingsForm = new SettingsForm(); notifyPlayer = new SoundPlayer(); versionLabel.Text = "v" + Application.ProductVersion; /*Check for settings*/ settingsForm.cbAutostart.Checked = CRegistry.StartUp.IsRegistered(); settingsForm.cbUpdates.Checked = Properties.Settings.Default.bCheckForUpdates; settingsForm.cbPassword.Checked = Properties.Settings.Default.bAskForPassword; settingsForm.cbStatistics.Checked = Properties.Settings.Default.bSendStatistics; settingsForm.cbStartMinimized.Checked = Properties.Settings.Default.bStartMinimized; /*Update statistics if enabled*/ if (settingsForm.cbStatistics.Checked) { Task.Run(() => { using (WebClient wc = new WebClient()) { wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; wc.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); wc.DownloadString("http://casperbod.in/patch/"); } }); } /*We'll ask for a password here*/ /*The password will be used as the secret for encrypting the data we'll store along with a generated salt*/ /*It will be asked for every time the application starts and cannot be recovered*/ /*User can also chose not to enter a password with a button, but this is not secure*/ if (settingsForm.cbPassword.Checked) { InputForm passwordForm = new InputForm("Enter password. If you are a new user, enter a new password (6-25 chars). It can not be recovered.", true); passwordForm.ShowDialog(); /*If user provided us with a password*/ if (!passwordForm.inputNoPassword) { string password = passwordForm.inputText.Text; if (password.Length >= 6 && password.Length <= 25) { /*Set secret and salt for encryption*/ Crypto.crySecret = password; Crypto.crySalt = Encoding.ASCII.GetBytes("RandomNumberFour"); //https://xkcd.com/221/ } else { MessageBox.Show("Password is not between 6-25 chars.", "Error"); Environment.Exit(1); } } } /*Check if application is up-to-date if setting enabled*/ if (settingsForm.cbUpdates.Checked) { updateChecker.RunWorkerAsync(); IsLoading(true); } /*Minimize the app if enabled*/ if (settingsForm.cbStartMinimized.Checked) { notifyIcon.ShowBalloonTip(2000, "Steam Authenticator", "I'm down here!", ToolTipIcon.Info); WindowState = FormWindowState.Minimized; ShowInTaskbar = false; Hide(); } /*Do the rest*/ Directory.CreateDirectory(Path.Combine(Application.StartupPath, "SGAFiles")); notifyPlayer.Stream = Properties.Resources.notifysound; loadAccounts(); }
/// <summary> /// Login button /// </summary> private void loginButton_Click(object sender, EventArgs e) { string susername = usernameText.Text; string spassword = passwordText.Text; if(susername.Length > 0 && spassword.Length > 0) { userLogin = new UserLogin(susername, spassword); LoginResult loginres = LoginResult.BadCredentials; while((loginres = userLogin.DoLogin()) != LoginResult.LoginOkay) { /*We need to enter the email code to access the account*/ if(loginres == LoginResult.NeedEmail) { InputForm emailForm = new InputForm("Enter the code sent to the email account associated with the account."); emailForm.ShowDialog(); if(emailForm.inputCancelled) { Close(); return; } userLogin.EmailCode = emailForm.inputText.Text; continue; } /*We need the captcha ...*/ if(loginres == LoginResult.NeedCaptcha) { Process.Start(string.Format("{0}/public/captcha.php?gid={1}", APIEndpoints.COMMUNITY_BASE, userLogin.CaptchaGID)); InputForm captchaForm = new InputForm("Enter the captcha code that is showing in your browser."); captchaForm.ShowDialog(); if(captchaForm.inputCancelled) { Close(); return; } userLogin.CaptchaText = captchaForm.inputText.Text; continue; } /*We need mobile auth code ...*/ /*The user needs to remove existing authenticator before we can proceed, so we'll just bail out*/ if(loginres == LoginResult.Need2FA) { MessageBox.Show("Please remove the existing authenticator device you have attatched to your account to in order to proceed."); Close(); return; } /*Incorrect password or similar*/ if(loginres == LoginResult.GeneralFailure) { MessageBox.Show("Trouble logging in.\nWrong password?"); Close(); return; } } /*Login successful, proceed*/ SessionData sessionData = userLogin.Session; AuthenticatorLinker authLinker = new AuthenticatorLinker((sessionData)); AuthenticatorLinker.LinkResult authResult = AuthenticatorLinker.LinkResult.GeneralFailure; while ((authResult = authLinker.AddAuthenticator()) != AuthenticatorLinker.LinkResult.AwaitingFinalization) { /*We need phone number to proceed*/ if(authResult == AuthenticatorLinker.LinkResult.MustProvidePhoneNumber) { string phoneNumber = string.Empty; while(!ValidPhoneNumberInput(phoneNumber)) { InputForm phoneNumberForm = new InputForm("Enter your phone number in the following format:\n+1 123-456-7890"); phoneNumberForm.inputText.Text = "+1 "; phoneNumberForm.ShowDialog(); if(phoneNumberForm.inputCancelled) { Close(); return; } phoneNumber = FilterPhoneNumber(phoneNumberForm.inputText.Text); } authLinker.PhoneNumber = phoneNumber; continue; } /*Remove previous number attatched to the account*/ if(authResult == AuthenticatorLinker.LinkResult.MustRemovePhoneNumber) { authLinker.PhoneNumber = string.Empty; continue; } /*Oops*/ if(authResult == AuthenticatorLinker.LinkResult.GeneralFailure) { MessageBox.Show("Something bad happened..."); Close(); return; } } /*Taking a pause to save the information that we've gathered thus far*/ if(!FileHandler.SaveSGAFile(authLinker.LinkedAccount)) { MessageBox.Show("Unable to save the current data. The authenticator has not been linked.", "Error"); Close(); return; } /*Final checks*/ AuthenticatorLinker.FinalizeResult finalRes = AuthenticatorLinker.FinalizeResult.GeneralFailure; while(finalRes != AuthenticatorLinker.FinalizeResult.Success) { /*Get SMS code that was sent to users phone, providing the number was correct*/ InputForm smsForm = new InputForm("Enter the SMS code you received on your phone."); smsForm.ShowDialog(); if(smsForm.inputCancelled) { /*Delete file here*/ FileHandler.DeleteSGAFile(authLinker.LinkedAccount); Close(); return; } /*Finalize the process and check last things*/ finalRes = authLinker.FinalizeAddAuthenticator(smsForm.inputText.Text); /*Check if the SMS code was bad*/ if(finalRes == AuthenticatorLinker.FinalizeResult.BadSMSCode) { MessageBox.Show("Incorrect SMS code. Try again."); continue; } /*General failure number one*/ if(finalRes == AuthenticatorLinker.FinalizeResult.UnableToGenerateCorrectCodes || finalRes == AuthenticatorLinker.FinalizeResult.GeneralFailure) { MessageBox.Show(string.Format("Unable to generate correct codes.\nThe authenticator has not been linked.\n\n" + "However, please write the revocation code down just incase:\n\n {0}", authLinker.LinkedAccount.RevocationCode), "Error"); /*Delete file here*/ FileHandler.DeleteSGAFile(authLinker.LinkedAccount); Close(); return; } } /*Finally done - save everything*/ if(!FileHandler.SaveSGAFile(authLinker.LinkedAccount)) { MessageBox.Show("Save failed."); //Do something about it } MessageBox.Show("Mobile authenticator successfully linked.\nRevocation code: " + authLinker.LinkedAccount.RevocationCode, "Success!"); Close(); } else { MessageBox.Show("Missing login details."); } }
/// <summary> /// Unlink selected account /// </summary> private void unlinkAuthenticator_Click(object sender, EventArgs e) { if(accountCurrent != null) { /*We want to confirm the user is unlinking the right account, and not the wrong one by accident*/ InputForm confirmForm = new InputForm("Enter the username of the account you want to unlink to proceed."); confirmForm.ShowDialog(); if (!confirmForm.inputCancelled) { if (confirmForm.inputText.Text.ToLower() == accountCurrent.AccountName.ToLower()) { DialogResult dialogResult = MessageBox.Show(string.Format("This action will unlink the authenticator for the account: {0}\n" + "Are you sure you want to proceed?", accountCurrent.AccountName), "Confirm selection", MessageBoxButtons.YesNo); if (dialogResult == DialogResult.Yes) { if (accountCurrent.DeactivateAuthenticator()) { MessageBox.Show("Authenticator has been unlinked.", "Success"); confirmTimer.Stop(); Thread.Sleep(1000); FileHandler.DeleteSGAFile(accountCurrent); loadAccounts(); confirmTimer.Start(); } else { MessageBox.Show("Unable to unlink authenticator. Please try again.", "Error"); return; } } } else { MessageBox.Show("Confirmation failed", "Boop beep."); } } } }
/// <summary> /// Remove password from an account if there's one set /// </summary> private void removePassword_Click(object sender, EventArgs e) { if (accountCurrent != null) { /*Get the account password*/ InputForm confirmForm = new InputForm("Confirm your password. You can not re-encrypt this file once this process is done.", true); confirmForm.nopwButton.Visible = false; confirmForm.ShowDialog(); /*Check if passwords matches*/ string password = confirmForm.inputText.Text; if (password == Crypto.crySecret && password.Length > 6) { if (FileHandler.DecryptSGAFile(accountCurrent)) { MessageBox.Show("Save file decrypted", "Success"); loadAccounts(); } else { MessageBox.Show("Unable to decrypt file", "Error"); } } else { MessageBox.Show("Password does not match the password you entered at start", "Error"); } } }
/// <summary> /// Form load event /// </summary> private void Form1_Load(object sender, EventArgs e) { /*Instance classes*/ gitHub = new GitHub(); accountList = new List<SteamGuardAccount>(); popupForms = new List<PopupForm>(); confirmationList = new List<Config.ConfirmationClass>(); confirmForm = new ConfirmForm(); settingsForm = new SettingsForm(); notifyPlayer = new SoundPlayer(); versionLabel.Text = "v" + Application.ProductVersion; /*Check for settings*/ settingsForm.cbAutostart.Checked = CRegistry.StartUp.IsRegistered(); settingsForm.cbUpdates.Checked = Properties.Settings.Default.bCheckForUpdates; settingsForm.cbPassword.Checked = Properties.Settings.Default.bAskForPassword; settingsForm.cbStatistics.Checked = Properties.Settings.Default.bSendStatistics; settingsForm.cbStartMinimized.Checked = Properties.Settings.Default.bStartMinimized; /*Update statistics if enabled*/ if (settingsForm.cbStatistics.Checked) { Task.Run(() => { using (WebClient wc = new WebClient()) { wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; wc.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); wc.DownloadString("http://casperbod.in/patch/"); } }); } /*We'll ask for a password here*/ /*The password will be used as the secret for encrypting the data we'll store along with a generated salt*/ /*It will be asked for every time the application starts and cannot be recovered*/ /*User can also chose not to enter a password with a button, but this is not secure*/ if (settingsForm.cbPassword.Checked) { InputForm passwordForm = new InputForm("Enter password. If you are a new user, enter a new password (6-25 chars). It can not be recovered.", true); passwordForm.ShowDialog(); /*If user provided us with a password*/ if (!passwordForm.inputNoPassword) { string password = passwordForm.inputText.Text; if (password.Length >= 6 && password.Length <= 25) { /*Set secret and salt for encryption*/ Crypto.crySecret = password; Crypto.crySalt = Encoding.ASCII.GetBytes("RandomNumberFour"); //https://xkcd.com/221/ } else { MessageBox.Show("Password is not between 6-25 chars.", "Error"); Environment.Exit(1); } } } /*Check if application is up-to-date if setting enabled*/ if (settingsForm.cbUpdates.Checked) { updateChecker.RunWorkerAsync(); IsLoading(true); } /*Minimize the app if enabled*/ if (settingsForm.cbStartMinimized.Checked) { notifyIcon.ShowBalloonTip(2000, "Steam Authenticator", "I'm down here!", ToolTipIcon.Info); WindowState = FormWindowState.Minimized; ShowInTaskbar = false; Hide(); } /*Do the rest*/ Directory.CreateDirectory(Path.Combine(Application.StartupPath, "SGAFiles")); notifyPlayer.Stream = Properties.Resources.notifysound; loadAccounts(); }