def show(ctx: click.Context, serial: str, interactive: bool) -> None: secret = ctx.obj.get_secret(serial) totp = TOTP(secret, digits=8) if interactive: click.echo("Ctrl-C to exit") while True: token = totp.now() sys.stdout.write("\r" + token) sys.stdout.flush() sleep(1) else: click.echo(totp.now())
def test_google_authenticator_delete(self): from talos.models import ValidationToken from talos.models import OneTimePasswordCredentialDirectory from talos.models import OneTimePasswordCredential from pyotp import TOTP self.create_user() self.login() self.add_evidence_sms() response = self.client.post(self.request_url, {}, format='json') self.assertResponseStatus(response, status.HTTP_403_FORBIDDEN) self.add_evidence_google() response = self.client.post(self.request_url, {}, format='json') self.assertResponseStatus(response, status.HTTP_200_OK) validation_token = ValidationToken.objects.last() self.assertEqual(validation_token.principal, self.principal) self.assertEqual(validation_token.type, 'otp_delete') sms_otp_directory = OneTimePasswordCredentialDirectory.objects.get( code='onetimepassword_internal_phone_sms') google_otp_directory = OneTimePasswordCredentialDirectory.objects.get( code='onetimepassword_internal_google_authenticator') sms_otp_credential = OneTimePasswordCredential.objects.get( principal=self.principal, directory=sms_otp_directory) google_otp_credential = OneTimePasswordCredential.objects.get( principal=self.principal, directory=google_otp_directory) totp = TOTP(sms_otp_credential.salt.decode()) sms_code = totp.now() totp = TOTP(google_otp_credential.salt) google_code = totp.now() data = { 'otp_code': sms_code, 'google_otp_code': google_code, 'password': self.password, 'token': validation_token.secret } response = self.client.post(self.confirm_url, data, format='json') self.assertResponseStatus(response, status.HTTP_200_OK) self.assertEqual( OneTimePasswordCredential.objects.filter( directory=google_otp_directory).count(), 0)
def test_change_email_when_wrong_password(self): from pyotp import TOTP self.create_user() self.login() self.add_evidence_sms() self.generate_sms_code(self.principal) validation_token = ValidationToken.objects.create( identifier='email', identifier_value=self.email, principal=self.principal, type='email_change', ) code = (OneTimePasswordCredential.objects.last()) totp = TOTP(code.salt.decode()) data = { 'sms_code': totp.now(), 'password': '******', 'secret': validation_token.secret } response = self.client.put(self.email_change_insecure_url, data=data) self.assertResponseStatus(response, status.HTTP_400_BAD_REQUEST) self.assertListEqual( response.data.get('error').get('password'), ['password_invalid']) self.assertListEqual( response.data.get('details').get('password'), ['Password is incorrect'])
def test_password_change_secure(self): from talos.models import OneTimePasswordCredential from talos.models import Principal from pyotp import TOTP self.create_user() self.login() self.add_evidence_google() self.assertEqual(OneTimePasswordCredential.objects.all().count(), 1) google_otp_credential = OneTimePasswordCredential.objects.last() secret = google_otp_credential.salt totp = TOTP(secret) google_otp_code = totp.now() data = { 'password': self.password, 'new_password': '******', 'otp_code': google_otp_code } response = self.client.put(self.url, data, format='json') self.assertResponseStatus(response, status.HTTP_200_OK) principal = Principal.objects.last() self.assertFalse(principal.check_password(self.password)) self.assertTrue(principal.check_password('1234567'))
def main(): token = input("Please input your token found on your android: ") data = list(bytes.fromhex(token)) assert len(data) == len(masks) # xor every byte with masks for i in range(0, len(data)): b = data[i] m = masks[i] b = b ^ m data[i] = b data_str = bytes(data).decode() secret_hex = data_str[:40] serial = data_str[40:] # use base32 to encode the first 40 bytes to be used in totp secret = base64.b32encode(bytes.fromhex(secret_hex)).decode() from pyotp import TOTP totp = TOTP(secret, digits=8) key = totp.now() print(secret) print(serial) print(key) url = "otpauth://totp/{0}:{0}?secret={1}&issuer={0}&digits=8".format( serial, secret) print(url)
def test_change_email_when_success(self): from pyotp import TOTP self.create_user() self.login() self.add_evidence_sms() self.generate_sms_code(self.principal) email_to_change = "*****@*****.**" validation_token = ValidationToken.objects.create( identifier='email', identifier_value=email_to_change, principal=self.principal, type='email_change', ) code = (OneTimePasswordCredential.objects.last()) totp = TOTP(code.salt.decode()) data = { 'otp_code': totp.now(), 'password': self.password, 'secret': validation_token.secret } response = self.client.put(self.email_change_insecure_url, data=data) changed_pricipal = Principal.objects.last() self.assertResponseStatus(response) self.assertEquals(changed_pricipal.email, email_to_change)
def main(): parser = ArgumentParser(path.basename(__file__)) parser.add_argument('--source-url', required=True) parser.add_argument('--journo-url', required=True) args = parser.parse_args() totp = TOTP('JHCOGO7VCER3EJ4L') auth = UserPassOtp('journalist', 'WEjwn8ZyczDhQSK24YKM8C9a', totp.now()) client = Client(args.journo_url, auth)
class Code: password = None def __init__(self, secret_code): self.secret_code = secret_code self.create() @staticmethod def is_valid(code): """ Check if the secret code is a valid one """ try: b32decode(code, casefold=True) return True except (binascii.Error, ValueError): return False def create(self): """ Create a tfa code """ try: self.totp = TOTP(self.secret_code) self.password = self.totp.now() except Exception as e: logging.error("Couldn't generate two factor code : %s" % str(e)) def update(self): """ Update the code """ self.password = self.totp.now() def get_secret_code(self): try: if self.password: return self.password else: raise AttributeError except AttributeError as e: logging.error("Couldn't generate the code : %s " % str(e)) return None
class GuildBank(Handler): def __init__(self, log_to_file, bank_channel_id, bank_role_id, totp_secret): super().__init__() self._log_to_file = log_to_file self._bank_channel_id = bank_channel_id self._bank_role_id = bank_role_id self._totp = TOTP(totp_secret) self.bank_roles = [] self.bank_channels = [] # Checks that a user is permitted to access the guild bank and responds # accordingly. async def process_message(self, message): if message.channel in self.bank_channels: response = None # Check that requester is a member of guild bank role if any(role in self.bank_roles for role in message.author.roles): justification = message.content[4:].strip() # Check that a justification is present if justification: await self._bot.send_message(message.author, self._totp.now()) response = ('{user} has accessed guild bank 2FA: ' '{justification}').format( user=message.author.mention, justification=justification) else: response = 'Missing justification for guild bank access.' else: response = ( '{user} is not permitted to access guild bank.').format( user=message.author.mention) await self._bot.send_message(message.channel, response) # Write to file if requested if self._log_to_file: dt = datetime.utcnow() with open(dt.date().isoformat() + '.log', 'a+') as f: f.write(dt.timetz().isoformat() + ' ' + (message.author.nick or message.author.name) + ': ' + response + '\n') def client_ready(self): for server in self._bot.servers: for role in server.roles: if role.id == self._bank_role_id: self.bank_roles.append(role) for channel in server.channels: if channel.id == self._bank_channel_id: self.bank_channels.append(channel) def command_triggers(self): return ['!2fa']
def test_2fa(self): """The authentication should be failed because otp is not correct.""" from pyotp import TOTP otp = TOTP(self.secret.secret) query = { "username": "******", "password": "******", "otp_auth": str((int(otp.now()) + 1) % 1000000).zfill(6) } form = self.form_cls(None, query) self.assertFalse(form.is_valid()) self.assertTrue(form.errors)
class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.totp = TOTP(get_secret()) self.totp_qr = get_secret_qr(self.totp) self.create_widgets() self.pack() self.update_pin_label() self.set_scheduler() def create_widgets(self) -> None: # TOTP qrcode widget self.totp_qr_label = tk.Label(self) self.totp_qr_label['image'] = self.totp_qr self.totp_qr_label.grid(row=0, column=0, columnspan=2) # TOTP pin text, it change every 30 seconds self.pin_label_text = tk.StringVar() self.pin_label_text.set('Wait...') # TOTP pin widget pin_label = tk.Entry(self) pin_label['font'] = 'monospace 20 bold' pin_label['state'] = 'readonly' pin_label['textvariable'] = self.pin_label_text pin_label.grid(row=1, column=0) # Quit widget new_secret_btn = tk.Button(self) new_secret_btn['font'] = 'monospace 20' new_secret_btn['fg'] = 'red' new_secret_btn['text'] = 'NEW SECRET!' new_secret_btn['command'] = self.set_secret_and_update_pin_label new_secret_btn.grid(row=1, column=1) # Update pin label def update_pin_label(self) -> None: self.pin_label_text.set(self.totp.now()) # Set scheduler to update pin label every 30 seconds def set_scheduler(self) -> None: scheduler = BackgroundScheduler() scheduler.start() scheduler.add_job(self.update_pin_label, trigger='cron', second=0) scheduler.add_job(self.update_pin_label, trigger='cron', second=30) # Set new secret and update the GUI def set_secret_and_update_pin_label(self) -> None: self.totp = TOTP(set_secret()) self.totp_qr = get_secret_qr(self.totp) self.totp_qr_label['image'] = self.totp_qr self.update_pin_label()
class OTP(GeneratedSecret): """One Time Password Generates a secret that changes over time that generally is used as a second factor when authenticating. It can act as a replacement for, and is fully compatible with, Google Authenticator or Authy. You would provide the text version of the shared secret that is presented to you when first configuring your second factor authentication. See :ref:`otp` for more information. Only available if pyotp is installed (pip install pyotp). Args: shared_secret (str): The shared secret in base32. interval (int): Update interval in seconds. Use 30 to mimic Google Authenticator, 10 to mimic Authy. digits (int): Number of digits to output, choose between 6, 7, or 8. Use 6 to mimic Google Authenticator, 7 to mimic Authy. """ def __init__(self, shared_secret, interval=30, digits=6): self.interval = interval self.digits = digits try: shared_secret = shared_secret.render() except AttributeError: pass try: b32decode(str(shared_secret), casefold=True) except BinasciiError: raise PasswordError('invalid value specified to OTP: %s.' % str(shared_secret), culprit=error_source()) self.shared_secret = shared_secret self.is_secret = False # no need to conceal OTPs as they are ephemeral def initialize(self, account, field_name, field_key=None): self.totp = TOTP(self.shared_secret, interval=self.interval, digits=self.digits) def render(self): return self.totp.now() # __repr__() {{{2 def __repr__(self): # this is used to create the archive, archive the shared secret # rather than OTP return "OTP({!r})".format(self.shared_secret)
def test_2fa(self): """2fa should be valid.""" from pyotp import TOTP otp = TOTP(self.secret.secret) query = { "username": "******", "password": "******", "otp_auth": otp.now() } form = self.form_cls(None, query) self.assertTrue(form.is_valid(), "Form is invalid: {}".format(dict(form.errors))) self.assertDictEqual(query, form.clean())
def _enable_virtual_mfa(self, serial_number, seed): enable_mfa_url = f'{self._api_url}/enableMfaDevice' totp = TOTP(seed) self.logger.debug('Calculating the first totp.') authentication_code_1 = totp.now() self.logger.debug('Waiting 30 seconds for the next totp.') time.sleep(30) authentication_code_2 = totp.now() enable_payload = { 'authenticationCode1': authentication_code_1, 'authenticationCode2': authentication_code_2, 'serialNumber': serial_number, 'userName': '' } self.logger.debug('Trying to enable the virtual mfa.') response = self.session.post(enable_mfa_url, json=enable_payload) if not response.ok: raise UnableToEnableVirtualMFA(response.text) self.logger.info( f'Successfully enabled mfa device with serial number "{serial_number}"' ) return VirtualMFADevice(seed, serial_number)
def test_clear_evidences_for_other_users(self): from datetime import datetime, timedelta from talos.models import OneTimePasswordCredential from talos.models import Principal from talos.models import Session from django.db.models import Q from pyotp import TOTP self.create_user() self.login() self.add_evidence_sms() self.assertEqual(OneTimePasswordCredential.objects.all().count(), 1) sms_otp_credential = OneTimePasswordCredential.objects.last() totp = TOTP(sms_otp_credential.salt.decode()) sms_code = totp.now() data = { 'password': self.password, 'new_password': '******', 'otp_code': sms_code } Session.objects.create(principal=self.principal, evidences='evidences') Session.objects.create(principal=self.principal, evidences='evidences') # Add another Session where valid_till is invalid (less than current time) Session.objects.create(principal=self.principal, evidences='evidences', valid_till=datetime.now() - timedelta(hours=24)) self.assertEqual(4, Session.objects.all().count()) response = self.client.put(self.url, data, format='json') self.assertResponseStatus(response, status.HTTP_200_OK) principal = Principal.objects.last() self.assertFalse(principal.check_password(self.password)) self.assertTrue(principal.check_password('1234567')) # Two row has been updated correctly (principal, valid_till) self.assertEqual( 2, Session.objects.filter(principal=self.principal, evidences=None).count()) self.assertEqual( 2, Session.objects.filter(Q(principal=self.principal), ~Q(evidences=None)).count())
def get_profile(**options): instpector = Instpector() # Using pyotp for getting the two-factor authentication code totp = TOTP(options.get("two_factor_key")) if not instpector.login(user=options.get("user"), password=options.get("password"), two_factor_code=totp.now()): return profile = endpoints.factory.create("profile", instpector) print(profile.of_user("dwgran")) instpector.logout()
class Code: def __init__(self, token): self._token = token self._secret_code = None self.create() @staticmethod def is_valid(token): """Validate a token.""" try: b32decode(token, casefold=True) return True except (binascii.Error, ValueError): return False def create(self): """ Create a tfa code """ try: self._totp = TOTP(self._token) self._secret_code = self._totp.now() except Exception as e: logging.error("Couldn't generate two factor code : %s" % str(e)) def update(self): """ Update the code """ self._secret_code = self._totp.now() @property def secret_code(self): if self._secret_code: return self._secret_code return None
def generate_otp(): try: phone = request.args.get('phone', None) app.logger.info(f'Phone: {phone}') shared_key = random_base32() app.logger.info(f'Shared key: {shared_key}') totp = TOTP(shared_key, interval=interval) code = totp.now() app.logger.info(f'Otp code: {code}') return jsonify({ 'ok': True, 'message': f'Code sent to {phone}', 'shared_key': shared_key }) except Exception as error: app.logger.error(f'Exception {error}') return ('Error', 500)
def disable_2fa(user, password, totp_secret, base_url): prefix = "/vpn-admin-portal" admin_url = base_url + prefix browser = mechanicalsoup.StatefulBrowser(raise_on_404=True) logger.info("opening auth_url") response = browser.open(admin_url) assert response.ok browser.select_form() browser["userName"] = user browser["userPass"] = password logger.info("logging in") response = browser.submit_selected() assert response.ok form = browser.select_form() if form.form.attrs['action'] != prefix + '/_two_factor/auth/verify/totp': logger.warning("2fa not enabled") return # redirected to totp screen totp = TOTP(totp_secret) browser['_two_factor_auth_totp_key'] = totp.now() logger.info("submitting totp key") response = browser.submit_selected() assert response.ok form = browser.select_form() if form.form.attrs['action'] == prefix + '/_two_factor/auth/verify/totp': error = browser.get_current_page().findAll( "p", {"class": "error"})[0].contents[0].strip() raise EduvpnAuthException(error) response = browser.open("{}/user?user_id={}".format(admin_url, user)) assert response.ok form = browser.select_form() button = form.form.select('button[value="deleteTotpSecret"]') if button: response = browser.submit_selected() assert (response.ok) else: logger.error(form.form) logger.error("2fa not enabled, but had to supply otp during login")
def test_add_evidence_google(self): from talos.models import OneTimePasswordCredentialDirectory from talos.models import OneTimePasswordCredential from talos.models import Principal from pyotp import TOTP self.create_user() self.login() principal = Principal.objects.last() otp_diretory = OneTimePasswordCredentialDirectory.objects.get( code='onetimepassword_internal_google_authenticator') otp_diretory.create_credentials(principal, {}) self.assertEqual(OneTimePasswordCredential.objects.all().count(), 1) otp_credential = OneTimePasswordCredential.objects.last() secret = otp_credential.salt totp = TOTP(secret) code = totp.now() data = {'otp_code': code} response = self.client.post(self.url, data, format='json') self.assertResponseStatus(response, status.HTTP_200_OK) # Try incorrect data data = {'otp_code': 'aaaa'} response = self.client.post(self.url, data, format='json') self.assertResponseStatus(response, status.HTTP_400_BAD_REQUEST) self.assertTrue(response.data.get('error').get('otp_code', False)) self.assertEqual( response.data.get('error').get('otp_code')[0], constants.GOOGLE_OTP_INVALID_CODE)
def main(): secret_or_uri = '' line_end = '\n' terminal = sys.stdin.isatty() if not terminal: secret_or_uri = sys.stdin.read().strip() line_end = '' if not secret_or_uri and terminal: secret_or_uri = getpass(prompt='Secret or URI: ', stream=None).strip() try: totp = parse_uri(secret_or_uri) except ValueError: totp = TOTP(secret_or_uri) try: print(totp.now(), end=line_end) except binascii.Error: print('Invalid 2FA secret', end=line_end)
def topt(self): self.driver.get("#totp").is_displayed() img = self.driver.get('#kc-totp-secret-qr-code').get_attribute('src') # download the qr code image current_dir = Path(__file__) bceid_png = Path(f"{current_dir.parent}/bceid.png") urlretrieve(img, bceid_png.name) # read the qr code from the image and get the secret reader = zxing.BarCodeReader() barcode = reader.decode(bceid_png.name) parsed = urlparse(barcode.parsed) query = parse_qs(parsed.query) qr_secret = query['secret'][0] # bceid_png.unlink() # generate token totp = TOTP(qr_secret) token = totp.now() self.driver.get('#totp').type(token) self.driver.get('.btn-primary').click()
def add_evidence_google(self): from talos.models import OneTimePasswordCredentialDirectory from talos.models import OneTimePasswordCredential from pyotp import TOTP add_evidence_google_url = reverse('add-evidence-google') otp_directory = OneTimePasswordCredentialDirectory.objects.get( code='onetimepassword_internal_google_authenticator') otp_directory.create_credentials(self.principal, {}) otp_credential = OneTimePasswordCredential.objects.last() self.assertIsNotNone(otp_credential) secret = otp_credential.salt totp = TOTP(secret) google_otp_code = totp.now() data = {'otp_code': google_otp_code} self.client.post(add_evidence_google_url, data, format='json')
def generateOtp(request,loggedInUserProfile,groupSearched): ########Generation of otp and saving it in database loggedInUser=wallet.objects.filter(username=loggedInUserProfile.username.username) loggedInUser=loggedInUser[0] TOTPinput=str(datetime.now()) TOTPinput=base64.b32encode(TOTPinput.encode()) TOTPinput=TOTPinput.decode() totp=TOTP(TOTPinput) totp.interval=180 otp=totp.now() loggedInUser.otp=codecs.encode(pickle.dumps(totp),"base64").decode() ########################################################## print("generate otp") print(otp) requestToBeSaved = [] requestToBeSaved.append(requestTypes[0]) requestToBeSaved.append(loggedInUser.username.username) requestToBeSaved.append(groupSearched.groupName) loggedInUser.request=json.dumps(requestToBeSaved) #####Sending email email_subject = 'Continue Payment' message = render_to_string('send_otp.html', { 'otp':otp, }) to_email = loggedInUser.username.email print(to_email) email = EmailMessage(email_subject, message, to=[to_email]) email.send() ################### loggedInUser.save() return render(request,'groupOtp.html')
def generate_credentials(self, principal, credentials): from ..models import _tznow from pyotp import TOTP from talos.models import OneTimePasswordCredential from ..contrib.sms_sender import SMSSender try: otp_credential = self._credential_directory.credentials.get( principal=principal, valid_from__lte=_tznow(), valid_till__gte=_tznow()) secret_key = otp_credential.salt.decode() totp = TOTP(secret_key) sms_sender = SMSSender() sms_sender.send_message(principal.phone, 'Your registraion code is %s' % totp.now()) return True except OneTimePasswordCredential.DoesNotExist: pass return False
def main(): parser = ArgumentParser() parser.add_argument("search_string", nargs='?', default='', help="Optional search string.") args = parser.parse_args() homedir = expanduser("~") with open(homedir + '/.2fa.yml') as f: totp_data = safe_load(f) for i in totp_data: try: account = i['account'] username = i['username'] key = i['key'] otp = TOTP(key) print("%s %s\t(%s)" % (otp.now(), account, username)) except KeyError as e: print("No such key found.") pprint(e)
def test_add_google_authentictor(self): from talos.models import OneTimePasswordCredentialDirectory from talos.models import OneTimePasswordCredential from pyotp import TOTP self.create_user() self.login() self.add_evidence_sms() data = {'password': self.password} response = self.client.post(self.request_url, data, format='json') self.assertResponseStatus(response, status.HTTP_200_OK) self.assertTrue(response.data.get('result').get('secret', False)) secret = response.data.get('result').get('secret') totp = TOTP(secret) code = totp.now() data = {'code': code} #self.assertFalse(self.principal.profile.is_secure) response = self.client.post(self.confirm_url, data, format='json') self.assertResponseStatus(response, status.HTTP_201_CREATED) google_otp_directory = OneTimePasswordCredentialDirectory.objects.get( code='onetimepassword_internal_google_authenticator') otp_credential = OneTimePasswordCredential.objects.last() self.assertEqual(otp_credential.directory, google_otp_directory) self.assertEqual(otp_credential.principal, self.principal) self.assertEqual(otp_credential.salt.decode(), secret) principal = Principal.objects.get(pk=self.principal.pk)
def slash(): payload = {'text': ''} if request.form['token'] != SLACK_TOKEN: payload['text'] = 'Sorry, I did not understand your command.' return jsonify(payload) command = request.form['text'].split(' ') command_type = command[0] if command_type == 'add': name = command[1] token = command[2] name_normal = re.sub("[^A-Za-z0-9-]+", "", name) add_new_token(token, name_normal) payload['text'] = f'Successfully set up token for {name_normal}' return jsonify(payload) if command_type == 'get': name = command[1] try: token = get_token(name) totp = TOTP(token) passcode = totp.now() payload['text'] = f'One time password for {name} is {passcode}' except: payload['text'] = "Error: Token doesn't exist." finally: return jsonify(payload) payload['text'] = 'Sorry, I did not understand your command' return jsonify(payload)
def add_evidence_sms(self): from talos.models import OneTimePasswordCredentialDirectory from talos.models import OneTimePasswordCredential from pyotp import TOTP add_evidence_sms_url = reverse('add-evidence-sms') if self.principal is None: raise Exception( 'Please run create_user() login() before this function') otp_directory = OneTimePasswordCredentialDirectory.objects.get( code='onetimepassword_internal_phone_sms') otp_directory.create_credentials(self.principal, {}) otp_credential = OneTimePasswordCredential.objects.last() self.assertIsNotNone(otp_credential) totp = TOTP(otp_credential.salt.decode()) data = {'otp_code': totp.now()} self.client.post(add_evidence_sms_url, data, format='json')
class Application(Wrapper, Updatable): """Representation of a Gem integration. Attributes: api_token (str) totp (pyotp.TOTP): A TOTP MFA token generator (initialized with set_totp) users (round.Users): A collection of Users who have an active device authorization on this Application. """ def set_totp(self, totp_secret): """Set the secret for generating MFA tokens to authorize Args: totp_secret (str): The secret token set on an Application in the Gem Developer Console. """ self.totp = TOTP(totp_secret) return self def get_mfa(self): """Return the currently-valid MFA token for this application.""" token = str(self.totp.now()) # PyOTP doesn't pre-pad tokens shorter than 6 characters # ROTP does, so we have to. while len(token) < 6: token = '0{}'.format(token) return token def reset(self, *args): """Resets any of the tokens for this Application. Note that you may have to reauthenticate afterwards. Usage: application.reset('api_token') application.reset('api_token', 'totp_secret') Args: *args (list of str): one or more of ['api_token', 'subscription_token', 'totp_secret'] Returns: The Application. """ self.resource = self.resource.reset(list(args)) return self @property @cacheable def users(self): """Returned the cached Users associated with this application.""" return self.get_users() def get_users(self, fetch=True): """Return this Applications's users object, populating it if fetch is True.""" return Users(self.resource.users, self.client, populate=fetch) @property @cacheable def wallets(self): """Returned the cached Wallets associated with this application.""" return self.get_wallets() def get_wallets(self, fetch=False): """Return this Applications's wallets object, populating it if fetch is True.""" return Wallets( self.resource.wallets, self.client, populate=fetch, application=self) @property @cacheable def subscriptions(self): """Return the cached Subscriptions object for this Application.""" return self.get_subscriptions() def get_subscriptions(self, fetch=True): """Return this Application's subscriptions object, populating it if fetch is True.""" return Subscriptions( self.resource.subscriptions, self.client, populate=fetch) def wallet(self, key): return self.client.wallet(key, application=self) @property @cacheable def netki_domains(self): """Fetch and return an updated list of NetkiDomains inside this Application.""" return self.get_netki_domains() def get_netki_domains(self, fetch=False): """Return the Applications NetkiDomains object, populating it if fetch is True.""" return NetkiDomains( self.resource.netki_domains, self.client, populate=fetch)
class Application(Wrapper, Updatable): """Representation of a Gem integration. Attributes: api_token (str) totp (pyotp.TOTP): A TOTP MFA token generator (initialized with set_totp) users (round.Users): A collection of Users who have an active device authorization on this Application. """ def set_totp(self, totp_secret): """Set the secret for generating MFA tokens to authorize Args: totp_secret (str): The secret token set on an Application in the Gem Developer Console. """ self.totp = TOTP(totp_secret) return self def get_mfa(self): """Return the currently-valid MFA token for this application.""" return self.totp.now() def reset(self, *args): """Resets any of the tokens for this Application. Note that you may have to reauthenticate afterwards. Usage: application.reset('api_token') application.reset('api_token', 'totp_secret') Args: *args (list of str): one or more of ['api_token', 'subscription_token', 'totp_secret'] Returns: The Application. """ self.resource = self.resource.reset(list(args)) return self @property def users(self): if not hasattr(self, '_users'): users_resource = self.resource.users self._users = users.Users(users_resource, self.client) return self._users @property def wallets(self): """Fetch and return Wallets associated with this application.""" if not hasattr(self, '_wallets'): wallets_resource = self.resource.wallets self._wallets = Wallets(wallets_resource, self.client, self) return self._wallets @property def subscriptions(self): """Fetch and return Subscriptions associated with this account.""" if not hasattr(self, '_subscriptions'): subscriptions_resource = self.resource.subscriptions self._subscriptions = Subscriptions( subscriptions_resource, self.client) return self._subscriptions
from pyotp import TOTP import requests def run(token, outfile): print('running') payload = {'token': token} r = requests.post('http://127.0.0.1:8000/', payload) print(r.status_code) with open(outfile, 'w') as f: f.write(r.text) if(__name__ == '__main__'): totp = TOTP("longpassword2") run(totp.now(), 'success.html') run('666666', 'fail.html') run('', 'empty.html')
# Stop advertising subprocess.call("sudo hcitool -i hci0 cmd 0x08 0x000a 00", shell=True, stdout=DEVNULL) # Set message subprocess.call("sudo hcitool -i hci0 cmd 0x08 0x0008 " + message, shell=True, stdout=DEVNULL) # Resume advertising subprocess.call("sudo hcitool -i hci0 cmd 0x08 0x000a 01", shell=True, stdout=DEVNULL) def stopAdvertising(): print("Stopping advertising") verboseOutput("Stopping advertising") subprocess.call("sudo hcitool -i hci0 cmd 0x08 0x000a 00", shell=True, stdout=DEVNULL) try: if options.stop: stopAdvertising() else: while(True): otp = str(totp.now()) print(otp) advertise(url + otp) time.sleep(1) except Exception as e: sys.stderr.write("Exception: " + str(e) + "\n") exit(1)
class Safe(): """Stores the encrypted password for a determined period. This class stores the enctypted password, provides a passphrase and token and returns the encrypted password when provided the valid token""" def __init__(self): pass def encrypt(self, password, minutes): """Encrypts the user password. Parameters ---------- password : str The password to encrypt minutes : int The validity period, in minutes, of the TOTP token used to retreive the encrypted password. Returns ------- passphrase : str The passhprase used to derive the encryption key. token : str The TOTP token required to retreive the encrypted password. """ self._window = 60 * int(minutes) # Generate TOTP source self._totp = TOTP(random_base32(), interval=1) # Generate TOTP token token = self._totp.now() # Generate passphrase and derive key from passphrase passphrase = Passphrase().generate(PASSPHRASE_N_WORDS) key = _generate_key(passphrase) # Encrypt password using key f = Fernet(key) self._password = f.encrypt(password.encode('utf-8')) return passphrase, token def get_password(self, token): """Returns the encrypted password, provided a valid TOTP token. Parameters ---------- token : str The TOTP token required to retreive the encrypted password. Returns ------- password : str The encrypted password. Raises ------ InvalidToken If the provided TOTP token is invalid or expired. """ token = token.replace(' ', '') if self._totp.verify(token, valid_window=self._window): return self._password else: raise InvalidToken('Invalid TOTP token.')