class mainWindow(Frame): #Initialize def __init__(self, parent, colorDic): #Declare class variables self.activeSecrets = None self.client = SteamClient() self.colorDic = colorDic self.conn = dataBase() self.apiKey = self.conn.get_api_key() self.apiController = api(self.apiKey) self.parent = parent self.guiControl = guiController(self.parent, self.colorDic) self.steamGuardController = None self.steamName = "" self.updateProgressBarID = None #Initialize window's frame Frame.__init__(self, self.parent) #Everything below is created in order from top of application to the bottom #Menu bar self.menuBar = Menu(self.parent, border=0) self.menuBar.config(bg=self.colorDic["menuBarBackground"], fg=self.colorDic["menuBarForeground"]) self.accountMenu = Menu(self.menuBar, tearoff=0) #New account and Import account button self.accountMenu.add_command(label="New Steam Guard", command=self.new_account_window) self.accountMenu.add_command(label="Delete Steam Guard", command=self.delete_steam_guard) #Seperator makes it look fabulous self.accountMenu.add_separator() self.accountMenu.add_command(label="Import Steam Guard") self.menuBar.add_cascade(label="Guard", menu=self.accountMenu) self.accountMenu.config(bg=self.colorDic["menuBarBackground"], fg=self.colorDic["menuBarForeground"]) self.editMenu = Menu(self.menuBar, tearoff=0) #Security preferences and color scheme button self.editMenu.add_command(label="Security Preferences") self.editMenu.add_command(label="Color Scheme") self.menuBar.add_cascade(label="Edit", menu=self.editMenu) self.editMenu.config(bg=self.colorDic["menuBarBackground"], fg=self.colorDic["menuBarForeground"]) #Window Title self.windowTitle = Label(self.parent, text="Steam Guard") self.windowTitle.configure(font=("Segoe UI", 12), bg=self.colorDic["windowTitleBackground"], fg=self.colorDic["windowTitleForeground"], width="350", pady=10) self.windowTitle.pack() #Guard codes and Steam name frame self.guardCodeHolder = Frame(self.parent, bg=self.colorDic["guardCodeBackground"]) self.guardCodeHolder.pack() #Generated Steam Guard text self.guardLabel = Label(self.guardCodeHolder, text="...") self.guardLabel.configure(font=("Segoe UI", 30), bg=self.colorDic["guardCodeBackground"], fg=self.colorDic["guardCodeForeground"], width="350", pady=15) self.guardLabel.pack() #Styling for progress bar self.barStyle = ttk.Style() self.barStyle.theme_use('alt') self.barStyle.configure( "blue.Horizontal.TProgressbar", troughrelief="flat", troughcolor=self.colorDic["progressBarBackground"], background=self.colorDic["progressBarForeground"], relief="flat") #Progress bar self.progressBar = ttk.Progressbar( self.guardCodeHolder, style="blue.Horizontal.TProgressbar", orient="horizontal", length=250, mode="determinate") self.progressBar.pack() self.progressBar["maximum"] = 58 #Steam name text self.steamNameLabel = Label(self.guardCodeHolder, text=self.steamName) self.steamNameLabel.configure(font=("Segoe UI", 10), bg=self.colorDic["guardCodeBackground"], fg=self.colorDic["steamNameForeground"], width="350", pady=5) self.steamNameLabel.pack() #Special buttons frame self.specialButtonsHolder = Frame( self.parent, bg=self.colorDic["specialButtonBackground"]) self.specialButtonsHolder.pack(side="top", expand=True, fill="y") self.specialButtonsBackground = Frame(self.specialButtonsHolder, bg=self.colorDic["hrColor"], width="350", height="241") self.specialButtonsBackground.pack() self.specialButtonsBackground.pack_propagate(0) #"Confirmations" button frame self.confirmationHolder = Frame( self.specialButtonsBackground, bg=self.colorDic["specialButtonBackground"], width="350", height="79", cursor="hand2") self.confirmationHolder.pack(pady="1") self.confirmationLabel = Label( self.confirmationHolder, text="Confirmations", font=("Segoe UI", 15), bg=self.colorDic["specialButtonBackground"], fg=self.colorDic["specialButtonForeground"], cursor="hand2") self.confirmationLabel.pack(side="left", pady="15", padx="20") self.confirmationHolder.pack_propagate(0) self.confirmationHolder.bind("<Enter>", self.guiControl.special_button_hover) self.confirmationHolder.bind("<Leave>", self.guiControl.special_button_leave) self.confirmationHolder.bind("<Button-1>", self.confirmations_window) self.confirmationLabel.bind("<Button-1>", self.confirmations_window) #"Revocation" button frame self.revocationCodeHolder = Frame( self.specialButtonsBackground, bg=self.colorDic["specialButtonBackground"], width="350", height="79", cursor="hand2") self.revocationCodeLabel = Label( self.revocationCodeHolder, text="Revocation Code", font=("Segoe UI", 15), bg=self.colorDic["specialButtonBackground"], fg=self.colorDic["specialButtonForeground"], cursor="hand2") self.revocationCodeLabel.pack(side="left", pady="15", padx="20") self.revocationCodeHolder.pack() self.revocationCodeHolder.pack_propagate(0) self.revocationCodeHolder.bind("<Enter>", self.guiControl.special_button_hover) self.revocationCodeHolder.bind("<Leave>", self.guiControl.special_button_leave) self.revocationCodeHolder.bind("<Button-1>", self.revocation_code_window) self.revocationCodeLabel.bind("<Button-1>", self.revocation_code_window) #"Switch Account" button frame self.switchAccountHolder = Frame( self.specialButtonsBackground, bg=self.colorDic["specialButtonBackground"], width="350", height="79", cursor="hand2") self.switchAccountLabel = Label( self.switchAccountHolder, text="Switch Accounts", font=("Segoe UI", 15), bg=self.colorDic["specialButtonBackground"], fg=self.colorDic["specialButtonForeground"], cursor="hand2") self.switchAccountLabel.pack(side="left", pady="15", padx="20") self.switchAccountHolder.pack(pady="1") self.switchAccountHolder.pack_propagate(0) self.switchAccountHolder.bind("<Enter>", self.guiControl.special_button_hover) self.switchAccountHolder.bind("<Leave>", self.guiControl.special_button_leave) self.switchAccountHolder.bind("<Button-1>", self.switch_account_window) self.switchAccountLabel.bind("<Button-1>", self.switch_account_window) #Copy button frame self.buttonHolder = Frame(self.parent, bg=self.colorDic["appBackground"]) self.copyCodeButton = Button( self.buttonHolder, text="Copy Code", command=lambda: self.guiControl.copy_label_text(self.guardLabel), font=("Segoe UI", 12), relief="flat", cursor="hand2") self.copyCodeButton.configure( fg=self.colorDic["actionButtonForeground"], bg=self.colorDic["actionButtonBackground"]) self.copyCodeButton.pack(padx=30, pady=20, ipady=10, ipadx=10) self.buttonHolder.pack(side="bottom") #Set our window properties self.parent.geometry("350x500") self.parent.resizable(0, 0) self.parent.configure(bg=self.colorDic["appBackground"]) self.parent.title("Steam Guardian") self.parent.config(menu=self.menuBar) self.guiControl.center() if self.conn.has_active_user(): self.update_guard() #API key window method def api_key_window(self): #Start API key window self.clientLogin = apiKeyWindow(self.parent, self.colorDic, self.conn, self) self.clientLogin.geometry("500x300") self.clientLogin.resizable(0, 0) self.clientLogin.configure(bg=self.colorDic["appBackground"]) self.clientLogin.title("Steam Guardian - Api Key") guiController(self.clientLogin).center() #Check for active account method def check_active_secrets(self): if self.activeSecrets: return True else: self.show_message( None, "error", "No active account! This is required to do this action.\nGo to 'Guard -> New Steam Guard' to add one." ) #Check for active api key def check_active_api(self): if self.check_active_secrets(): if self.apiKey: if self.apiController.check_api_key(): return True else: self.show_message( None, "error", "API key is invalid! Taking you to the\nAPI window to update your key." ) self.api_key_window() else: self.show_message( None, "error", "No API key is set! This is required to do this action.\nTaking you to the API window to add a key." ) self.api_key_window() #Confirmations window method def confirmations_window(self, event): if self.check_active_api(): #Everything's good, get our confirmations print("Feature not yet added!") #Delete Steam Guard method def delete_steam_guard(self): #If active secrets set if self.check_active_secrets(): #Ask user if it's okay to remove Steam Guard userApproves = self.show_message( None, "warning", "This will remove steam guard from your {} account.\nYou cannot undo this action, would yo like to continue?" .format(self.steamName), True) #If user approves if userApproves: self.conn.remove_guard(self.guardLabel["text"], self.activeSecrets) #Reset Steam Guard in GUI self.steamName = '' self.activeSecrets = None self.steamGuardController = None self.guardLabel.config({"text": "..."}) self.progressBar["value"] = 0 self.steamName = '' self.steamNameLabel.configure(text=self.steamName) self.barStyle.configure( "blue.Horizontal.TProgressbar", troughcolor=self.colorDic["progressBarBackground"], background=self.colorDic["progressBarForeground"]) self.guardLabel.configure( fg=self.colorDic["guardCodeForeground"], bg=self.colorDic["guardCodeBackground"]) self.steamNameLabel.config( fg=self.colorDic["steamNameForeground"], bg=self.colorDic["guardCodeBackground"]) self.guardCodeHolder.config( bg=self.colorDic["guardCodeBackground"]) #Tell user we're done self.show_message( None, "success", "Steam Guard has been successfully removed.") else: #No active secrets set self.show_message(None, "error", "No account to delete!") #New account window method def new_account_window(self): #Start login window self.clientLogin = clientLoginWindow(self.parent, self.colorDic, self.conn, self) self.clientLogin.geometry("500x350") self.clientLogin.resizable(0, 0) self.clientLogin.configure(bg=self.colorDic["appBackground"]) self.clientLogin.title("Steam Guardian - New Account") guiController(self.clientLogin).center() #Revocation code window method def revocation_code_window(self, event): if self.check_active_secrets(): #Start revocation code window self.revocationCode = revocationCodeWindow(self.parent, self.colorDic, self) self.revocationCode.geometry("350x300") self.revocationCode.resizable(0, 0) self.revocationCode.configure(bg=self.colorDic["appBackground"]) self.revocationCode.title("Steam Guardian - Revocation Code") guiController(self.revocationCode).center() #Message window method def show_message(self, event, messageType, text, yesNo=False): #Start message window self.messageWindow = showMessage(self.parent, self.colorDic, messageType, text, yesNo) self.messageWindow.title("Steam Guardian - {}".format(messageType)) guiController(self.messageWindow).center() self.messageWindow.wait_window() return self.messageWindow.response #Switch account window method def switch_account_window(self, event): #If there's more than 1 user to select if self.conn.count_users() > 1: #Start switch account window self.switchGui = clientSwitchWindow(self.parent, self.colorDic, self.conn, self) self.switchGui.geometry("400x450") self.switchGui.resizable(0, 0) self.switchGui.configure(bg=self.colorDic["appBackground"]) self.switchGui.title("Steam Guardian - Accounts") guiController(self.switchGui).center() else: #If no accounts were found to switch to show an error self.rootClassRef.show_message( None, "warning", "You have no accounts to switch to.\n'Click Account-> New Account' to add a new one." ) #Update secrets and reset progress bar method def update_guard(self): #Update active guard secrets, Steam name and reset our progress bar self.activeSecrets = json.loads(self.conn.get_active_secrets()) self.apiKey = self.conn.get_api_key() self.apiController = api(self.apiKey) self.steamGuardController = SteamAuthenticator( secrets=self.activeSecrets, medium=self.client) self.steamName = self.activeSecrets["account_name"] self.steamNameLabel.configure(text=self.steamName) if self.progressBar["value"] <= 18: self.barStyle.configure( "blue.Horizontal.TProgressbar", troughcolor=self.colorDic["progressBarBackground"], background=self.colorDic["progressBarForeground"]) self.guardLabel.configure(fg=self.colorDic["guardCodeForeground"], bg=self.colorDic["guardCodeBackground"]) self.steamNameLabel.config(fg=self.colorDic["steamNameForeground"], bg=self.colorDic["guardCodeBackground"]) self.guardCodeHolder.config( bg=self.colorDic["guardCodeBackground"]) #Cancel wait for updating progress bar. This way we don't call the same function twice doubling our speed. if self.updateProgressBarID: self.parent.after_cancel(self.updateProgressBarID) self.progressBar["value"] = 0 self.update_progress_bar() #Progress bar timer and color changing method def update_progress_bar(self): #If our Steam guard controller object is set if self.steamGuardController: #Update progress bar and reset when value is 0. Set background to "warn" color when low on time or under 18 if self.progressBar["value"] == 0: self.guardLabel.config({ "text": str( self.steamGuardController.get_code( timestamp=self.steamGuardController.get_time())) }) self.progressBar["value"] = 58 self.barStyle.configure( "blue.Horizontal.TProgressbar", troughcolor=self.colorDic["progressBarBackground"], background=self.colorDic["progressBarForeground"]) self.guardLabel.configure( fg=self.colorDic["guardCodeForeground"], bg=self.colorDic["guardCodeBackground"]) self.steamNameLabel.config( fg=self.colorDic["steamNameForeground"], bg=self.colorDic["guardCodeBackground"]) self.guardCodeHolder.config( bg=self.colorDic["guardCodeBackground"]) elif self.progressBar["value"] <= 18: self.barStyle.configure( "blue.Horizontal.TProgressbar", troughcolor=self.colorDic["progressBarBackgroundWarn"], background=self.colorDic["progressBarForegroundWarn"]) self.guardLabel.configure( fg=self.colorDic["guardCodeForeground"], bg=self.colorDic["guardCodeBackgroundWarn"]) self.steamNameLabel.config( fg=self.colorDic["steamNameForegroundWarn"], bg=self.colorDic["guardCodeBackgroundWarn"]) self.guardCodeHolder.config( bg=self.colorDic["guardCodeBackgroundWarn"]) self.progressBar["value"] = self.progressBar["value"] - 1 self.updateProgressBarID = self.parent.after( 500, self.update_progress_bar)
def getSteamKey(): mnjson = app.config['STEAM_KEY'] mjson = json.loads(mnjson) authbean = SteamAuthenticator(mjson) steamcode = authbean.get_code() return steamcode
def cmd_authenticator_add(args): account = args.account.lower().strip() secrets_file = UserDataFile('authenticator/{}.json'.format(account)) sa = None if secrets_file.exists(): if not args.force: print( "There is already an authenticator for that account. Use --force to overwrite" ) return 1 # error sa = SteamAuthenticator(secrets_file.read_json()) print("To add an authenticator, first we need to login to Steam") print("Account name:", account) wa = BetterMWA(account) try: wa.bcli_login(sa_instance=sa) except (KeyboardInterrupt, EOFError): print("Login interrupted") return 1 # error print("Login successful. Checking pre-conditions...") sa = SteamAuthenticator(backend=wa) status = sa.status() _LOG.debug("Authenticator status: %s", status) if not status['email_validated']: print("Account needs a verified email address") return 1 # error if status['state'] == 1: print("This account already has an authenticator.") print("You need to remove it first, before proceeding") return 1 # error if not status['authenticator_allowed']: print("This account is now allowed to have authenticator") return 1 # error # check phone number, and add one if its missing if not sa.has_phone_number(): print("No phone number on this account. This is required.") if pmt_confirmation("Do you want to add a phone number?", default_yes=True): print("Phone number need to include country code and no spaces.") while True: phnum = pmt_input("Enter phone number:", regex=r'^(\+|00)[0-9]+$') resp = sa.validate_phone_number(phnum) _LOG.debug("Phone number validation for %r: %s", phnum, resp) if not resp.get('is_valid', False): print("That number is not valid for Steam.") continue if not sa.add_phone_number(phnum): print("Failed to add phone number!") continue print("Phone number added. Confirmation SMS sent.") while not sa.confirm_phone_number( pmt_input("Enter SMS code:", regex='^[0-9]+$')): print("Code was incorrect. Try again.") break else: # user declined adding a phone number, we cant proceed return 1 # error # being adding authenticator setup sa.add() _LOG.debug("Authenticator secrets obtained. Saving to disk") secrets_file.write_json(sa.secrets) # Setup Steam app in conjuction if pmt_confirmation("Do you want to use Steam app too?", default_yes=False): print("Great! Go and setup Steam Guard in your app.") print("Once completed, generate a code and enter it below.") showed_fail_info = False fail_counter = 0 while True: code = pmt_input( "Steam Guard code:", regex='^[23456789BCDFGHJKMNPQRTVWXYbcdfghjkmnpqrtvwxy]{5}$') # code match if sa.get_code() == code.upper(): break # success # code do not match else: fail_counter += 1 if fail_counter >= 3 and not showed_fail_info: showed_fail_info = True print("The codes do not match. This can be caused by:") print("* The code was not entered correctly") print("* Your system time is not synchronized") print("* Steam has made changes to their backend") if not pmt_confirmation("Code mismatch. Try again?", default_yes=True): _LOG.debug("Removing secrets file") secrets_file.remove() return 1 # failed, exit # only setup steamctl 2fa else: print( "Authenticator secrets obtained. SMS code for finalization sent.") while True: code = pmt_input("Enter SMS code:", regex='^[0-9]+$') try: sa.finalize(code) except SteamAuthenticatorError as exp: print("Finalization error: %s", exp) continue else: break # finish line print("Authenticator added successfully!") print("Get a code: {} authenticator code {}".format(__appname__, account)) print("Or QR code: {} authenticator qrcode {}".format( __appname__, account))
def get_code(): secrets = json.load(open('./mysecrets.json')) sa = SteamAuthenticator(secrets) TFAcode = sa.get_code() return TFAcode
class SteamClient: def __init__(self, username, password, secrets=None, deviceId=None): self.user = wa.WebAuth(username, password) if secrets is not None: self.mobile = wa.MobileWebAuth(username, password) self.sa = SteamAuthenticator(secrets) else: self.mobile = None self.sa = None self.deviceId = deviceId self.login() self.baseURL = 'https://steamcommunity.com' self.urlToId = {} self.SIDDB = requests.Session() print(f'Steam User: {self.user.steam_id.as_64} Logged.') def login(self): notDone = True while notDone: try: self.user.login() except wa.CaptchaRequired: print(self.user.captcha_url) self.user.login(captcha=input('Captcha: ')) notDone = False except wa.EmailCodeRequired: self.user.login(email_code=input('Email Code: ')) notDone = False except wa.TwoFactorCodeRequired: if self.sa is None: self.user.login(twofactor_code=input('Two-Factor Code: ')) else: self.user.login(twofactor_code=self.sa.get_code()) notDone = False self.steamId = self.user.steam_id if self.mobile is None: return timeToSleep = 30 - int(time.time() % 30) + 1 for i in tqdm(range(timeToSleep), desc='Waiting for next code'): time.sleep(1) notDone = True while notDone: try: self.mobile.login() except wa.CaptchaRequired: print(self.mobile.captcha_url) self.mobile.login(captcha=input('Captcha: ')) notDone = False except wa.EmailCodeRequired: self.mobile.login(email_code=input('Email Code: ')) notDone = False except wa.TwoFactorCodeRequired: self.mobile.login(twofactor_code=self.sa.get_code()) notDone = False return def validateWalletCode(self, code): payload = { 'sessionid': self.user.session.cookies.get_dict()['sessionid'], 'wallet_code': code } return self.user.session.post('https://store.steampowered.com/account/validatewalletcode/', data=payload).json() def redeemWalletCode(self, code): payload = { 'sessionid': self.user.session.cookies.get_dict()['sessionid'], 'wallet_code': code } return self.user.session.post('https://store.steampowered.com/account/confirmredeemwalletcode/', data=payload).json()
import json import sys from os import path from steam.guard import SteamAuthenticator if len(sys.argv) < 2: print("Usage: ", sys.argv[0], " username") sys.exit(1) username = sys.argv[1] data = json.load( open(path.expanduser('~/.config/steam-totp/%s.secrets.json' % username))) sa = SteamAuthenticator(secrets=data) print(sa.get_code())