Exemplo n.º 1
0
    def _add_otp(self, name=None, otp_type=None, secret=None):
        if not name:
            self.q.put([Action.ask_input, _("Add OTP to which password?"), "", "add_otp"])
        elif not otp_type:
            screenshot = pyscreenshot.grab(childprocess=False).convert('L')
            qr_codes = zbar.Scanner().scan(screenshot)
            autodetected = 0
            for qr_code in qr_codes:
                qr_data = qr_code.data.decode()
                try:
                    pyotp.parse_uri(qr_data)
                except ValueError:
                    continue

                autodetected += 1
                self._append_password(name, qr_data)

            if autodetected == 0:
                self.q.put([Action.add_error, _("Could not detect any valid OTP QR codes on your screen. Continuing with manual configuration...")])
                self.q.put([Action.ask_choice, _("Use which OTP type?"), ["TOTP", "HOTP"], "add_otp {}".format(name)])
            else:
                self.q.put([Action.add_message, _("Detected and added {} valid OTP QR code(s) on your screen.").format(str(autodetected))])
                return
        elif not secret:
            self.q.put([Action.ask_input, _("What is the OTP secret?"), "", "add_otp {} {}".format(name, otp_type)])
        else:
            if otp_type == "TOTP":
                otp_uri = pyotp.TOTP(secret).provisioning_uri()
            elif otp_type == "HOTP":
                otp_uri = pyotp.HOTP(secret).provisioning_uri()
            else:
                return

            self._append_password(name, otp_uri)
Exemplo n.º 2
0
    def _add_otp(self, name=None, otp_type=None, secret=None):
        if not hasattr(pyotp, "parse_uri"):
            self.q.put([
                Action.critical_error,
                _("pyotp lib doesn't support this yet")
            ])
            return
        if not name:
            self.q.put([
                Action.ask_input,
                _("What password should OTP be added to?"), "", "add_otp"
            ])
        elif not otp_type:
            screenshot = pyscreenshot.grab(childprocess=False).convert('L')
            qr_codes = zbar.Scanner().scan(screenshot)
            autodetected = 0
            for qr_code in qr_codes:
                qr_data = qr_code.data.decode()
                try:
                    pyotp.parse_uri(qr_data)
                except ValueError:
                    continue

                autodetected += 1
                self._append_password(name, qr_data)

            if autodetected == 0:
                self.q.put([
                    Action.add_error,
                    _("No valid OTP QR codes detected on your screen. Configuring manually…"
                      )
                ])
                self.q.put([
                    Action.ask_choice,
                    _("Which OTP type should be used?"), ["TOTP", "HOTP"],
                    "add_otp {}".format(name)
                ])
            else:
                self.q.put([
                    Action.add_message,
                    _("Detected and added {} valid OTP QR code(s) on your screen."
                      ).format(str(autodetected))
                ])
                return
        elif not secret:
            self.q.put([
                Action.ask_input,
                _("What is the OTP secret?"), "",
                "add_otp {} {}".format(name, otp_type)
            ])
        else:
            if otp_type == "TOTP":
                otp_uri = pyotp.TOTP(secret).provisioning_uri()
            elif otp_type == "HOTP":
                otp_uri = pyotp.HOTP(secret).provisioning_uri()
            else:
                return

            self._append_password(name, otp_uri)
Exemplo n.º 3
0
    def __init__(self, db_manager: DatabaseManager, entry: Entry) -> None:
        """GObject to handle a safe entry.

        :param DatabaseManager db_manager:  database of the entry
        :param Entry entry: entry to handle
        """
        super().__init__(db_manager, entry)

        self._entry: Entry = entry

        self._attachments: list[Attachment] = entry.attachments or []

        self._attributes: dict[str, str] = {
            key: value
            for key, value in entry.custom_properties.items()
            if key not in (self._color_key, self._note_key, self._otp_key)
        }

        color_value: str = entry.get_custom_property(self._color_key)
        self._color: str = color_value or EntryColor.NONE.value

        self._icon_nr: str = entry.icon or ""
        self._password: str = entry.password or ""
        self._url: str = entry.url or ""
        self._username: str = entry.username or ""

        otp_uri = entry.get_custom_property("otp")
        if otp_uri:
            try:
                self._otp = parse_uri(otp_uri)
            except ValueError as err:
                logging.debug(err)

        self._check_expiration()
