diff -Nru ssh-import-id-4.5/bin/ssh-import-id ssh-import-id-5.0/bin/ssh-import-id --- ssh-import-id-4.5/bin/ssh-import-id 2014-04-27 19:31:06.000000000 +0000 +++ ssh-import-id-5.0/bin/ssh-import-id 1970-01-01 00:00:00.000000000 +0000 @@ -1,272 +0,0 @@ -#!/usr/bin/env python3 -# -# ssh-import-id - Authorize SSH public keys from trusted online identities -# -# Copyright (c) 2013 Casey Marshall -# Copyright (c) 2013 Dustin Kirkland -# -# ssh-import-id is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, version 3. -# -# ssh-import-id is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with ssh-import-id. If not, see . - -import argparse -import logging -import os -import stat -import subprocess -import sys -import tempfile - -DEFAULT_PROTO = "lp" - -logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO) - -parser = argparse.ArgumentParser(description='Authorize SSH public keys from trusted online identities.') -parser.add_argument('-o', '--output', metavar='FILE', help='Write output to file (default ~/.ssh/authorized_keys)') -parser.add_argument('-r', '--remove', help='Remove a key from authorized keys file', action="store_true", default=False) -parser.add_argument('userids', nargs='+', metavar="USERID", help='User IDs to import') -parser.options = None - -TEMPFILES = [] - - -def cleanup(): - """ - Cleanup tempfiles - """ - for f in TEMPFILES: - if os.path.exists(f): - os.unlink(f) - - -def die(msg): - """ - The only thing in Perl worth keeping - """ - logging.error(msg) - cleanup() - os._exit(1) - - -def key_fingerprint(fields): - """ - Get the fingerprint for an SSH public key - Returns None if not valid key material - """ - if not fields: - return None - if len(fields) < 3: - return None - tempfd, tempname = tempfile.mkstemp(prefix='ssh-auth-key-check', suffix='.pub') - TEMPFILES.append(tempname) - with os.fdopen(tempfd, "w") as tempf: - tempf.write(" ".join(fields)) - tempf.write("\n") - keygen_proc = subprocess.Popen(['ssh-keygen', '-l', '-f', tempname], stdout=subprocess.PIPE) - keygen_out, _ = keygen_proc.communicate(None) - if keygen_proc.returncode: - # Non-zero RC: probably not a public key - return None - os.unlink(tempname) - keygen_fields = keygen_out.split() - if not keygen_fields or len(keygen_fields) < 2: - # Empty output? - return None - out = [] - for k in keygen_out.split(): - out.append(str(k.decode('utf-8').strip())) - return out - - -def open_output(name, mode='a+'): - """ - Open output for writing, supporting either stdout or a filename - """ - if name == '-': - return False - else: - return open(name, mode) - - -def assert_parent_dir(keyfile): - """ - Ensure that the keyfile parent directory exists - """ - # Standard out: nothing to do - if keyfile == "-": - return True - # Get output file parent directory - if os.path.dirname(keyfile): - parent_dir = os.path.dirname(keyfile) - else: - parent_dir = "." - # Ensure parent directory exists - if not os.path.exists(parent_dir): - umask = os.umask(0o077) - os.makedirs(parent_dir, 0o700) - os.umask(umask) - if os.path.isdir(parent_dir): - return True - else: - die("Parent directory not found for output [%s]" % (keyfile)) - return False - - -def read_keyfile(): - """ - Locate key file, read the current state, return lines in a list - """ - lines = [] - output_file = parser.options.output or os.path.join(os.getenv("HOME"), ".ssh", "authorized_keys") - if os.path.exists(output_file): - try: - with open(output_file, "r") as f: - lines = f.readlines() - except: - die("Could not read authorized key file [%s]" % (output_file)) - return lines - - -def write_keyfile(keyfile_lines, mode): - """ - Locate key file, write lines to it - """ - output_file = parser.options.output or os.path.join(os.getenv("HOME"), ".ssh", "authorized_keys") - if output_file == "-": - for line in keyfile_lines: - if line: - sys.stdout.write(line) - sys.stdout.write("\n") - sys.stdout.flush() - elif assert_parent_dir(output_file): - with open(output_file, mode) as f: - for line in keyfile_lines: - if line.strip(): - f.write(line) - f.write("\n") - - -def fp_tuple(fp): - """ - Build a string that uniquely identifies a key - """ - # An SSH public key is uniquely identified by the tuple [length, hash, type]] - # fp should be a list of results of the `ssh-keygen -l -f` command - return ' '.join([fp[0], fp[1], fp[-1]]) - - -def key_list(keyfile_lines): - """ - Return a list of uniquely identified keys - """ - # Map out which keys we already have - keys = [] - for line in keyfile_lines: - ssh_fp = key_fingerprint(line.split()) - if ssh_fp: - keys.append(fp_tuple(ssh_fp)) - logging.debug("Already have SSH public keys: [%s]" % (' '.join(keys))) - return keys - - -def fetch_keys(proto, username): - """ - Call out to a subcommand to handle the specified protocol and username - """ - proto_cmd_path = os.path.join(os.path.dirname(sys.argv[0]), "%s-%s" % (os.path.basename(sys.argv[0]), proto)) - if not os.path.isfile(proto_cmd_path) or not os.access(proto_cmd_path, os.X_OK): - die("ssh-import-id protocol handler %s: not found or cannot execute" % (proto_cmd_path)) - proc = subprocess.Popen([proto_cmd_path, username], stdout=subprocess.PIPE) - output, _ = proc.communicate(None) - if proc.returncode: - raise Exception("Error executing protocol helper [%s]" % proto_cmd_path) - return output.split(b"\n") - - -def import_keys(proto, username): - """ - Import keys from service at 'proto' for 'username', appending to output file - """ - # Map out which keys we already have, so we don't keep appending the same ones - local_keys = key_list(read_keyfile()) - # Protocol handler should output SSH keys, one per line - result = [] - keyfile_lines = [] - comment_string = "# ssh-import-id %s:%s" % (proto, username) - for line in fetch_keys(proto, username): - # Validate/clean-up key text - line = line.decode('utf-8').strip() - fields = line.split() - fields.append(comment_string) - ssh_fp = key_fingerprint(fields) - if ssh_fp: - if fp_tuple(ssh_fp) in local_keys: - logging.info("Already authorized %s" % (ssh_fp[:3] + ssh_fp[-1:])) - result.append(fields) - else: - keyfile_lines.append(" ".join(fields)) - result.append(fields) - logging.info("Authorized key %s" % (ssh_fp[:3] + ssh_fp[-1:])) - write_keyfile(keyfile_lines, "a+") - return result - - -def remove_keys(proto, username): - """ - Remove keys from the output file, if they were inserted by this tool - """ - # Only remove keys labeled with our comment string - comment_string = "# ssh-import-id %s:%s\n" % (proto, username) - update_lines = [] - removed = [] - for line in read_keyfile(): - if line.endswith(comment_string): - ssh_fp = key_fingerprint(line.split()) - logging.info("Removed labeled key %s" % (ssh_fp[:3] + ssh_fp[-1:])) - removed.append(line) - else: - update_lines.append(line) - write_keyfile(update_lines, "w") - return removed - - -if __name__ == '__main__': - errors = [] - try: - os.umask(0o177) - parser.options = parser.parse_args() - keys = [] - for userid in parser.options.userids: - user_pieces = userid.split(':') - if len(user_pieces) == 2: - proto, username = user_pieces - elif len(user_pieces) == 1: - proto, username = DEFAULT_PROTO, userid - else: - die("Invalid user ID: [%s]" % (userid)) - if parser.options.remove: - k = remove_keys(proto, username) - keys.extend(k) - action = "Removed" - else: - k = import_keys(proto, username) - keys.extend(k) - action = "Authorized" - if len(k) == 0: - errors.append(userid) - logging.info("[%d] SSH keys [%s]" % (len(keys), action)) - except (Exception,): - e = sys.exc_info()[1] - die("%s" % (str(e))) - cleanup() - if len(errors) > 0: - die("No matching keys found for [%s]" % ','.join(errors)) - os._exit(0) diff -Nru ssh-import-id-4.5/bin/ssh-import-id-gh ssh-import-id-5.0/bin/ssh-import-id-gh --- ssh-import-id-4.5/bin/ssh-import-id-gh 2015-10-05 23:29:48.000000000 +0000 +++ ssh-import-id-5.0/bin/ssh-import-id-gh 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -#!/usr/bin/env python3 -# -# ssh-import-id - Authorize SSH public keys from trusted online identities. -# -# Copyright (c) 2013 Casey Marshall -# Copyright (c) 2013 Dustin Kirkland -# -# ssh-import-id is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, version 3. -# -# ssh-import-id is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with ssh-import-id. If not, see . - -import os -import json -import subprocess -import sys -import requests -try: - from urllib.parse import quote_plus -except: - from urllib import quote_plus - - -X_RATELIMIT_REMAINING = 'x-ratelimit-remaining' -HELP_URL = 'https://developer.github.com/v3/#rate-limiting' - - -if __name__ == '__main__': - if not sys.argv[:1]: - sys.stderr.write("Usage: %s \n" % (sys.argv[0])) - os._exit(1) - for ghid in sys.argv[1:]: - try: - url = "https://api.github.com/users/%s/keys" % (quote_plus(ghid)) - resp = requests.get(url, verify=True) - text = resp.text - data = json.loads(text) - if resp.status_code == 404: - print('Username "%s" not found at GitHub API' % ghid) - os._exit(1) - if X_RATELIMIT_REMAINING in resp.headers and int(resp.headers[X_RATELIMIT_REMAINING]) == 0: - print('GitHub REST API rate-limited this IP address. See %s' % HELP_URL) - os._exit(1) - for keyobj in data: - sys.stdout.write("%s %s@github/%s\n" % (keyobj['key'], ghid, keyobj['id'])) - sys.stdout.flush() - except (Exception,): - e = sys.exc_info()[1] - sys.stderr.write("ERROR: %s\n" % (str(e))) - os._exit(1) - sys.stdout.write("\n") - os._exit(0) diff -Nru ssh-import-id-4.5/bin/ssh-import-id-lp ssh-import-id-5.0/bin/ssh-import-id-lp --- ssh-import-id-4.5/bin/ssh-import-id-lp 2015-10-05 23:13:11.000000000 +0000 +++ ssh-import-id-5.0/bin/ssh-import-id-lp 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 -# -# ssh-import-id - Authorize SSH public keys from trusted online identities. -# -# Copyright (c) 2013 Casey Marshall -# Copyright (c) 2013 Dustin Kirkland -# -# ssh-import-id is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, version 3. -# -# ssh-import-id is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with ssh-import-id. If not, see . - -import json -import os -import subprocess -import sys -import requests -try: - from urllib.parse import quote_plus -except: - from urllib import quote_plus - - -if __name__ == '__main__': - if not sys.argv[:1]: - sys.stderr.write("Usage: %s \n" % (sys.argv[0])) - os._exit(1) - for lpid in sys.argv[1:]: - try: - url = os.getenv("URL", None) - if url is None and os.path.exists("/etc/ssh/ssh_import_id"): - try: - conf = json.loads(open("/etc/ssh/ssh_import_id").read()) - url = conf.get("URL", None) % (quote_plus(lpid)) - except: - raise Exception("Ensure that URL is defined in [/etc/ssh/ssh_import_id] is in JSON syntax") - elif url is not None: - url = url % (quote_plus(lpid)) - # Finally, fall back to Launchpad - if url is None: - url = "https://launchpad.net/~%s/+sshkeys" % (quote_plus(lpid)) - text = requests.get(url, verify=True).text - sys.stdout.write(str(text)) - sys.stdout.write("\n") - sys.stdout.flush() - except (Exception,): - e = sys.exc_info()[1] - sys.stderr.write("ERROR: %s\n" % (str(e))) - os._exit(1) - sys.stdout.write("\n") - os._exit(0) diff -Nru ssh-import-id-4.5/ChangeLog ssh-import-id-5.0/ChangeLog --- ssh-import-id-4.5/ChangeLog 2015-10-05 23:31:41.000000000 +0000 +++ ssh-import-id-5.0/ChangeLog 2016-01-30 15:45:53.000000000 +0000 @@ -1,11 +1,44 @@ -ssh-import-id (4.5) released; urgency=medium +ssh-import-id (5.0) released; urgency=medium + + * === added directory etc, === added directory etc/ssh, === added + directory ssh_import_id, === added directory usr, === added + directory usr/bin, === added directory usr/share, === added + directory usr/share/man, === added directory usr/share/man/man1, + bin/ssh-import-id-gh => usr/bin/ssh-import-id-gh, bin/ssh-import-id- + lp => usr/bin/ssh-import-id-lp, bin/ssh-import-id => + ssh_import_id/__init__.py (properties changed: +x to -x), + debian/control, debian/install, debian/manpages, debian/rules, === + removed directory bin, setup.py, ssh-import-id.1 => + usr/share/man/man1/ssh-import-id.1, ssh_import_id => + etc/ssh/ssh_import_id, usr/bin/ssh-import-id: + - build depend on dh-python + - simplify package install, etc/ and usr/ + - syntax check both locations + - build an ssh_import_id python package/module + - put all common functionality into an ssh_import_id module + - add a browser useragent string, for protocol version support on the server + - move ssh-import-id-lp and ssh-import-id-gh functionality into a base + python function, and wrap those with shell + - remove a couple of subcommand shell outs by using native python calls + * setup.py, ssh_import_id/__init__.py: + - bump major version to 5.0, major changes here + * debian/rules, setup.py: + - add scripts back to setup.py + * ssh_import_id/__init__.py: + - add extra blank line back, for readability + * debian/control, ssh_import_id/__init__.py: + - use pkg_resources to get __version__, depend on package + + -- Dustin Kirkland Mon, 05 Oct 2015 18:32:55 -0500 + +ssh-import-id (4.5-0ubuntu1) wily; urgency=medium [ Andres Riancho and Dustin Kirkland ] * bin/ssh-import-id-gh: LP: #1397332 - handle two github error conditions (rate limiting and user not found) - -- Dustin Kirkland Mon, 05 Oct 2015 18:15:54 -0500 + -- Dustin Kirkland Mon, 05 Oct 2015 18:32:53 -0500 ssh-import-id (4.4-0ubuntu1) wily; urgency=medium diff -Nru ssh-import-id-4.5/debian/changelog ssh-import-id-5.0/debian/changelog --- ssh-import-id-4.5/debian/changelog 2016-01-30 15:49:21.000000000 +0000 +++ ssh-import-id-5.0/debian/changelog 2016-01-30 15:49:21.000000000 +0000 @@ -1,11 +1,44 @@ -ssh-import-id (4.5-0ubuntu1~vivid) vivid; urgency=medium +ssh-import-id (5.0-0ubuntu1~vivid) vivid; urgency=medium + + * === added directory etc, === added directory etc/ssh, === added + directory ssh_import_id, === added directory usr, === added + directory usr/bin, === added directory usr/share, === added + directory usr/share/man, === added directory usr/share/man/man1, + bin/ssh-import-id-gh => usr/bin/ssh-import-id-gh, bin/ssh-import-id- + lp => usr/bin/ssh-import-id-lp, bin/ssh-import-id => + ssh_import_id/__init__.py (properties changed: +x to -x), + debian/control, debian/install, debian/manpages, debian/rules, === + removed directory bin, setup.py, ssh-import-id.1 => + usr/share/man/man1/ssh-import-id.1, ssh_import_id => + etc/ssh/ssh_import_id, usr/bin/ssh-import-id: + - build depend on dh-python + - simplify package install, etc/ and usr/ + - syntax check both locations + - build an ssh_import_id python package/module + - put all common functionality into an ssh_import_id module + - add a browser useragent string, for protocol version support on the server + - move ssh-import-id-lp and ssh-import-id-gh functionality into a base + python function, and wrap those with shell + - remove a couple of subcommand shell outs by using native python calls + * setup.py, ssh_import_id/__init__.py: + - bump major version to 5.0, major changes here + * debian/rules, setup.py: + - add scripts back to setup.py + * ssh_import_id/__init__.py: + - add extra blank line back, for readability + * debian/control, ssh_import_id/__init__.py: + - use pkg_resources to get __version__, depend on package + + -- Dustin Kirkland Mon, 05 Oct 2015 18:32:55 -0500 + +ssh-import-id (4.5-0ubuntu1) wily; urgency=medium [ Andres Riancho and Dustin Kirkland ] * bin/ssh-import-id-gh: LP: #1397332 - handle two github error conditions (rate limiting and user not found) - -- Dustin Kirkland Mon, 05 Oct 2015 18:15:54 -0500 + -- Dustin Kirkland Mon, 05 Oct 2015 18:32:53 -0500 ssh-import-id (4.4-0ubuntu1) wily; urgency=medium diff -Nru ssh-import-id-4.5/debian/control ssh-import-id-5.0/debian/control --- ssh-import-id-4.5/debian/control 2016-01-30 15:49:21.000000000 +0000 +++ ssh-import-id-5.0/debian/control 2016-01-30 15:49:21.000000000 +0000 @@ -4,8 +4,9 @@ Maintainer: Dustin Kirkland Uploaders: Andrew Starr-Bochicchio Build-Depends: debhelper (>= 8), - python3-pep8, + dh-python, python3-all, + python3-pep8, python3-setuptools Standards-Version: 3.9.6 X-Python3-Version: >= 3.2 @@ -17,6 +18,7 @@ Architecture: all Depends: ca-certificates, openssh-client, + python3-pkg-resources, python3-requests (>= 1.1.0), wget, ${misc:Depends}, diff -Nru ssh-import-id-4.5/debian/install ssh-import-id-5.0/debian/install --- ssh-import-id-4.5/debian/install 2016-01-30 15:49:21.000000000 +0000 +++ ssh-import-id-5.0/debian/install 2016-01-30 15:49:21.000000000 +0000 @@ -1 +1,2 @@ -ssh_import_id etc/ssh +etc/ +usr/ diff -Nru ssh-import-id-4.5/debian/manpages ssh-import-id-5.0/debian/manpages --- ssh-import-id-4.5/debian/manpages 2016-01-30 15:49:21.000000000 +0000 +++ ssh-import-id-5.0/debian/manpages 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -ssh-import-id.1 diff -Nru ssh-import-id-4.5/debian/rules ssh-import-id-5.0/debian/rules --- ssh-import-id-4.5/debian/rules 2016-01-30 15:49:21.000000000 +0000 +++ ssh-import-id-5.0/debian/rules 2016-01-30 15:49:21.000000000 +0000 @@ -2,8 +2,7 @@ override_dh_auto_build: # Check syntax - python3 /usr/lib/python3/dist-packages/pep8.py \ - --verbose --repeat --ignore W191,E501,E121 bin/* + python3 /usr/lib/python3/dist-packages/pep8.py --verbose --repeat --ignore W191,E501,E121 ssh_import_id/* usr/bin/ssh-import-id dh_auto_build %: diff -Nru ssh-import-id-4.5/etc/ssh/ssh_import_id ssh-import-id-5.0/etc/ssh/ssh_import_id --- ssh-import-id-4.5/etc/ssh/ssh_import_id 1970-01-01 00:00:00.000000000 +0000 +++ ssh-import-id-5.0/etc/ssh/ssh_import_id 2013-02-05 06:54:27.000000000 +0000 @@ -0,0 +1,4 @@ +{ + "_comment_": "This file is JSON syntax and will be loaded by ssh-import-id to obtain the URL string, which defaults to launchpad.net. The following URL *must* be an https address with a valid, signed certificate!!! %s is the variable that will be filled by the ssh-import-id utility.", + "URL": "https://launchpad.net/~%s/+sshkeys" +} diff -Nru ssh-import-id-4.5/setup.py ssh-import-id-5.0/setup.py --- ssh-import-id-4.5/setup.py 2015-10-05 23:15:54.000000000 +0000 +++ ssh-import-id-5.0/setup.py 2016-01-30 15:43:48.000000000 +0000 @@ -23,16 +23,18 @@ except: readme = "See: http://pypi.python.org/pypi?name=ssh-import-id&:action=display_pkginfo" setup( - name='ssh-import-id', - description='Authorize SSH public keys from trusted online identities', - long_description=readme, - version='4.5', - author='Casey Marshall, Dustin Kirkland', - author_email='casey.marshall@gmail.com, dustin.kirkland@gmail.com', - license="GPLv3", - keywords="ssh public key", - url='https://launchpad.net/ssh-import-id', - platforms=['any'], - scripts=['bin/ssh-import-id', 'bin/ssh-import-id-gh', 'bin/ssh-import-id-lp'], - install_requires=["Requests>=1.1.0"], + name='ssh-import-id', + description='Authorize SSH public keys from trusted online identities', + long_description=readme, + version='5.0', + author='Dustin Kirkland, Casey Marshall', + author_email='dustin.kirkland@gmail.com, casey.marshall@gmail.com', + license="GPLv3", + keywords="ssh public key", + url='https://launchpad.net/ssh-import-id', + platforms=['any'], + packages=['ssh_import_id'], + py_modules=['ssh_import_id'], + scripts=['usr/bin/ssh-import-id', 'usr/bin/ssh-import-id-gh', 'usr/bin/ssh-import-id-lp'], + install_requires=["Requests>=1.1.0"], ) File /tmp/tmp49yOY8/pI5aDKNxA4/ssh-import-id-4.5/ssh_import_id is a regular file while file /tmp/tmp49yOY8/cPrXt4EV7j/ssh-import-id-5.0/ssh_import_id is a directory diff -Nru ssh-import-id-4.5/ssh-import-id.1 ssh-import-id-5.0/ssh-import-id.1 --- ssh-import-id-4.5/ssh-import-id.1 2013-02-15 20:50:44.000000000 +0000 +++ ssh-import-id-5.0/ssh-import-id.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -.TH ssh\-import\-id 1 "4 Feb 2013" ssh\-import "ssh\-import" -.SH NAME -\fBssh\-import\-id\fP \- retrieve one or more public keys from a public keyserver and append them to the current user's authorized_keys file (or some other specified file) - -.SH SYNOPSIS -.BI "ssh\-import\-id [options] USER_ID_1 [gh:USER_ID_2] ... [lp:USER_ID_n] - -.BI "ssh\-import\-id\-lp USER_ID_1 [USER_ID_2] ... [USER_ID_n] - -.BI "ssh\-import\-id\-gh USER_ID_1 [USER_ID_2] ... [USER_ID_n] - -.SH OPTIONS - \-h | \-\-help usage - \-o | \-\-output F write output to file 'F' (default ~/.ssh/authorized_keys, use "\-" for standard out) - \-r | \-\-remove remove keys from authorized keys file 'F' - PROTO:USER_ID Protocol can be 'lp' for Launchpad.net, or 'gh' for Github.com - -.SH DESCRIPTION -This utility will securely contact a public keyserver and retrieve one or more user's public keys, and append these to the current user's \fI~/.ssh/authorized_keys\fP file, standard output or any other specified output file. - -User IDs can be prepended by a protocol: - - - \fBlp:\fP to use \fIhttps://launchpad.net/~%s/+sshkeys\fP - - \fBgh:\fP to use \fIhttps://api.github.com/users/%s/keys\fP - -If the protocol is not explicitly specified, then \fBssh-import-id\fP will read a URL variable string from \fI/etc/ssh/ssh_import_id\fP as installed by your package manager and configured by your system administrator. You can override this locally by exporting the string you want in a URL environment variable. If all of these are empty, then the protocol is assumed to be "lp:", which was the original target implementation of this tool. - -Any keys added will be "labled" with a trailing comment, "# ssh-import-id PROTO:USER_ID". Revoking keys will first look for lines in the authorized keys file ending with that label. - -.SH SEE ALSO -\fIssh\fP(1) - -.SH FILES -\fI/etc/ssh/ssh_import_id\fP - -.SH AUTHOR -This manpage and the utility was written by Dustin Kirkland for Ubuntu systems (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 published by the Free Software Foundation. - -On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL. diff -Nru ssh-import-id-4.5/sshi.py ssh-import-id-5.0/sshi.py --- ssh-import-id-4.5/sshi.py 2014-12-23 11:38:53.000000000 +0000 +++ ssh-import-id-5.0/sshi.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -# -# ssh-import-id - Authorize SSH public keys from trusted online identities. -# -# Copyright (c) 2013 Casey Marshall -# Copyright (c) 2013 Dustin Kirkland -# -# ssh-import-id is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, version 3. -# -# ssh-import-id is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with ssh-import-id. If not, see . - -import os -import json -import subprocess -import sys -import requests -from urllib.parse import quote_plus - - -X_RATELIMIT_REMAINING = 'x-ratelimit-remaining' -HELP_URL = 'https://developer.github.com/v3/#rate-limiting' - - -if __name__ == '__main__': - if not sys.argv[:1]: - sys.stderr.write("Usage: %s \n" % (sys.argv[0])) - os._exit(1) - for ghid in sys.argv[1:]: - try: - url = "https://api.github.com/users/%s/keys" % (quote_plus(ghid)) - resp = requests.get(url, verify=True) - text = resp.text - data = json.loads(text) - - if resp.status_code == 404: - print('Username "%s" not found at GitHub API' % ghid) - os._exit(1) - - if X_RATELIMIT_REMAINING in resp.headers and int(resp.headers[X_RATELIMIT_REMAINING]) == 0: - print('GitHub REST API rate-limited this IP address. See %s' % HELP_URL) - os._exit(1) - - for keyobj in data: - sys.stdout.write("%s %s@github/%s\n" % (keyobj['key'], ghid, keyobj['id'])) - - sys.stdout.flush() - except (Exception,): - e = sys.exc_info()[1] - sys.stderr.write("ERROR: %s\n" % (str(e))) - os._exit(1) - sys.stdout.write("\n") - os._exit(0) - \ No newline at end of file diff -Nru ssh-import-id-4.5/usr/bin/ssh-import-id ssh-import-id-5.0/usr/bin/ssh-import-id --- ssh-import-id-4.5/usr/bin/ssh-import-id 1970-01-01 00:00:00.000000000 +0000 +++ ssh-import-id-5.0/usr/bin/ssh-import-id 2016-01-30 04:27:24.000000000 +0000 @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# +# ssh-import-id - Authorize SSH public keys from trusted online identities +# +# Copyright (c) 2013 Casey Marshall +# Copyright (c) 2013-16 Dustin Kirkland +# +# ssh-import-id is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3. +# +# ssh-import-id is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ssh-import-id. If not, see . + + +import argparse +import sys +from ssh_import_id import * + + +def main(): + errors = [] + try: + os.umask(0o177) + parser.options = parser.parse_args() + keys = [] + for userid in parser.options.userids: + user_pieces = userid.split(':') + if len(user_pieces) == 2: + proto, username = user_pieces + elif len(user_pieces) == 1: + proto, username = DEFAULT_PROTO, userid + else: + die("Invalid user ID: [%s]" % (userid)) + if parser.options.remove: + k = remove_keys(proto, username) + keys.extend(k) + action = "Removed" + else: + k = import_keys(proto, username, parser.options.useragent) + keys.extend(k) + action = "Authorized" + if len(k) == 0: + errors.append(userid) + logging.info("[%d] SSH keys [%s]" % (len(keys), action)) + except (Exception,): + e = sys.exc_info()[1] + die("%s" % (str(e))) + cleanup() + if len(errors) > 0: + die("No matching keys found for [%s]" % ','.join(errors)) + os._exit(0) + + +if __name__ == '__main__': + main() diff -Nru ssh-import-id-4.5/usr/bin/ssh-import-id-gh ssh-import-id-5.0/usr/bin/ssh-import-id-gh --- ssh-import-id-4.5/usr/bin/ssh-import-id-gh 1970-01-01 00:00:00.000000000 +0000 +++ ssh-import-id-5.0/usr/bin/ssh-import-id-gh 2016-01-30 05:11:11.000000000 +0000 @@ -0,0 +1,23 @@ +#!/bin/sh +# +# ssh-import-id - Authorize SSH public keys from trusted online identities. +# +# Copyright (c) 2016 Dustin Kirkland +# +# ssh-import-id is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3. +# +# ssh-import-id is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ssh-import-id. If not, see . + +set -e + +for i in $@; do + ssh-import-id gh:$i +done diff -Nru ssh-import-id-4.5/usr/bin/ssh-import-id-lp ssh-import-id-5.0/usr/bin/ssh-import-id-lp --- ssh-import-id-4.5/usr/bin/ssh-import-id-lp 1970-01-01 00:00:00.000000000 +0000 +++ ssh-import-id-5.0/usr/bin/ssh-import-id-lp 2016-01-30 05:11:25.000000000 +0000 @@ -0,0 +1,23 @@ +#!/bin/sh +# +# ssh-import-id - Authorize SSH public keys from trusted online identities. +# +# Copyright (c) 2016 Dustin Kirkland +# +# ssh-import-id is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3. +# +# ssh-import-id is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ssh-import-id. If not, see . + +set -e + +for i in $@; do + ssh-import-id lp:$i +done diff -Nru ssh-import-id-4.5/usr/share/man/man1/ssh-import-id.1 ssh-import-id-5.0/usr/share/man/man1/ssh-import-id.1 --- ssh-import-id-4.5/usr/share/man/man1/ssh-import-id.1 1970-01-01 00:00:00.000000000 +0000 +++ ssh-import-id-5.0/usr/share/man/man1/ssh-import-id.1 2016-01-30 15:04:51.000000000 +0000 @@ -0,0 +1,40 @@ +.TH ssh\-import\-id 1 "4 Feb 2013" ssh\-import "ssh\-import" +.SH NAME +\fBssh\-import\-id\fP \- retrieve one or more public keys from a public keyserver and append them to the current user's authorized_keys file (or some other specified file) + +.SH SYNOPSIS +.BI "ssh\-import\-id [options] USER_ID_1 [gh:USER_ID_2] ... [lp:USER_ID_n] + +.BI "ssh\-import\-id\-lp USER_ID_1 [USER_ID_2] ... [USER_ID_n] + +.BI "ssh\-import\-id\-gh USER_ID_1 [USER_ID_2] ... [USER_ID_n] + +.SH OPTIONS + \-h | \-\-help usage + \-o | \-\-output F write output to file 'F' (default ~/.ssh/authorized_keys, use "\-" for standard out) + \-r | \-\-remove remove keys from authorized keys file 'F' + \-u | \-\-useragent U append U to the user agent string + PROTO:USER_ID Protocol can be 'lp' for Launchpad.net, or 'gh' for Github.com + +.SH DESCRIPTION +This utility will securely contact a public keyserver and retrieve one or more user's public keys, and append these to the current user's \fI~/.ssh/authorized_keys\fP file, standard output or any other specified output file. + +User IDs can be prepended by a protocol: + + - \fBlp:\fP to use \fIhttps://launchpad.net/~%s/+sshkeys\fP + - \fBgh:\fP to use \fIhttps://api.github.com/users/%s/keys\fP + +If the protocol is not explicitly specified, then \fBssh-import-id\fP will read a URL variable string from \fI/etc/ssh/ssh_import_id\fP as installed by your package manager and configured by your system administrator. You can override this locally by exporting the string you want in a URL environment variable. If all of these are empty, then the protocol is assumed to be "lp:", which was the original target implementation of this tool. + +Any keys added will be "labled" with a trailing comment, "# ssh-import-id PROTO:USER_ID". Revoking keys will first look for lines in the authorized keys file ending with that label. + +.SH SEE ALSO +\fIssh\fP(1) + +.SH FILES +\fI/etc/ssh/ssh_import_id\fP + +.SH AUTHOR +This manpage and the utility was written by Dustin Kirkland for Ubuntu systems (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL.