[elbe-devel] [PATCH v2 6/8] proprocess: migrate root and user passwords

Holger Dengler holger at hdengler.de
Sat Jun 25 12:27:47 CEST 2022


On 24.06.22 13:12, Bastian Germann wrote:
> Typo in subject: preprocess

Ok.

> 
> Am 16.06.22 um 12:10 schrieb Holger Dengler:
>> Support legacy XMLs by adding preprocessing for plain-text passwords for
>> root and users. The plain-text password elements or attributes will be
>> replaced with their hashed variants.
>>
>> XMLs with only hashed passwords will not be changed by the
>> preprocessing.
>>
>> Signed-off-by: Holger Dengler <holger at hdengler.de>
>> ---
>>   elbepack/xmlpreprocess.py | 28 +++++++++++++++++++++++++---
>>   1 file changed, 25 insertions(+), 3 deletions(-)
>>
>> diff --git a/elbepack/xmlpreprocess.py b/elbepack/xmlpreprocess.py
>> index f3c2f2a7f..947b3cfce 100644
>> --- a/elbepack/xmlpreprocess.py
>> +++ b/elbepack/xmlpreprocess.py
>> @@ -14,6 +14,7 @@ from optparse import OptionGroup
>>   from itertools import islice
>>   from urllib.error import HTTPError,URLError
>>   from urllib.request import urlopen
>> +from crypt import crypt, METHOD_SHA512
> 
> The crypt module is deprecated in Python 11.

ok, I missed that. I will use passlib instead.

> preprocess runs on the host machine so I would like to have broad compatibility.
> I am thinking of making the host commands compatible with Windows where this is
> not available (part of the rationale for the deprecation). If there is no Python
> 3.6+ module (hashlib?) that we can use, I would prefer introducing a dependency,
> possibly passlib.
> 
> The method has to be compatible with the oldest of our supported target systems,
> which is jessie. I would prefer Blowfish over SHA512. If we keep SHA512, please
> use a greater than default rounds parameter.

I did a quick test on a stretch machine: 
passlib.hash.bcrypt ('$2b$12$...') does not work 
passlib.hash.sha512_crypt ('$6$rounds=656000$...') works

I also found the following hint in /etc/pam.d/common-password (sid):
"Explanation of pam_unix options: The "yescrypt" option enables hashed passwords using the yescrypt algorithm, introduced in Debian 11.  Without this option, the default is Unix crypt.  Prior releases used the option "sha512"; if a shadow password hash will be shared between Debian 11 and older releases replace "yescrypt" with "sha512" for compatibility."

I assume, that all releases from stretch to current support sha256 and sha512 (including rounds), but no bcrypt. I've currently no access to a jessie system, maybe someone else can provide some information, which algorithms are supported there. If jessie has no support for sha512 but for sha256, I personally would prefer to use sha256, at least for jessie. I'll prepare v3 (presumably next weekend).

Can someone please provide information about the supported hash methods for jessie and also older ubuntu releases?

One question about the rounds: passlib uses 656000 rounds as default for sha512 (sha256: 535000). Is this enough? I think it is, but are open for other proposals.

> 
>>     from lxml import etree
>>   from lxml.etree import XMLParser, parse, Element
>> @@ -251,6 +252,25 @@ def preprocess_mirrors(xml):
>>               option.text = opt
>>               options.append(option)
>>   +def preprocess_passwd(xml):
>> +    """Preprocess plain-text passwords. Plain-text passwords for root and
>> +       adduser will be replaced with their hashed values.
>> +    """
>> +
>> +    # migrate root password
>> +    for passwd in xml.iterfind(".//target/passwd"):
>> +        passwd_hashed = '%s' % crypt(passwd.text, METHOD_SHA512)
>> +        passwd.tag = "passwd_hashed"
>> +        passwd.text = passwd_hashed
>> +
>> +    # migrate user passwords
>> +    for adduser in xml.iterfind(".//target/finetuning/adduser[@passwd]"):
>> +        passwd = adduser.attrib['passwd']
>> +        passwd_hashed = crypt(passwd, METHOD_SHA512)
>> +
>> +        adduser.attrib['passwd_hashed'] = passwd_hashed
>> +        del adduser.attrib['passwd']
>> +
>>   def xmlpreprocess(fname, output, variants=None, proxy=None):
>>         # pylint: disable=too-many-locals
>> @@ -334,6 +354,8 @@ def xmlpreprocess(fname, output, variants=None, proxy=None):
>>             preprocess_mirrors(xml)
>>   +        preprocess_passwd(xml)
>> +
>>           if schema.validate(xml):
>>               # if validation succedes write xml file
>>               xml.write(
>> @@ -349,9 +371,9 @@ def xmlpreprocess(fname, output, variants=None, proxy=None):
>>       except ArchivedirError:
>>           raise XMLPreprocessError("<archivedir> handling failed\n" +
>>                                    str(sys.exc_info()[1]))
>> -    except BaseException:
>> -        raise XMLPreprocessError(
>> -            "Unknown Exception during validation\n" + str(sys.exc_info()[1]))
>> +#     except BaseException:
>> +#         raise XMLPreprocessError(
>> +#             "Unknown Exception during validation\n" + str(sys.exc_info()[1]))
>>         # We have errors, return them in string form...
>>       raise XMLPreprocessError("\n".join(error_log_to_strings(schema.error_log)))

-- 
Gruß,
Holger Dengler
--
holger at hdengler.de


More information about the elbe-devel mailing list