Exemplo n.º 4
0
def generate(issuer):
    home = os.environ.get('HOME')

    with open('{}/totp.yaml'.format(home)) as file:
        contents = yaml.full_load(file.read())

        generator = pyotp.parse_uri(contents['totp'][issuer]['url'])
        click.secho(generator.now())
Exemplo n.º 5
0
def show(args):
    """Print out the contents of an entry to console"""

    kp = open_database(**vars(args))

    _, path = parse_path(args.path)
    entry = get_entry(kp, path)

    # show specified field
    if args.field:
        # handle lowercase field input gracefully
        field = get_field(entry, args.field)
        print(entry._get_string_field(field), end='')

    elif args.totp:
        if entry.otp is None:
            log.error(red("Entry has no OTP field"))
            sys.exit(1)
        import pyotp
        print(pyotp.parse_uri(entry.otp).now(), end='')

    # otherwise, show all fields
    else:
        print(green("Title: ") + (entry.title or ''))
        print(green("UserName: "******"Password: "******"URL: ") + (entry.url or ''))
        if entry.otp is not None:
            print(green("OTP: ") + (entry.otp or ''))
            import pyotp
            import qrcode
            # generate QR code for seed
            qr = qrcode.QRCode(
                error_correction=qrcode.constants.ERROR_CORRECT_L, border=1)
            qr.add_data(entry.otp)
            qr.print_ascii()
            print(green("OTP Code: ") + pyotp.parse_uri(entry.otp).now())
        # print custom fields
        for field_name, field_value in entry.custom_properties.items():
            print(green("{}: ".format(field_name)) + str(field_value or ''))

        print(green("Created: ") + entry.ctime.isoformat())
        print(green("Modified: ") + entry.mtime.isoformat())
Exemplo n.º 6
0
def generate_otp(username, otp_seed):
    """Generate a time based OTP using the OTP_SEED for the npm user
    It is used in 2 Factor Authentication for the user account
    Args:
        username (string): The username of the npm user
        otp_seed (string): The seed generated during 2 factor auth setup for the user
    """
    totp = pyotp.parse_uri(
        f'otpauth://totp/{username}?secret={otp_seed}&issuer=npm')
    otp = totp.now()
    return otp
Exemplo n.º 7
0
    def get_otp(self):
        if not self.mfa_string:
            return None

        otp = pyotp.parse_uri(self.mfa_string)

        # the library fails to cast the interval field to a number,
        # despite requiring that the field be a number
        otp.interval = int(otp.interval)

        return otp
Exemplo n.º 8
0
async def test_signin():
    otp = None
    if os.environ.get('OTP_URI'):
        import pyotp

        otp = pyotp.parse_uri(os.environ.get('OTP_URI'))

    from v2ex.utils import recognize_captcha_by_human

    me = await Me.signin(os.environ.get('USERNAME'),
                         os.environ.get('PASSWORD'),
                         recognize_captcha_by_human,
                         otp=otp)
    print(me.id)
Exemplo n.º 9
0
def main():
    args = parser.parse_args()

    f = open(args.password_file)
    pw = f.read().strip()

    kp = PyKeePass(args.kdbx, password=pw)

    entry = kp.find_entries(title=args.entry, first=True)

    uri = entry.get_custom_property("otp")

    totp = pyotp.parse_uri(uri)

    print(totp.now())
Exemplo n.º 10
0
    def _parse_otp(self, line):
        if not hasattr(pyotp, "parse_uri"):
            return

        try:
            otp = pyotp.parse_uri(line)
        except ValueError:
            return

        if isinstance(otp, pyotp.TOTP):
            otp_code = otp.now()
        else:
            otp_code = otp.generate_otp()

        return ("{} - {}".format(otp.issuer, otp.name)
                if otp.issuer else otp.name, otp_code)
