Skip to content

Commit

Permalink
utils: introduce passlib
Browse files Browse the repository at this point in the history
Transient commit to show passlib functionality is equivalent with
crypt module, given the right parameters. Rebase me before merge.
  • Loading branch information
Chris-Peterson444 committed Nov 2, 2024
1 parent e0ab7db commit 5cba20c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ parts:
- python3-minimal
- python3-more-itertools
- python3-oauthlib
- python3-passlib
- python3-pkg-resources
- python3-pyroute2
- python3-pyrsistent
Expand Down
32 changes: 32 additions & 0 deletions subiquitycore/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
from subiquitycore.tests import SubiTestCase
from subiquitycore.utils import (
_zsys_uuid_charset,
crypt_password,
gen_zsys_uuid,
orig_environ,
passlib_crypt,
system_scripts_env,
)

Expand Down Expand Up @@ -129,3 +131,33 @@ def test_zsys_uuid(self):
for i in range(10):
uuid = gen_zsys_uuid()
self.assertEqual(6, len(uuid), uuid)


class TestCryptPassword(SubiTestCase):
@patch("subiquitycore.utils._generate_salt")
def test_compare_passlib_with_crypt(self, salt_mock):
"""Test passlib module output is equivalent with python crypt module."""

# Test SHA-512
salt_mock.return_value = "mock.salt"
python = crypt_password("ubuntu", "SHA-512")
passlib = passlib_crypt("ubuntu", "SHA-512")
self.assertEqual(python, passlib)

# Test SHA-256
salt_mock.return_value = "mock.salt"
python = crypt_password("ubuntu", "SHA-256")
passlib = passlib_crypt("ubuntu", "SHA-256")
self.assertEqual(python, passlib)

# Test MD5
salt_mock.return_value = "mock.salt"
python = crypt_password("ubuntu", "MD5")
passlib = passlib_crypt("ubuntu", "MD5")
self.assertEqual(python, passlib)

# Test DES
salt_mock.return_value = "mock.salt"
python = crypt_password("ubuntu", "DES")
passlib = passlib_crypt("ubuntu", "DES")
self.assertEqual(python, passlib)
24 changes: 24 additions & 0 deletions subiquitycore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import tempfile
from typing import Any, Dict, List, Sequence

import passlib.hash

log = logging.getLogger("subiquitycore.utils")


Expand Down Expand Up @@ -257,6 +259,28 @@ def crypt_password(passwd, algo="SHA-512"):
return crypt.crypt(passwd, algos[algo] + salt)


def passlib_crypt(passwd, algo="SHA-512"):
# Use rounds=5000 where possible to be equivalent w/ crypt.
algos = {
"SHA-512": passlib.hash.sha512_crypt.using(rounds=5000),
"SHA-256": passlib.hash.sha256_crypt.using(rounds=5000),
"MD5": passlib.hash.md5_crypt,
"DES": passlib.hash.des_crypt,
}

salt = _generate_salt()

# MD5 only supports salts of <= 8 characters
if algo == "MD5":
salt = salt[:8]
# DES only supports salts of <= 2 charactes
elif algo == "DES":
salt = salt[:2]

handler = algos[algo].using(salt=salt)
return handler.hash(passwd)


def disable_subiquity():
"""Stop subiquity service; which also restores getty service"""
log.info("disabling subiquity service")
Expand Down

0 comments on commit 5cba20c

Please sign in to comment.