Author: Eric S. Raymond <esr@thyrsus.com>"""
-import os, sys, getopt, getpass, tempfile
+import os, sys, getopt, getpass, tempfile, ConfigParser
###############################################################################
#
return child.before
def ssh(self, command):
- "Execute a command on the remote host."
+ "Execute a command on the remote host, returning its output."
return self.__exec("ssh -p %s -l %s %s \"%s\"" % (session.port,
self.user,
self.host,
else:
return seen.split()[0] # Return permission field of listing.
+class KeyConfig(ConfigParser.RawConfigParser):
+ "Store our state about remote keys."
+ def __init__(self):
+ ConfigParser.RawConfigParser.__init__(self)
+ self.read(os.path.expanduser('~/.ssh-installkeys'))
+ def save(self):
+ self.write(open(os.path.expanduser('~/.ssh-installkeys'), "w"))
+ def readremote(self, session):
+ authorized = session.ssh("cat ~/.ssh/authorized_keys")
+ keydict = {}
+ for line in authorized.split("\n"):
+ if line:
+ (keytype, content, keyid) = line.strip().split()
+ if keyid not in keydict:
+ keydict[keyid] = []
+ keydict[keyid].append(keytype)
+ self.remove_section(session.host)
+ self.add_section(session.host)
+ for (keyid, types) in keydict.items():
+ self.set(session.host, keyid, ",".join(types))
+
def die(msg):
"Die quietly."
print msg
elif (switch == '-v'):
verbose = 1
+ config = KeyConfig()
+
if not arguments:
print "No remote host specified."
print __doc__
if delete:
os.system('ssh -l %s %s "rm -fr .ssh"' % (login, host))
+ config.remove_section(host)
print "Keys for %s on %s have been deleted." % (login, host)
raise SystemExit, 0
# OK, install keys remotely if they don't exist
if session.exists("~/.ssh/authorized_keys"):
print "authorized_keys already exists on", host
+ config.readremote(session)
elif not check:
print "Copying your public keys to", host
session.scp(keyfile, "~/.ssh/authorized_keys")
+ config.readremote(session)
except SystemExit:
pass
except RuntimeError:
print "Check is complete."
else:
print "Keys for %s on %s have been installed." % (login, host)
+ config.save()
# End
the @ will be clipped off and used as the login name. Otherwise your
local login name will be used.</para>
+<para>Places where you install keys will be recorded in
+<filename>~/.ssh/installkeys</filename>. This configuration file will
+also be updated when you use the check option, so you can use
+that option to check sites where you may have previously installed
+keys and add them to the list.</para>
+
<para>Note: this script does not parse your ssh configuration —
therefore, if you have specified a different remote user in your
configuration, this script will not know that. You can use the