Exemplo n.º 11
0
    def test_algorithms(self):
        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1')
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(0), '734055')
        self.assertEqual(otp.at(30), '662488')
        self.assertEqual(otp.at(60), '289363')
        self.assertEqual(otp.provisioning_uri(),
                         'otpauth://totp/Secret?secret=GEZDGNBV')
        self.assertEqual(otp.provisioning_uri(name='n', issuer_name='i'),
                         'otpauth://totp/i:n?secret=GEZDGNBV&issuer=i')

        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1&period=60'
        )
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(30), '734055')
        self.assertEqual(otp.at(60), '662488')
        self.assertEqual(
            otp.provisioning_uri(name='n', issuer_name='i'),
            'otpauth://totp/i:n?secret=GEZDGNBV&issuer=i&period=60')

        otp = pyotp.parse_uri(
            'otpauth://hotp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1')
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(0), '734055')
        self.assertEqual(otp.at(1), '662488')
        self.assertEqual(otp.at(2), '289363')
        self.assertEqual(
            otp.provisioning_uri(name='n', issuer_name='i'),
            'otpauth://hotp/i:n?secret=GEZDGNBV&issuer=i&counter=0')

        otp = pyotp.parse_uri(
            'otpauth://hotp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1&counter=1'
        )
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(0), '662488')
        self.assertEqual(otp.at(1), '289363')
        self.assertEqual(
            otp.provisioning_uri(name='n', issuer_name='i'),
            'otpauth://hotp/i:n?secret=GEZDGNBV&issuer=i&counter=1')

        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA256')
        self.assertEqual(hashlib.sha256, otp.digest)
        self.assertEqual(otp.at(0), '918961')
        self.assertEqual(otp.at(9000), '934470')

        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA512')
        self.assertEqual(hashlib.sha512, otp.digest)
        self.assertEqual(otp.at(0), '816660')
        self.assertEqual(otp.at(9000), '524153')
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
    def _display_results(self, results):
        while self.result_display_active:
            result_lines = results.rstrip().splitlines()
            self.passwordEntries = {}
            # Parse OTP
            for number, line in enumerate(result_lines):
                try:
                    otp = pyotp.parse_uri(line)
                except ValueError:
                    continue

                if isinstance(otp, pyotp.TOTP):
                    otp_code = otp.now()
                else:
                    otp_code = otp.generate_otp()

                otp_description = "{} - {}".format(
                    otp.issuer, otp.name) if otp.issuer else otp.name
                result_lines[number] = "OTP ({}): {}".format(
                    otp_description, otp_code)

            # If only a password and no other fields, select password immediately
            if len(result_lines) == 1:
                self.q.put([Action.copy_to_clipboard, result_lines[0]])
                self.q.put([Action.close])
                return

            for line in result_lines:
                if len(self.passwordEntries) == 0:
                    self.passwordEntries["********"] = line
                else:
                    self.passwordEntries[line] = line

            self.q.put(
                [Action.replace_entry_list, ["********"] + result_lines[1:]])

            if self.result_display_active:
                sleep(1)
