diff options
Diffstat (limited to 'newuser.py')
-rw-r--r-- | newuser.py | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/newuser.py b/newuser.py new file mode 100644 index 0000000..4e0a0cd --- /dev/null +++ b/newuser.py @@ -0,0 +1,67 @@ +#! /usr/bin/env python + +from subprocess import call +import base64 + +import gnupg # python-gnupg + +root_user_fs_path = './user_fses/' +root_repo_path = './repos/' + +authorized_keys_base = '/var/authorized_keys/' + +gpg = gnupg.GPG(gnupghome='/does/not/exist') + +def recv_keys(gpg_key_path, ssh_key_path): + fingerprint = full_fingerprint(gpg_key_path) + username = tiny_gpg_fingerprint(fingerprint) + alloc_user(username) + add_key(username, ssh_key_path) + print("gpg key: %s, ssh key: %s" % (gpg_key_path, ssh_key_path)) + print("username: %s, gpg fingerprint: %s" % (username, fingerprint)) + return True + +def full_fingerprint(gpg_key_path): + keys = gpg.scan_keys(gpg_key_path) + if (len(keys) == 0): + raise "hell" + if (len(keys) != 1): + raise "the roof" + return keys[0]["fingerprint"] + +# the s/./=/g thing here is because +# = is apparently not valid in a username! +# but having the padding around is nice. so keep it. +# so turn it into valid characters! +def untiny_gpg_fingerprint(tiny): + return binascii.unhexlify( + base64.b64decode(tiny.replace('.', '='), '-_') + ) + +def tiny_gpg_fingerprint(raw_fingerprint): + fingerprint_bytes = raw_fingerprint.decode('hex') + return base64.b64encode(fingerprint_bytes, '-_').replace('=', '.') + +def add_key(username, ssh_key_path): + with open(ssh_key_path, 'r') as key_file: + ssh_key = key_file.read() + with open(authorized_keys_base + username, 'a+') as user_authorized_keys: + user_authorized_keys.write(ssh_key) + return True + +def alloc_user(username): + + if username == '': + raise Exception("Username must not be empty and must be alphanumeric (but it's derived from your full gpg key id, so how did you do that?") + + fs_path = root_user_fs_path + username + repo_path = root_repo_path + username +# [D]on't give a password (ssh login only) +# Don't create a [H]ome directory +# Set the login [s]hell to a non-shell to disallow logins + call(['adduser', '-D', '-H', '-s', '/bin/false', username]) + call(['dd', 'if=/dev/zero', 'of=' + fs_path, 'bs=4096', 'count=32768']) + call(['mkfs.ext4', '-q', fs_path]) + call(['mkdir', repo_path]) + call(['mount', '-o', 'loop,rw', fs_path, repo_path + '/']) + call(['touch', repo_path + '/git-daemon-export-ok']) |