def login_from_args(self, args, print_status=True): result = None if not args.anonymous and not args.user: last = UserDataFile('client/lastuser') if last.exists(): args.user = last.read_full() if args.anonymous or not args.user: self._LOG.info("Attempting anonymous login") return self.anonymous_login() if args.user: self._LOG.info("Attempting login as: %s" % args.user) self.username = args.user userkey = UserDataFile('client/%s.key' % self.username) if userkey.exists(): self.login_key = userkey.read_full() result = self.relogin() if result == EResult.InvalidPassword: self._LOG.info("Remembered login has expired") userkey.remove() if not self.logged_on: result = self.cli_login(self.user) return result
def cmd_webapi_set(args): keyfile = UserDataFile('apikey.txt', 'w') if args.key: with keyfile as fp: fp.write(args.key) if keyfile.exists(): print("Current key:", keyfile.read_full()) else: print("Current key: NOT SET")
def cmd_authenticator_status(args): account = args.account.lower().strip() secrets_file = UserDataFile('authenticator/{}.json'.format(account)) sa = None wa = BetterMWA(account) if secrets_file.exists(): sa = SteamAuthenticator(secrets_file.read_json(), backend=wa) try: wa.bcli_login(sa_instance=sa) except (KeyboardInterrupt, EOFError): print("Login interrupted") return 1 # error if sa is None: sa = SteamAuthenticator(backend=wa) status = sa.status() print("----- Status ------------") mode = status['steamguard_scheme'] if mode == 0: print("Steam Guard mode: disabled/insecure") elif mode == 1: print("Steam Guard mode: enabled (email)") elif mode == 2: print("Steam Guard mode: enabled (authenticator)") else: print("Steam Guard mode: unknown ({})".format(mode)) print("Authenticator enabled:", "Yes" if status['state'] == 1 else "No") print("Authenticator allowed:", "Yes" if status['state'] else "No") print("Email verified:", "Yes" if status['email_validated'] else "No") print("External allowed:", "Yes" if status['allow_external_authenticator'] else "No") if status['state'] == 1: print("----- Token details -----") print("Token GID:", status['token_gid']) print("Created at:", fmt_datetime(status['time_created'])) print("Device identifier:", status['device_identifier']) print("Classified agent:", status['classified_agent']) print("Revocation attempts remaining:", status['revocation_attempts_remaining'])
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 cmd_authenticator_add(args): account = args.account.lower().strip() secrets_file = UserDataFile('authenticator/{}.json'.format(account)) if secrets_file.exists(): print("There is already an authenticator for that account") return 1 # error print("To add an authenticator, first we need to login to Steam") print("Account name:", account) wa = BetterMWA(account) try: wa.bcli_login() except (KeyboardInterrupt, EOFError): print("Login interrupted") return 1 # error print("Login successful. Checking pre-conditions...") sa = SteamAuthenticator(backend=wa) # 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) 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("To get a code run: {} authenticator code {}".format(__appname__, account))
def login_from_args(self, args, print_status=True): result = None # anonymous login if args.anonymous and not args.user: self._LOG.info("Attempting anonymous login") return self.anonymous_login() # user login user = args.user lastFile = UserDataFile('client/lastuser') # check for previously used user if not user and lastFile.exists(): user = lastFile.read_text() if user: self._LOG.info("Reusing previous username: %s", user) self._LOG.info( "Hint: use 'steamctl --user <username> ...' to change") else: self._LOG.debug("lastuser file is empty?") lastFile.remove() if user: # attempt login self.username = user if not lastFile.exists() or lastFile.read_text() != self.username: lastFile.write_text(self.username) # check for userkey and login without a prompt userkey = UserDataFile('client/%s.key' % self.username) if userkey.exists(): self._LOG.info("Attempting login with remembered credentials") self.login_key = userkey.read_text() result = self.relogin() self._LOG.debug("Re-login result is: %s", repr(EResult(result))) if result == EResult.InvalidPassword: self._LOG.info("Remembered credentials have expired") userkey.remove() else: return result self.sleep(0.1) # attempt manual cli login if not self.logged_on: if self.username: self._LOG.info("Enter credentials for: %s", self.username) else: self._LOG.info("Enter Steam login") result = self.cli_login(self.username) if not lastFile.exists() or lastFile.read_text() != self.username: lastFile.write_text(self.username) self._LOG.debug("Login result is: %s", repr(EResult(result))) if not self.relogin_available: self.wait_event(self.EVENT_NEW_LOGIN_KEY, timeout=10) return result