Exemplo n.º 14
0
 def test_enable_totp_view(self):
     self.client.login(username='******', password='******')
     get_response = self.client.get(reverse('accounts:enable_totp'))
     self.assertEquals(get_response.status_code, 200)
     self.assertTemplateUsed(get_response, 'accounts/totp_form.html')
     self.assertEquals(get_response.request['PATH_INFO'],
                       '/accounts/enable-totp/')
     soup = BeautifulSoup(get_response.content, features="lxml")
     svg_container = soup.find("div", {"id": "svgcontainer"})
     self.assertIsNotNone(svg_container)
     scsvg = svg_container.findChild("svg", recursive=False)
     self.assertIsNotNone(scsvg)
     with open('qr.svg', 'w') as f:
         f.write("<?xml version='1.0' encoding='utf-8'?>\n" + str(scsvg))
     svg2png(url='qr.svg', write_to='qr.png', scale=8)
     t_image = Image.open('qr.png')
     t_image.load()
     background = Image.new("RGB", t_image.size, (255, 255, 255))
     background.paste(t_image, mask=t_image.split()[3])
     background.save('qr.jpg', "JPEG", quality=100)
     image = Image.open('qr.jpg')
     img_data = decode(image)
     qr_data = img_data[0].data.decode("utf-8")
     totp_code = pyotp.TOTP(pyotp.parse_uri(qr_data).secret).now()
     response = self.client.post(reverse('accounts:enable_totp'),
                                 {'totp_code': totp_code},
                                 follow=True)
     self.assertEquals(response.status_code, 200)
     self.assertTemplateUsed(response, 'base_form.html')
     self.assertEquals(response.request['PATH_INFO'],
                       '/accounts/edit-profile/')
     user_a = User.objects.get(username='******')
     self.assertTrue(user_a.account.use_totp)
     self.assertEquals(len(user_a.account.totp_key), 32)
     pathlib.Path('qr.svg').unlink()
     pathlib.Path('qr.png').unlink()
     pathlib.Path('qr.jpg').unlink()
Exemplo n.º 15
0
def type_entries(args):
    """Type out password using keyboard

    Selects an entry using `prog`, then sends the password to the keyboard.
    If `tabbed` is true, both the username and password are typed, separated
    by a tab.  If `totp` is true, generate and type totp.
    """

    from Xlib.error import DisplayNameError

    try:
        from pynput.keyboard import Controller, Key
    except DisplayNameError:
        log.error(red("No X11 session found"))

    # build up a dictionary mapping strings (shown in dmenu) to entries
    entry_texts = {}

    # type from all databases
    if args.name is None:
        databases = open_database(all=True, **vars(args))

        # generate multi-line string to send to dmenu
        for name, kp in databases:
            for entry in kp.entries:
                if entry.title:
                    if len(databases) > 1:
                        entry_text = "@{}/{}".format(name,
                                                     '/'.join(entry.path))
                    else:
                        entry_text = '/'.join(entry.path)
                    if args.username:
                        entry_text += " ({})".format(entry.username)
                    entry_texts[entry_text] = entry
        dmenu_text = '\n'.join(sorted(entry_texts.keys()))

    # type from specific database
    else:
        kp = open_database(**vars(args))
        for entry in kp.entries:
            if entry.title:
                entry_text = '/'.join(entry.path)
                if args.username:
                    entry_text += " ({})".format(entry.username)
                entry_texts[entry_text] = entry
        dmenu_text = '\n'.join(sorted(entry_texts.keys()))

    # get the entry from dmenu
    try:
        p = subprocess.Popen(args.prog,
                             stdout=subprocess.PIPE,
                             stdin=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
                             shell=True)
    except FileNotFoundError:
        log.error(bold(args.prog[0]) + red(" not found."))
        sys.exit(1)
    stdout = p.communicate(
        input=dmenu_text.encode('utf-8'))[0].decode('utf-8').rstrip('\n')
    log.debug("text from dmenu: {}".format(stdout))

    # if nothing was selected, return None
    if not stdout:
        log.warning("No path returned by {}".format(args.prog))
        return

    # kp = entry_texts[stdout]
    # _, selection_path = parse_path(stdout)
    # selected_entry = get_entry(kp, selection_path)

    selected_entry = entry_texts[stdout]

    log.debug("selected_entry:{}".format(selected_entry))

    def call_xdotool(args):
        try:
            subprocess.call(["xdotool"] + args)
        except FileNotFoundError:
            log.error(bold("xdotool ") + red("not found"))
            sys.exit(1)

    # type out username/password
    k = Controller()
    # parse OTP field and type
    if args.totp:
        otp = None
        if selected_entry.otp is not None:
            otp = pyotp.parse_uri(selected_entry.otp)
        if otp is not None:
            if args.xdotool:
                call_xdotool(['type', otp.now()])
            else:
                k.type(otp.now())
        else:
            log.error(red("Selected entry has no OTP field"))
            sys.exit(1)
    else:
        if args.tabbed:
            if selected_entry.username:
                if args.xdotool:
                    call_xdotool(['type', selected_entry.username])
                    call_xdotool(['key', 'Tab'])
                else:
                    k.type(selected_entry.username)
                    k.press(Key.tab)
                    k.release(Key.tab)
            else:
                log.warning("Selected entry does not have a username")
        # type out password only
        if selected_entry.password:
            if args.xdotool:
                call_xdotool(['type', selected_entry.password])
            else:
                k.type(selected_entry.password)
        else:
            log.warning("Selected entry does not have a password")
Exemplo n.º 16
0
    def selection_made(self, selection):
        if len(selection) == 0:
            # We're at the main menu
            self.passwordEntries = {}
            self.q.put([Action.set_header])
            self.q.put([Action.replace_command_list, []])
            self.q.put([Action.replace_entry_list, []])
            self._get_entries()
        elif selection[-1]["type"] == SelectionType.none:
            # Global context menu option
            if selection[-1]["context_option"] == _("Create"):
                self._insert()
                self.q.put([Action.set_selection, []])
                return
            elif selection[-1]["context_option"] == _("Generate"):
                self._generate()
                self.q.put([Action.set_selection, []])
                return
            else:
                self.q.put([Action.critical_error, _("Unexpected selection_made value: {}").format(selection)])
        elif len(selection) == 1:
            if selection[0]["type"] == SelectionType.entry:
                if selection[0]["context_option"] == _("Edit"):
                    self._edit(name=selection[0]["value"])
                    self.q.put([Action.set_selection, []])
                    return
                elif selection[0]["context_option"] == _("Copy"):
                    self._copy(name=selection[0]["value"])
                    self.q.put([Action.set_selection, []])
                    return
                elif selection[0]["context_option"] == _("Rename"):
                    self._rename(name=selection[0]["value"])
                    self.q.put([Action.set_selection, []])
                    return
                elif selection[0]["context_option"] == _("Remove"):
                    self._remove(selection[0]["value"])
                    self.q.put([Action.set_selection, []])
                    return
                elif selection[0]["context_option"] == _("Add OTP"):
                    self._add_otp(selection[0]["value"])
                    self.q.put([Action.set_selection, []])
                    return

                results = self.password_store.get_decrypted_password(selection[0]["value"])
                if results is None:
                    self.q.put([Action.set_selection, []])
                    return

                self.q.put([Action.replace_entry_list, []])
                self.q.put([Action.replace_command_list, []])

                result_lines = results.rstrip().splitlines()

                # Parse OTP
                for number, line in enumerate(result_lines):
                    try:
                        otp = pyotp.parse_uri(line)
                    except ValueError:
                        continue

                    if isinstance(otp, pyotp.TOTP):
                        otp_code = otp.now()
                    else:
                        otp_code = otp.generate_otp()

                    result_lines[number] = "OTP: {}".format(otp_code)

                # If only a password and no other fields, select password immediately
                if len(result_lines) == 1:
                    self.q.put([Action.copy_to_clipboard, result_lines[0]])
                    self.q.put([Action.close])
                    return

                for line in result_lines:
                    if len(self.passwordEntries) == 0:
                        self.passwordEntries["********"] = line
                        self.q.put([Action.add_entry, "********"])
                    else:
                        self.passwordEntries[line] = line
                        self.q.put([Action.add_entry, line])
            else:
                self.q.put([Action.critical_error, _("Unexpected selection_made value: {}").format(selection)])
        elif len(selection) == 2:
            # We're selecting a password
            if selection[1]["value"] == "********":
                self.q.put([Action.copy_to_clipboard, self.passwordEntries["********"]])
            else:
                # Get the final part to prepare for copying. For example, if
                # the entry is named URL: https://example.org/", only copy
                # "https://example.org/" to the clipboard
                copyStringParts = self.passwordEntries[selection[1]["value"]].split(": ", 1)

                copyString = copyStringParts[1] if len(copyStringParts) > 1 else copyStringParts[0]
                self.q.put([Action.copy_to_clipboard, copyString])

            self.passwordEntries = {}
            self.q.put([Action.close])
        else:
            self.q.put([Action.critical_error, _("Unexpected selection_made value: {}").format(selection)])
