Merge ~otubo/cloud-init:multiple-ssh-keys into cloud-init:master

Proposed by Eduardo Otubo
Status: Work in progress
Proposed branch: ~otubo/cloud-init:multiple-ssh-keys
Merge into: cloud-init:master
Diff against target: 73 lines (+24/-19)
1 file modified
cloudinit/ssh_util.py (+24/-19)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Needs Fixing
Eduardo Otubo (community) review Needs Information
Scott Moser Pending
Review via email: mp+372981@code.launchpad.net

Commit message

Multiple file fix for AuthorizedKeysFile config

Currently cloud-init does not know how to handle multiple file
configuration on section AuthorizedKeysFile of ssh configuration.
cloud-init will mess up the home user directory by creating bogus
folders inside it.

This patch provides a fix for this erroneous behavior. It gathers all
keys from all the files listed on the section AuthorizedKeysFile of ssh
configuration and merge all of them inside home user
~/.ssh/authorized_keys of the vm deployed.

To post a comment you must log in.
Revision history for this message
Eduardo Otubo (otubo) wrote :
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:c422c91cbb4bf8ffdad89081221f7b7e83584c79
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1166/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1166//rebuild

review: Needs Fixing (continuous-integration)
~otubo/cloud-init:multiple-ssh-keys updated
1ac3ad4... by Eduardo Otubo

Fixing coding style

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:1ac3ad42e7d9d8de851e7399920e6214d7961696
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1168/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1168//rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Eduardo Otubo (otubo) wrote :

Hey guys, I already fixed the style issues and tox returns:
  pycodestyle: commands succeeded
  congratulations :)
Anyone can help to push here?

review: Needs Information (review)
Revision history for this message
Dan Watkins (oddbloke) wrote :

Just kicked off a new CI run. :)

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:1ac3ad42e7d9d8de851e7399920e6214d7961696
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1217/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1217//rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Dan Watkins (oddbloke) wrote :

Those CI failures have been fixed in master, so you'll need to rebase onto master and then re-request a CI run.

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

over all this looks fine. one question in line.

It would be nice if you could add some tests.

I'm always hesitant to request someone add tests to code they're fixing when the original code (probably that I wrote) had no tests... but it ensures that stuff works later.

Revision history for this message
Eduardo Otubo (otubo) wrote :

Unmerged commits

1ac3ad4... by Eduardo Otubo

Fixing coding style

c422c91... by Eduardo Otubo

Multiple file fix for AuthorizedKeysFile config

Currently cloud-init does not know how to handle multiple file
configuration on section AuthorizedKeysFile of ssh configuration.
cloud-init will mess up the home user directory by creating bogus
folders inside it.

This patch provides a fix for this erroneous behavior. It gathers all
keys from all the files listed on the section AuthorizedKeysFile of ssh
configuration and merge all of them inside home user
~/.ssh/authorized_keys of the vm deployed.

Signed-off-by: Eduardo Otubo <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/ssh_util.py b/cloudinit/ssh_util.py
2index 3f99b58..3e931e3 100644
3--- a/cloudinit/ssh_util.py
4+++ b/cloudinit/ssh_util.py
5@@ -160,14 +160,15 @@ class AuthKeyLineParser(object):
6 comment=comment, options=options)
7
8
9-def parse_authorized_keys(fname):
10+def parse_authorized_keys(fnames):
11 lines = []
12- try:
13- if os.path.isfile(fname):
14- lines = util.load_file(fname).splitlines()
15- except (IOError, OSError):
16- util.logexc(LOG, "Error reading lines from %s", fname)
17- lines = []
18+ for fname in fnames:
19+ try:
20+ if os.path.isfile(fname):
21+ lines = util.load_file(fname).splitlines()
22+ except (IOError, OSError):
23+ util.logexc(LOG, "Error reading lines from %s", fname)
24+ lines = []
25
26 parser = AuthKeyLineParser()
27 contents = []
28@@ -213,7 +214,7 @@ def users_ssh_info(username):
29
30 def extract_authorized_keys(username):
31 (ssh_dir, pw_ent) = users_ssh_info(username)
32- auth_key_fn = None
33+ auth_key_fns = []
34 with util.SeLinuxGuard(ssh_dir, recursive=True):
35 try:
36 # The 'AuthorizedKeysFile' may contain tokens
37@@ -222,21 +223,25 @@ def extract_authorized_keys(username):
38 # '%', %h is replaced by the home directory of the user being
39 # authenticated and %u is replaced by the username of that user.
40 ssh_cfg = parse_ssh_config_map(DEF_SSHD_CFG)
41- auth_key_fn = ssh_cfg.get("authorizedkeysfile", '').strip()
42- if not auth_key_fn:
43- auth_key_fn = "%h/.ssh/authorized_keys"
44- auth_key_fn = auth_key_fn.replace("%h", pw_ent.pw_dir)
45- auth_key_fn = auth_key_fn.replace("%u", username)
46- auth_key_fn = auth_key_fn.replace("%%", '%')
47- if not auth_key_fn.startswith('/'):
48- auth_key_fn = os.path.join(pw_ent.pw_dir, auth_key_fn)
49+ auth_key_fns = ssh_cfg.get(
50+ "authorizedkeysfile", '').strip().split()
51+ if not auth_key_fns:
52+ auth_key_fns[0] = "%h/.ssh/authorized_keys"
53+ i = 0
54+ for i in range(len(auth_key_fns)):
55+ auth_key_fns[i] = auth_key_fns[i].replace("%h", pw_ent.pw_dir)
56+ auth_key_fns[i] = auth_key_fns[i].replace("%u", username)
57+ auth_key_fns[i] = auth_key_fns[i].replace("%%", '%')
58+ if not auth_key_fns[i].startswith('/'):
59+ auth_key_fns[i] = os.path.join(
60+ pw_ent.pw_dir, auth_key_fns[i])
61 except (IOError, OSError):
62 # Give up and use a default key filename
63- auth_key_fn = os.path.join(ssh_dir, 'authorized_keys')
64+ auth_key_fns[0] = os.path.join(ssh_dir, 'authorized_keys')
65 util.logexc(LOG, "Failed extracting 'AuthorizedKeysFile' in ssh "
66 "config from %r, using 'AuthorizedKeysFile' file "
67- "%r instead", DEF_SSHD_CFG, auth_key_fn)
68- return (auth_key_fn, parse_authorized_keys(auth_key_fn))
69+ "%r instead", DEF_SSHD_CFG, auth_key_fns[0])
70+ return (auth_key_fns[0], parse_authorized_keys(auth_key_fns))
71
72
73 def setup_user_keys(keys, username, options=None):

Subscribers

People subscribed via source and target branches