move permissions module password hashing to utils/security.py
This commit is contained in:
parent
9ce21a30eb
commit
cca3817537
2 changed files with 17 additions and 15 deletions
|
@ -1,7 +1,6 @@
|
||||||
#--depends-on commands
|
#--depends-on commands
|
||||||
|
|
||||||
import base64, binascii, os
|
import base64, binascii, os
|
||||||
import scrypt
|
|
||||||
from src import EventManager, ModuleManager, utils
|
from src import EventManager, ModuleManager, utils
|
||||||
|
|
||||||
HOSTMASKS_SETTING = "hostmask-account"
|
HOSTMASKS_SETTING = "hostmask-account"
|
||||||
|
@ -25,15 +24,9 @@ class Module(ModuleManager.BaseModule):
|
||||||
if hostmask in server._hostmasks:
|
if hostmask in server._hostmasks:
|
||||||
del server._hostmasks[hostmask]
|
del server._hostmasks[hostmask]
|
||||||
|
|
||||||
def _make_salt(self):
|
|
||||||
return base64.b64encode(os.urandom(64)).decode("utf8")
|
|
||||||
|
|
||||||
def _random_password(self):
|
|
||||||
return binascii.hexlify(os.urandom(32)).decode("utf8")
|
|
||||||
|
|
||||||
def _make_hash(self, password, salt=None):
|
def _make_hash(self, password, salt=None):
|
||||||
salt = salt or self._make_salt()
|
salt = salt or utils.security.salt()
|
||||||
hash = base64.b64encode(scrypt.hash(password, salt)).decode("utf8")
|
hash = utils.security.hash(salt, password)
|
||||||
return hash, salt
|
return hash, salt
|
||||||
|
|
||||||
def _get_hash(self, server, account):
|
def _get_hash(self, server, account):
|
||||||
|
@ -42,7 +35,7 @@ class Module(ModuleManager.BaseModule):
|
||||||
return hash, salt
|
return hash, salt
|
||||||
|
|
||||||
def _master_password(self):
|
def _master_password(self):
|
||||||
master_password = self._random_password()
|
master_password = utils.security.password()
|
||||||
hash, salt = self._make_hash(master_password)
|
hash, salt = self._make_hash(master_password)
|
||||||
self.bot.set_setting("master-password", [hash, salt])
|
self.bot.set_setting("master-password", [hash, salt])
|
||||||
return master_password
|
return master_password
|
||||||
|
@ -162,8 +155,7 @@ class Module(ModuleManager.BaseModule):
|
||||||
saved_hash, saved_salt = self.bot.get_setting("master-password",
|
saved_hash, saved_salt = self.bot.get_setting("master-password",
|
||||||
(None, None))
|
(None, None))
|
||||||
if saved_hash and saved_salt:
|
if saved_hash and saved_salt:
|
||||||
given_hash, _ = self._make_hash(event["args"], saved_salt)
|
if utils.security.hash_verify(saved_salt, event["args"], saved_hash):
|
||||||
if utils.security.constant_time_compare(given_hash, saved_hash):
|
|
||||||
self.bot.del_setting("master-password")
|
self.bot.del_setting("master-password")
|
||||||
event["user"]._master_admin = True
|
event["user"]._master_admin = True
|
||||||
event["stdout"].write("Master login successful")
|
event["stdout"].write("Master login successful")
|
||||||
|
@ -212,8 +204,7 @@ class Module(ModuleManager.BaseModule):
|
||||||
|
|
||||||
hash, salt = self._get_hash(event["server"], account)
|
hash, salt = self._get_hash(event["server"], account)
|
||||||
if hash and salt:
|
if hash and salt:
|
||||||
attempt, _ = self._make_hash(password, salt)
|
if utils.security.hash_verify(salt, password, hash):
|
||||||
if utils.security.constant_time_compare(attempt, hash):
|
|
||||||
event["user"]._account_override = account
|
event["user"]._account_override = account
|
||||||
self._has_identified(event["server"], event["user"], account)
|
self._has_identified(event["server"], event["user"], account)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import base64, hmac, socket, ssl, typing
|
import base64, binascii, hmac, os, socket, ssl, typing
|
||||||
|
|
||||||
def ssl_context(cert: str=None, key: str=None, verify: bool=True
|
def ssl_context(cert: str=None, key: str=None, verify: bool=True
|
||||||
) -> ssl.SSLContext:
|
) -> ssl.SSLContext:
|
||||||
|
@ -25,6 +25,17 @@ def ssl_wrap(sock: socket.socket, cert: str=None, key: str=None,
|
||||||
def constant_time_compare(a: typing.AnyStr, b: typing.AnyStr) -> bool:
|
def constant_time_compare(a: typing.AnyStr, b: typing.AnyStr) -> bool:
|
||||||
return hmac.compare_digest(a, b)
|
return hmac.compare_digest(a, b)
|
||||||
|
|
||||||
|
import scrypt
|
||||||
|
def password(byte_n: int=32):
|
||||||
|
return binascii.hexlify(os.urandom(byte_n)).decode("utf8")
|
||||||
|
def salt(byte_n: int=64) -> bytes:
|
||||||
|
return base64.b64encode(os.urandom(byte_n)).decode("utf8")
|
||||||
|
def hash(given_salt: str, data: str):
|
||||||
|
return base64.b64encode(scrypt.hash(data, given_salt)).decode("utf8")
|
||||||
|
def hash_verify(salt: str, data: str, compare: str):
|
||||||
|
given_hash = hash(salt, data)
|
||||||
|
return constant_time_compare(given_hash, compare)
|
||||||
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
|
Loading…
Reference in a new issue