Exemplo n.º 17
0
    def test_algorithms(self):
        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1')
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(0), '734055')
        self.assertEqual(otp.at(30), '662488')
        self.assertEqual(otp.at(60), '289363')
        self.assertEqual(otp.provisioning_uri(),
                         'otpauth://totp/Secret?secret=GEZDGNBV')
        self.assertEqual(otp.provisioning_uri(name='n', issuer_name='i'),
                         'otpauth://totp/i:n?secret=GEZDGNBV&issuer=i')

        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1&period=60'
        )
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(30), '734055')
        self.assertEqual(otp.at(60), '662488')
        self.assertEqual(
            otp.provisioning_uri(name='n', issuer_name='i'),
            'otpauth://totp/i:n?secret=GEZDGNBV&issuer=i&period=60')

        otp = pyotp.parse_uri(
            'otpauth://hotp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1')
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(0), '734055')
        self.assertEqual(otp.at(1), '662488')
        self.assertEqual(otp.at(2), '289363')
        self.assertEqual(
            otp.provisioning_uri(name='n', issuer_name='i'),
            'otpauth://hotp/i:n?secret=GEZDGNBV&issuer=i&counter=0')

        otp = pyotp.parse_uri(
            'otpauth://hotp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA1&counter=1'
        )
        self.assertEqual(hashlib.sha1, otp.digest)
        self.assertEqual(otp.at(0), '662488')
        self.assertEqual(otp.at(1), '289363')
        self.assertEqual(
            otp.provisioning_uri(name='n', issuer_name='i'),
            'otpauth://hotp/i:n?secret=GEZDGNBV&issuer=i&counter=1')

        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA256')
        self.assertEqual(hashlib.sha256, otp.digest)
        self.assertEqual(otp.at(0), '918961')
        self.assertEqual(otp.at(9000), '934470')

        otp = pyotp.parse_uri(
            'otpauth://totp?algorithm=SHA1&secret=GEZDGNBV&algorithm=SHA512')
        self.assertEqual(hashlib.sha512, otp.digest)
        self.assertEqual(otp.at(0), '816660')
        self.assertEqual(otp.at(9000), '524153')

        self.assertEqual(
            otp.provisioning_uri(name='n',
                                 issuer_name='i',
                                 image='https://test.net/test.png'),
            'otpauth://totp/i:n?secret=GEZDGNBV&issuer=i&algorithm=SHA512&image=https%3A%2F%2Ftest.net%2Ftest.png'
        )
        with self.assertRaises(ValueError):
            otp.provisioning_uri(name='n', issuer_name='i', image='nourl')

        otp = pyotp.parse_uri(
            otp.provisioning_uri(name='n',
                                 issuer_name='i',
                                 image='https://test.net/test.png'))
        self.assertEqual(hashlib.sha512, otp.digest)
