Exemple #1
0
def test_activate():
    user_id = db_utils.create_user()
    tfa_secret = pyotp.random_base32()
    totp = pyotp.TOTP(tfa_secret)

    # Failed validation between tfa_secret/tfa_response
    assert not tfa.activate(user_id, tfa_secret, "000000")
    # Verify 2FA is not active
    assert not d.engine.scalar("""
        SELECT twofa_secret
        FROM login
        WHERE userid = %(userid)s
    """,
                               userid=user_id)

    # Validation successful, and tfa_secret written into user's `login` record
    tfa_response = totp.now()
    assert tfa.activate(user_id, tfa_secret, tfa_response)
    # The stored twofa_secret must not be plaintext
    stored_secret = d.engine.scalar("""
        SELECT twofa_secret
        FROM login
        WHERE userid = %(userid)s
    """,
                                    userid=user_id)
    assert tfa_secret != stored_secret
    # The stored secret must be decryptable to the generated tfa_secret
    assert tfa_secret == tfa._decrypt_totp_secret(stored_secret)
def test_activate():
    user_id = db_utils.create_user()
    tfa_secret = pyotp.random_base32()
    totp = pyotp.TOTP(tfa_secret)

    # Failed validation between tfa_secret/tfa_response
    assert not tfa.activate(user_id, tfa_secret, "000000")
    # Verify 2FA is not active
    assert not d.engine.scalar("""
        SELECT twofa_secret
        FROM login
        WHERE userid = %(userid)s
    """, userid=user_id)

    # Validation successful, and tfa_secret written into user's `login` record
    tfa_response = totp.now()
    assert tfa.activate(user_id, tfa_secret, tfa_response)
    # The stored twofa_secret must not be plaintext
    stored_secret = d.engine.scalar("""
        SELECT twofa_secret
        FROM login
        WHERE userid = %(userid)s
    """, userid=user_id)
    assert tfa_secret != stored_secret
    # The stored secret must be decryptable to the generated tfa_secret
    assert tfa_secret == tfa._decrypt_totp_secret(stored_secret)
Exemple #3
0
def tfa_init_verify_post_(request):
    # Extract parameters from the form
    verify_checkbox = 'verify' in request.params
    tfasecret = _get_totp_code_from_session()
    tfarecoverycodes = _get_recovery_codes_from_session()

    # Does the user want to proceed with enabling 2FA?
    if verify_checkbox and tfa.store_recovery_codes(request.userid,
                                                    tfarecoverycodes):
        # Strip any spaces from the TOTP code (some authenticators display the digits like '123 456')
        tfaresponse = request.params['tfaresponse'].replace(' ', '')

        # TOTP+2FA Secret validates (activate & redirect to status page)
        if tfa.activate(request.userid, tfasecret, tfaresponse):
            # Invalidate all other login sessions
            invalidate_other_sessions(request.userid)
            # Clean up the stored session variables
            _cleanup_session()
            raise HTTPSeeOther(location="/control/2fa/status")
        # TOTP+2FA Secret did not validate
        else:
            return Response(
                define.webpage(request.userid,
                               "control/2fa/init_verify.html",
                               [tfarecoverycodes.split(','), "2fa"],
                               title="Enable 2FA: Final Step"))
    # The user didn't check the verification checkbox (despite HTML5's client-side check); regenerate codes & redisplay
    elif not verify_checkbox:
        return Response(
            define.webpage(request.userid,
                           "control/2fa/init_verify.html",
                           [tfarecoverycodes.split(','), "verify"],
                           title="Enable 2FA: Final Step"))
Exemple #4
0
def test_2fa_changes_token(app):
    user = db_utils.create_user(username='******', password='******')

    resp = app.get('/')
    csrf = resp.html.find('html')['data-csrf-token']

    assert tfa.store_recovery_codes(user,
                                    ','.join(tfa.generate_recovery_codes()))
    tfa_secret = pyotp.random_base32()
    totp = pyotp.TOTP(tfa_secret)
    tfa_response = totp.now()
    assert tfa.activate(user, tfa_secret, tfa_response)

    old_cookie = app.cookies['WZL']
    resp = app.post('/signin', {
        'token': csrf,
        'username': '******',
        'password': '******'
    })
    new_csrf = resp.html.find('html')['data-csrf-token']
    assert app.cookies['WZL'] != old_cookie
    assert new_csrf != csrf
    assert not d.engine.scalar(
        "SELECT EXISTS (SELECT 0 FROM sessions WHERE userid = %(user)s)",
        user=user)
    assert d.engine.scalar(
        "SELECT EXISTS (SELECT 0 FROM sessions WHERE additional_data->'2fa_pwd_auth_userid' = %(user)s::text)",
        user=user)
Exemple #5
0
def tfa_init_verify_post_(request):
    # Extract parameters from the form
    verify_checkbox = 'verify' in request.params
    tfasecret = _get_totp_code_from_session()
    tfaresponse = request.params['tfaresponse']
    tfarecoverycodes = _get_recovery_codes_from_session()

    # Does the user want to proceed with enabling 2FA?
    if verify_checkbox and tfa.store_recovery_codes(request.userid, tfarecoverycodes):
        # Strip any spaces from the TOTP code (some authenticators display the digits like '123 456')
        tfaresponse = request.params['tfaresponse'].replace(' ', '')

        # TOTP+2FA Secret validates (activate & redirect to status page)
        if tfa.activate(request.userid, tfasecret, tfaresponse):
            # Invalidate all other login sessions
            invalidate_other_sessions(request.userid)
            # Clean up the stored session variables
            _cleanup_session()
            raise HTTPSeeOther(location="/control/2fa/status")
        # TOTP+2FA Secret did not validate
        else:
            return Response(define.webpage(request.userid, "control/2fa/init_verify.html", [
                tfarecoverycodes.split(','),
                "2fa"
            ], title="Enable 2FA: Final Step"))
    # The user didn't check the verification checkbox (despite HTML5's client-side check); regenerate codes & redisplay
    elif not verify_checkbox:
        return Response(define.webpage(request.userid, "control/2fa/init_verify.html", [
            tfarecoverycodes.split(','),
            "verify"
        ], title="Enable 2FA: Final Step"))
Exemple #6
0
def test_2fa_changes_token(app):
    user = db_utils.create_user(username='******', password='******')

    resp = app.get('/')
    csrf = resp.html.find('html')['data-csrf-token']

    assert tfa.store_recovery_codes(user, ','.join(tfa.generate_recovery_codes()))
    tfa_secret = pyotp.random_base32()
    totp = pyotp.TOTP(tfa_secret)
    tfa_response = totp.now()
    assert tfa.activate(user, tfa_secret, tfa_response)

    old_cookie = app.cookies['WZL']
    resp = app.post('/signin', {'token': csrf, 'username': '******', 'password': '******'})
    new_csrf = resp.html.find('html')['data-csrf-token']
    assert app.cookies['WZL'] != old_cookie
    assert new_csrf != csrf
    assert not d.engine.scalar("SELECT EXISTS (SELECT 0 FROM sessions WHERE userid = %(user)s)", user=user)
    assert d.engine.scalar("SELECT EXISTS (SELECT 0 FROM sessions WHERE additional_data->'2fa_pwd_auth_userid' = %(user)s::text)", user=user)