Skip to content
Snippets Groups Projects
Commit 565b05bb authored by Julian's avatar Julian
Browse files

Support for python3-fido2 v0.9.x (Debian Bullseye)

parent caf09ca2
Branches
Tags
No related merge requests found
......@@ -103,13 +103,24 @@ def delete_totp(id): #pylint: disable=redefined-builtin
return redirect(url_for('mfa.setup'))
# WebAuthn support is optional because fido2 has a pretty unstable
# interface (v0.5.0 on buster and current version are completely
# incompatible) and might be difficult to install with the correct version
# interface and might be difficult to install with the correct version
try:
import fido2
if fido2.__version__.startswith('0.5.'):
from fido2.client import ClientData
from fido2.server import Fido2Server, RelyingParty
from fido2.server import Fido2Server, RelyingParty as PublicKeyCredentialRpEntity
from fido2.ctap2 import AttestationObject, AuthenticatorData
from fido2 import cbor
cbor.encode = cbor.dumps
cbor.decode = lambda arg: cbor.loads(arg)[0]
elif fido2.__version__.startswith('0.9.'):
from fido2.client import ClientData
from fido2.webauthn import PublicKeyCredentialRpEntity
from fido2.server import Fido2Server
from fido2.ctap2 import AttestationObject, AuthenticatorData
from fido2 import cbor
else:
raise ImportError(f'Unsupported fido2 version: {fido2.__version__}')
WEBAUTHN_SUPPORTED = True
except ImportError as err:
warn(_('2FA WebAuthn support disabled because import of the fido2 module failed (%s)')%err)
......@@ -119,7 +130,9 @@ bp.add_app_template_global(WEBAUTHN_SUPPORTED, name='webauthn_supported')
if WEBAUTHN_SUPPORTED:
def get_webauthn_server():
return Fido2Server(RelyingParty(current_app.config.get('MFA_RP_ID', urllib.parse.urlsplit(request.url).hostname), current_app.config['MFA_RP_NAME']))
hostname = urllib.parse.urlsplit(request.url).hostname
return Fido2Server(PublicKeyCredentialRpEntity(current_app.config.get('MFA_RP_ID', hostname),
current_app.config['MFA_RP_NAME']))
@bp.route('/setup/webauthn/begin', methods=['POST'])
@login_required()
......@@ -140,14 +153,14 @@ if WEBAUTHN_SUPPORTED:
user_verification='discouraged',
)
session["webauthn-state"] = state
return cbor.dumps(registration_data)
return cbor.encode(registration_data)
@bp.route('/setup/webauthn/complete', methods=['POST'])
@login_required()
@csrf_protect(blueprint=bp)
def setup_webauthn_complete():
server = get_webauthn_server()
data = cbor.loads(request.get_data())[0]
data = cbor.decode(request.get_data())
client_data = ClientData(data["clientDataJSON"])
att_obj = AttestationObject(data["attestationObject"])
auth_data = server.register_complete(session["webauthn-state"], client_data, att_obj)
......@@ -156,7 +169,7 @@ if WEBAUTHN_SUPPORTED:
db.session.commit()
request.user.update_groups()
ldap.session.commit()
return cbor.dumps({"status": "OK"})
return cbor.encode({"status": "OK"})
@bp.route("/auth/webauthn/begin", methods=["POST"])
@login_required_pre_mfa(no_redirect=True)
......@@ -167,7 +180,7 @@ if WEBAUTHN_SUPPORTED:
abort(404)
auth_data, state = server.authenticate_begin(creds, user_verification='discouraged')
session["webauthn-state"] = state
return cbor.dumps(auth_data)
return cbor.encode(auth_data)
@bp.route("/auth/webauthn/complete", methods=["POST"])
@login_required_pre_mfa(no_redirect=True)
......@@ -176,7 +189,7 @@ if WEBAUTHN_SUPPORTED:
creds = [method.cred for method in request.user_pre_mfa.mfa_webauthn_methods]
if not creds:
abort(404)
data = cbor.loads(request.get_data())[0]
data = cbor.decode(request.get_data())
credential_id = data["credentialId"]
client_data = ClientData(data["clientDataJSON"])
auth_data = AuthenticatorData(data["authenticatorData"])
......@@ -193,7 +206,7 @@ if WEBAUTHN_SUPPORTED:
)
session['user_mfa'] = True
set_request_user()
return cbor.dumps({"status": "OK"})
return cbor.encode({"status": "OK"})
@bp.route('/setup/webauthn/<int:id>/delete')
@login_required()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment