mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2026-03-15 17:37:22 +01:00
Add TOTP secret to user_key hash
thanks @downtownallday * this invalidates all user_keys after TOTP status is changed for user * after changing TOTP state, a login is required * due to the forced login, we can't and don't need to store the code used for setup in `mru_code`
This commit is contained in:
@@ -3,7 +3,7 @@ import base64, os, os.path, hmac
|
||||
from flask import make_response
|
||||
|
||||
import utils, totp
|
||||
from mailconfig import get_mail_password, get_mail_user_privileges
|
||||
from mailconfig import get_mail_password, get_mail_user_privileges, get_mfa_state
|
||||
|
||||
DEFAULT_KEY_PATH = '/var/lib/mailinabox/api.key'
|
||||
DEFAULT_AUTH_REALM = 'Mail-in-a-Box Management Server'
|
||||
@@ -136,15 +136,23 @@ class KeyAuthService:
|
||||
|
||||
def create_user_key(self, email, env):
|
||||
# Store an HMAC with the client. The hashed message of the HMAC will be the user's
|
||||
# email address & hashed password and the key will be the master API key. The user of
|
||||
# course has their own email address and password. We assume they do not have the master
|
||||
# API key (unless they are trusted anyway). The HMAC proves that they authenticated
|
||||
# with us in some other way to get the HMAC. Including the password means that when
|
||||
# email address & hashed password and the key will be the master API key. If TOTP
|
||||
# is active, the key will also include the TOTP secret. The user of course has their
|
||||
# own email address and password. We assume they do not have the master API key
|
||||
# (unless they are trusted anyway). The HMAC proves that they authenticated with us
|
||||
# in some other way to get the HMAC. Including the password means that when
|
||||
# a user's password is reset, the HMAC changes and they will correctly need to log
|
||||
# in to the control panel again. This method raises a ValueError if the user does
|
||||
# not exist, due to get_mail_password.
|
||||
msg = b"AUTH:" + email.encode("utf8") + b" " + get_mail_password(email, env).encode("utf8")
|
||||
return hmac.new(self.key.encode('ascii'), msg, digestmod="sha256").hexdigest()
|
||||
|
||||
mfa_state = get_mfa_state(email, env)
|
||||
hash_key = self.key.encode('ascii')
|
||||
|
||||
if mfa_state['type'] == 'totp':
|
||||
hash_key = hash_key + mfa_state['secret'].encode('ascii')
|
||||
|
||||
return hmac.new(hash_key, msg, digestmod="sha256").hexdigest()
|
||||
|
||||
def _generate_key(self):
|
||||
raw_key = os.urandom(32)
|
||||
|
||||
Reference in New Issue
Block a user