Exemplo n.º 18
0
    def test_provisioning_uri(self):
        hotp = pyotp.HOTP('wrn3pqx5uqxqvnqr', name='mark@percival')

        url = urlparse(hotp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'hotp')
        self.assertEqual(url.path, '/mark%40percival')
        self.assertEqual(dict(parse_qsl(url.query)), {
            'secret': 'wrn3pqx5uqxqvnqr',
            'counter': '0'
        })
        self.assertEqual(
            hotp.provisioning_uri(),
            pyotp.parse_uri(hotp.provisioning_uri()).provisioning_uri())

        hotp = pyotp.HOTP('wrn3pqx5uqxqvnqr',
                          name='mark@percival',
                          initial_count=12)
        url = urlparse(hotp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'hotp')
        self.assertEqual(url.path, '/mark%40percival')
        self.assertEqual(dict(parse_qsl(url.query)), {
            'secret': 'wrn3pqx5uqxqvnqr',
            'counter': '12'
        })
        self.assertEqual(
            hotp.provisioning_uri(),
            pyotp.parse_uri(hotp.provisioning_uri()).provisioning_uri())

        hotp = pyotp.HOTP('wrn3pqx5uqxqvnqr',
                          name='mark@percival',
                          issuer='FooCorp!')
        url = urlparse(hotp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'hotp')
        self.assertEqual(url.path, '/FooCorp%21:mark%40percival')
        self.assertEqual(dict(parse_qsl(url.query)), {
            'secret': 'wrn3pqx5uqxqvnqr',
            'counter': '0',
            'issuer': 'FooCorp!'
        })
        self.assertEqual(
            hotp.provisioning_uri(),
            pyotp.parse_uri(hotp.provisioning_uri()).provisioning_uri())

        key = 'c7uxuqhgflpw7oruedmglbrk7u6242vb'
        hotp = pyotp.HOTP(key,
                          digits=8,
                          digest=hashlib.sha256,
                          name='baco@peperina',
                          issuer='FooCorp')
        url = urlparse(hotp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'hotp')
        self.assertEqual(url.path, '/FooCorp:baco%40peperina')
        self.assertEqual(
            dict(parse_qsl(url.query)), {
                'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb',
                'counter': '0',
                'issuer': 'FooCorp',
                'digits': '8',
                'algorithm': 'SHA256'
            })
        self.assertEqual(
            hotp.provisioning_uri(),
            pyotp.parse_uri(hotp.provisioning_uri()).provisioning_uri())

        hotp = pyotp.HOTP(key,
                          digits=8,
                          name='baco@peperina',
                          issuer='Foo Corp',
                          initial_count=10)
        url = urlparse(hotp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'hotp')
        self.assertEqual(url.path, '/Foo%20Corp:baco%40peperina')
        self.assertEqual(
            dict(parse_qsl(url.query)), {
                'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb',
                'counter': '10',
                'issuer': 'Foo Corp',
                'digits': '8'
            })
        self.assertEqual(
            hotp.provisioning_uri(),
            pyotp.parse_uri(hotp.provisioning_uri()).provisioning_uri())

        code = pyotp.totp.TOTP("S46SQCPPTCNPROMHWYBDCTBZXV")
        self.assertEqual(
            code.provisioning_uri(),
            "otpauth://totp/Secret?secret=S46SQCPPTCNPROMHWYBDCTBZXV")
        code.verify("123456")
        self.assertEqual(
            code.provisioning_uri(),
            "otpauth://totp/Secret?secret=S46SQCPPTCNPROMHWYBDCTBZXV")
Exemplo n.º 19
0
    def test_invalids(self):
        with self.assertRaises(ValueError) as cm:
            pyotp.parse_uri('http://hello.com')
        self.assertEqual('Not an otpauth URI', str(cm.exception))

        with self.assertRaises(ValueError) as cm:
            pyotp.parse_uri('otpauth://totp')
        self.assertEqual('No secret found in URI', str(cm.exception))

        with self.assertRaises(ValueError) as cm:
            pyotp.parse_uri('otpauth://derp?secret=foo')
        self.assertEqual('Not a supported OTP type', str(cm.exception))

        with self.assertRaises(ValueError) as cm:
            pyotp.parse_uri('otpauth://totp?foo=secret')
        self.assertEqual('foo is not a valid parameter', str(cm.exception))

        with self.assertRaises(ValueError) as cm:
            pyotp.parse_uri('otpauth://totp?digits=-1')
        self.assertEqual('Digits may only be 6, 7, or 8', str(cm.exception))

        with self.assertRaises(ValueError) as cm:
            pyotp.parse_uri('otpauth://totp/SomeIssuer:?issuer=AnotherIssuer')
        self.assertEqual(
            'If issuer is specified in both label and parameters, it should be equal.',
            str(cm.exception))

        with self.assertRaises(ValueError) as cm:
            pyotp.parse_uri('otpauth://totp?algorithm=aes')
        self.assertEqual(
            'Invalid value for algorithm, must be SHA1, SHA256 or SHA512',
            str(cm.exception))
