Merge ~tore.lonoy/cloud-init:hashed-chpasswd-support into cloud-init:master

Proposed by Tore
Status: Merged
Merged at revision: 21632972df034c200578e1fbc121a07f20bb8774
Proposed branch: ~tore.lonoy/cloud-init:hashed-chpasswd-support
Merge into: cloud-init:master
Diff against target: 112 lines (+44/-12)
2 files modified
cloudinit/config/cc_set_passwords.py (+36/-11)
doc/examples/cloud-config.txt (+8/-1)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Needs Fixing
Scott Moser Needs Fixing
Review via email: mp+310051@code.launchpad.net

Commit message

Add support for setting hashed passwords

This change will add support for hashed passwords in cc_set_passwords.
It checks if a password is a hash with this if/regxp statement:
re.match(r'\$[1,2a,2y,5,6](\$.+){2}', p) is not None and ":" not in p:

chpasswd needs to know if the password is hashed or not, so two lists
is created so chpasswd is feed with the correct one.

Description of the change

Currently only static or randomly generated passwords are supported,
adding support for hashed passwords enables the user to store password
in they configuration a little more secure then using plain-text.

I have been unable to run all the tests on the change, but I've verified
that it works by running these test manually:
* setting static password
* setting static and random
* setting hashed password
* setting hashed and static password

This is my first commit to any open-source project.

To post a comment you must log in.
Revision history for this message
Scott Moser (smoser) wrote :

this looks good. I marked 'Needs Fixing', just for a few nit picks.

I'd like some sort of unit test too.

The trend for adding unit tests is really to make 'handle' do less and move things into methods and use those methods.

review: Needs Fixing
6807679... by Tore

Changed regexp from regular match to compile -> match.

Looping through a large number of username/pass entries
in chpasswd would be less efficient without this change.

fde5f5c... by Tore

Improved the documentation for hashed-password support in chpasswd

Revision history for this message
Tore (tore.lonoy) wrote :

I've made the changes you requested.

I'm not able to create a unit test, as I really don't know how to do it. I don't see any test written already for setting password for chpasswd, so I'm little out of the blue on where to start.

Revision history for this message
Scott Moser (smoser) wrote :

Tore,

Thanks again, and sorry for the delay in getting back here.

In order to take this, you'll need to sign the contributors agreement (https://www.ubuntu.com/legal/contributors). See the hacking section on readthedocs for more info
http://cloudinit.readthedocs.io/en/latest/topics/hacking.html .

Also, please feel free to ping me in Freenode #cloud-init or /query me, or via email.

Taking a quick look, it looks like cc_spacewalk.py and its tests in unittests/test_handler/test_handler_spacewalk.py might be a reasonable template to start with.

Please do feel free to reach out, this looks great.
Scott

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

Tore,
I went ahead and modified some of the integration tests to have a test for this.
and then proposed https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/320986 for merge into your branch.

Can you review that ?

Also, i did nto realize before that you hadn't signed the contributors agreement.
Please do so as described in HACKING.rst

Revision history for this message
Tore (tore.lonoy) wrote :

> Tore,
> I went ahead and modified some of the integration tests to have a test for
> this.
> and then proposed https://code.launchpad.net/~smoser/cloud-init/+git/cloud-
> init/+merge/320986 for merge into your branch.
>
> Can you review that ?

Thanks the tests, didn't realise it what that easy

>
> Also, i did nto realize before that you hadn't signed the contributors
> agreement.
> Please do so as described in HACKING.rst

I've just done so, but I believe I already have signed this. I assume this [0] is the link that should be used ?

[0] https://www.ubuntu.com/legal/contributors/submit

Revision history for this message
Scott Moser (smoser) wrote :

Ok thanks!

