Skip to content

Commit

Permalink
Look up keymaker executables in path using shutil.which and fallback
Browse files Browse the repository at this point in the history
Fixes #56
  • Loading branch information
kislyuk committed Jul 7, 2019
1 parent c6bda35 commit f7ddd91
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ python:

install:
- python setup.py install
- pip install coverage
- pip install coverage flake8

script:
- coverage run --source=keymaker ./test/test.py
Expand Down
43 changes: 19 additions & 24 deletions keymaker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,15 @@

from io import open

import os
import sys
import json
import re
import time
import logging
import subprocess # nosec
import pwd
import hashlib
import codecs
import grp
import shlex
import os, sys, json, re, time, logging, subprocess, pwd, hashlib, grp, shlex
from collections import namedtuple

try:
from shutil import which
except ImportError:
def which(name):
return "/usr/local/bin/" + name if os.path.exists("/usr/local/bin/" + name) else "/usr/bin/" + name

import boto3
from botocore.exceptions import ClientError

Expand Down Expand Up @@ -234,17 +229,17 @@ def install(args):
try:
pwd.getpwnam(user)
except KeyError:
subprocess.check_call(["useradd", user, # nosec
subprocess.check_call(["useradd", user,
"--comment", "Keymaker SSH key daemon",
"--shell", "/usr/sbin/nologin"])

authorized_keys_script_path = "/usr/sbin/keymaker-get-public-keys"
with open(authorized_keys_script_path, "w") as fh:
print("#!/bin/bash -e", file=fh)
print('keymaker get_authorized_keys "$@"', file=fh)
subprocess.check_call(["chown", "root", authorized_keys_script_path]) # nosec
subprocess.check_call(["chmod", "go-w", authorized_keys_script_path]) # nosec
subprocess.check_call(["chmod", "a+x", authorized_keys_script_path]) # nosec
subprocess.check_call(["chown", "root", authorized_keys_script_path])
subprocess.check_call(["chmod", "go-w", authorized_keys_script_path])
subprocess.check_call(["chmod", "a+x", authorized_keys_script_path])

with open("/etc/ssh/sshd_config") as fh:
sshd_config_lines = fh.read().splitlines()
Expand All @@ -260,9 +255,9 @@ def install(args):
print(line, file=fh)

# TODO: print explanation if errors occur
subprocess.check_call(["sshd", "-t"]) # nosec
subprocess.check_call(["sshd", "-t"])

pam_config_line = "auth optional pam_exec.so stdout /usr/local/bin/keymaker-create-account-for-iam-user"
pam_config_line = "auth optional pam_exec.so stdout " + which("keymaker-create-account-for-iam-user")
with open("/etc/pam.d/sshd") as fh:
pam_config_lines = fh.read().splitlines()
if pam_config_line not in pam_config_lines:
Expand All @@ -272,7 +267,7 @@ def install(args):
print(line, file=fh)

with open("/etc/cron.d/keymaker-group-sync", "w") as fh:
print("*/5 * * * * root /usr/local/bin/keymaker sync_groups", file=fh)
print("*/5 * * * * root " + which("keymaker") + " sync_groups", file=fh)

def err_exit(msg, code=3):
print(msg, file=sys.stderr)
Expand All @@ -283,7 +278,7 @@ def load_ssh_public_key(filename):
key = fh.read()
if "PRIVATE KEY" in key:
logger.info("Extracting public key from private key {}".format(filename))
key = subprocess.check_output(["ssh-keygen", "-y", "-f", filename]).decode() # nosec
key = subprocess.check_output(["ssh-keygen", "-y", "-f", filename]).decode()
return key

def select_ssh_public_key(identity=None):
Expand All @@ -293,7 +288,7 @@ def select_ssh_public_key(identity=None):
return load_ssh_public_key(identity)
else:
try:
keys = subprocess.check_output(["ssh-add", "-L"]).decode("utf-8").splitlines() # nosec
keys = subprocess.check_output(["ssh-add", "-L"]).decode("utf-8").splitlines()
if len(keys) > 1:
exit(("Multiple keys reported by ssh-add. Please specify a key filename with --identity or unload keys "
'with "ssh-add -D", then load the one you want with "ssh-add ~/.ssh/id_rsa" or similar.'))
Expand Down Expand Up @@ -401,7 +396,7 @@ def sync_groups(args):
unix_group = grp.getgrnam(unix_group_name)
except KeyError:
logger.info("Provisioning group %s from IAM", unix_group_name)
subprocess.check_call(["groupadd", "--gid", str(aws_to_unix_id(group.group_id)), unix_group_name]) # nosec
subprocess.check_call(["groupadd", "--gid", str(aws_to_unix_id(group.group_id)), unix_group_name])
unix_group = grp.getgrnam(unix_group_name)
user_names_in_iam_group = [user.name[:len(user.name)-len(iam_linux_user_suffix)]
for user in group.users.all()
Expand All @@ -412,8 +407,8 @@ def sync_groups(args):
continue
if user not in unix_group.gr_mem:
logger.info("Adding user %s to group %s", user, unix_group_name)
subprocess.check_call(["usermod", "--append", "--groups", unix_group_name, user]) # nosec
subprocess.check_call(["usermod", "--append", "--groups", unix_group_name, user])
for unix_user_name in filter(is_managed, unix_group.gr_mem):
if unix_user_name not in user_names_in_iam_group:
logger.info("Removing user %s from group %s", unix_user_name, unix_group_name)
subprocess.check_call(["gpasswd", "--delete", unix_user_name, unix_group_name]) # nosec
subprocess.check_call(["gpasswd", "--delete", unix_user_name, unix_group_name])
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from setuptools import setup, find_packages

install_requires = [line.rstrip() for line in open(os.path.join(os.path.dirname(__file__), "requirements.txt"))]
tests_require = ["coverage", "flake8", "wheel", "bandit"]
tests_require = ["coverage", "flake8", "wheel"]

setup(
name='keymaker',
Expand Down

0 comments on commit f7ddd91

Please sign in to comment.