Exemplo n.º 20
0
    def test_provisioning_uri(self):
        totp = pyotp.TOTP('wrn3pqx5uqxqvnqr', name='mark@percival')
        url = urlparse(totp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'totp')
        self.assertEqual(url.path, '/mark%40percival')
        self.assertEqual(dict(parse_qsl(url.query)),
                         {'secret': 'wrn3pqx5uqxqvnqr'})
        self.assertEqual(
            totp.provisioning_uri(),
            pyotp.parse_uri(totp.provisioning_uri()).provisioning_uri())

        totp = pyotp.TOTP('wrn3pqx5uqxqvnqr',
                          name='mark@percival',
                          issuer='FooCorp!')
        url = urlparse(totp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'totp')
        self.assertEqual(url.path, '/FooCorp%21:mark%40percival')
        self.assertEqual(dict(parse_qsl(url.query)), {
            'secret': 'wrn3pqx5uqxqvnqr',
            'issuer': 'FooCorp!'
        })
        self.assertEqual(
            totp.provisioning_uri(),
            pyotp.parse_uri(totp.provisioning_uri()).provisioning_uri())

        key = 'c7uxuqhgflpw7oruedmglbrk7u6242vb'
        totp = pyotp.TOTP(key,
                          digits=8,
                          interval=60,
                          digest=hashlib.sha256,
                          name='baco@peperina',
                          issuer='FooCorp')
        url = urlparse(totp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'totp')
        self.assertEqual(url.path, '/FooCorp:baco%40peperina')
        self.assertEqual(
            dict(parse_qsl(url.query)), {
                'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb',
                'issuer': 'FooCorp',
                'digits': '8',
                'period': '60',
                'algorithm': 'SHA256'
            })
        self.assertEqual(
            totp.provisioning_uri(),
            pyotp.parse_uri(totp.provisioning_uri()).provisioning_uri())

        totp = pyotp.TOTP(key,
                          digits=8,
                          interval=60,
                          name='baco@peperina',
                          issuer='FooCorp')
        url = urlparse(totp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'totp')
        self.assertEqual(url.path, '/FooCorp:baco%40peperina')
        self.assertEqual(
            dict(parse_qsl(url.query)), {
                'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb',
                'issuer': 'FooCorp',
                'digits': '8',
                'period': '60'
            })
        self.assertEqual(
            totp.provisioning_uri(),
            pyotp.parse_uri(totp.provisioning_uri()).provisioning_uri())

        totp = pyotp.TOTP(key,
                          digits=8,
                          name='baco@peperina',
                          issuer='FooCorp')
        url = urlparse(totp.provisioning_uri())
        self.assertEqual(url.scheme, 'otpauth')
        self.assertEqual(url.netloc, 'totp')
        self.assertEqual(url.path, '/FooCorp:baco%40peperina')
        self.assertEqual(
            dict(parse_qsl(url.query)), {
                'secret': 'c7uxuqhgflpw7oruedmglbrk7u6242vb',
                'issuer': 'FooCorp',
                'digits': '8'
            })
        self.assertEqual(
            totp.provisioning_uri(),
            pyotp.parse_uri(totp.provisioning_uri()).provisioning_uri())
Exemplo n.º 21
0
def _get_token(response):
    totp_uri = response.json()["totp_uri"]
    totp = pyotp.parse_uri(totp_uri)
    return totp.now()
Exemplo n.º 22
0
 def is_valid_otp_string(self, mfa_string):
     try:
         pyotp.parse_uri(mfa_string)
         return True
     except ValueError:
         return False