On March 25, 2017 1:20:58 AM EDT, Tore <email address hidden> wrote:
>> Tore,
>> I went ahead and modified some of the integration tests to have a
>test for
>> this.
>> and then proposed
>https://code.launchpad.net/~smoser/cloud-init/+git/cloud-
>> init/+merge/320986 for merge into your branch.
>>
>> Can you review that ?
>
>Thanks the tests, didn't realise it what that easy
>
>>
>> Also, i did nto realize before that you hadn't signed the
>contributors
>> agreement.
>> Please do so as described in HACKING.rst
>
>I've just done so, but I believe I already have signed this. I assume
>this [0] is the link that should be used ?
>
>[0] https://www.ubuntu.com/legal/contributors/submit
>--
>https://code.launchpad.net/~tore.lonoy/cloud-init/+git/cloud-init/+merge/310051
>You are reviewing the proposed merge of
>~tore.lonoy/cloud-init:hashed-chpasswd-support into cloud-init:master.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py
2index 6fc0051..5dd4b01 100755
3--- a/cloudinit/config/cc_set_passwords.py
4+++ b/cloudinit/config/cc_set_passwords.py
5@@ -35,7 +35,8 @@ If the ``list`` key is provided, a list of
6 ``username:password`` pairs can be specified. The usernames specified
7 must already exist on the system, or have been created using the
8 ``cc_users_groups`` module. A password can be randomly generated using
9-``username:RANDOM`` or ``username:R``. Password ssh authentication can be
10+``username:RANDOM`` or ``username:R``. A hashed password can be specified
11+using ``username:$6$salt$hash``. Password ssh authentication can be
12 enabled, disabled, or left to system defaults using ``ssh_pwauth``.
13
14 .. note::
15@@ -59,11 +60,13 @@ enabled, disabled, or left to system defaults using ``ssh_pwauth``.
16 chpasswd:
17 list:
18 - user1:password1
19- - user2:Random
20+ - user2:RANDOM
21 - user3:password3
22 - user4:R
23+ - user4:$6$rL..$ej...
24 """
25
26+import re
27 import sys
28
29 from cloudinit.distros import ug_util
30@@ -105,24 +108,46 @@ def handle(_name, cfg, cloud, log, args):
31 errors = []
32 if plist:
33 plist_in = []
34+ hashed_plist_in = []
35+ hashed_users = []
36 randlist = []
37 users = []
38+
39+ prog = re.compile(r'\$[1,2a,2y,5,6](\$.+){2}')
40+
41 for line in plist.splitlines():
42 u, p = line.split(':', 1)
43 if p == "R" or p == "RANDOM":
44 p = rand_user_password()
45 randlist.append("%s:%s" % (u, p))
46- plist_in.append("%s:%s" % (u, p))
47- users.append(u)
48+ elif prog.match(p) is not None and ":" not in p:
49+ hashed_plist_in.append("%s:%s" % (u, p))
50+ hashed_users.append(u)
51+ else:
52+ plist_in.append("%s:%s" % (u, p))
53+ users.append(u)
54
55 ch_in = '\n'.join(plist_in) + '\n'
56- try:
57- log.debug("Changing password for %s:", users)
58- util.subp(['chpasswd'], ch_in)
59- except Exception as e:
60- errors.append(e)
61- util.logexc(log, "Failed to set passwords with chpasswd for %s",
62- users)
63+ if users:
64+ try:
65+ log.debug("Changing password for %s:", users)
66+ util.subp(['chpasswd'], ch_in)
67+ except Exception as e:
68+ errors.append(e)
69+ util.logexc(log,
70+ "Failed to set passwords with chpasswd for %s",
71+ users)
72+
73+ hashed_ch_in = '\n'.join(hashed_plist_in) + '\n'
74+ if hashed_users:
75+ try:
76+ log.debug("Setting hashed password for %s:", hashed_users)
77+ util.subp(['chpasswd', '-e'], hashed_ch_in)
78+ except Exception as e:
79+ errors.append(e)
80+ util.logexc(log,
81+ "Failed to set hashed passwords with chpasswd for %s",
82+ hashed_users)
83
84 if len(randlist):
85 blurb = ("Set the following 'random' passwords\n",
86diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt
87index 190029e..e6ff083 100644
88--- a/doc/examples/cloud-config.txt
89+++ b/doc/examples/cloud-config.txt
90@@ -426,14 +426,21 @@ syslog_fix_perms: syslog:root
91 #
92 # there is also an option to set multiple users passwords, using 'chpasswd'
93 # That looks like the following, with 'expire' set to 'True' by default.
94-# to not expire users passwords, set 'expire' to 'False':
95+# to not expire users passwords, set 'expire' to 'False'. Also possible
96+# to set hashed password, here account 'user3' has a password it set to
97+# 'cloud-init', hashed with SHA-256:
98 # chpasswd:
99 # list: |
100 # user1:password1
101 # user2:RANDOM
102+# user3:$5$eriogqzq$Dg7PxHsKGzziuEGkZgkLvacjuEFeljJ.rLf.hZqKQLA
103 # expire: True
104 # ssh_pwauth: [ True, False, "" or "unchanged" ]
105 #
106+# Hashed passwords can be generated in multiple ways, example with python3:
107+# python3 -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'
108+# Newer versions of 'mkpasswd' will also work: mkpasswd -m sha-512 password
109+#
110 # So, a simple working example to allow login via ssh, and not expire
111 # for the default user would look like:
112 password: passw0rd

Subscribers

People subscribed via source and target branches