From 7ab237237913ea4af33af83fd645c092e47d962f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 4 Dec 2003 00:44:45 +0000 Subject: [PATCH] This is ready to ship. --- ssh-installkeys | 72 +++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/ssh-installkeys b/ssh-installkeys index 7c31d13..ba82a22 100755 --- a/ssh-installkeys +++ b/ssh-installkeys @@ -2,7 +2,7 @@ """ssh-installkeys -- prepare a remote account for ssh access This script tries to export ssh public keys to a specified site. it will -walk the user through generating key pairs if it doesn't find any to export. +walk you through generating key pairs if it doesn't find any to export. It handles all the fiddly details like making sure local and remote permissions are correct, and tells you what it's doing if it has to change anything. @@ -11,18 +11,16 @@ Options: -h Print usage summary and exit -l login Specify login name to be used at the remote site (default '%s') --c Check local and remote configuration only, dn't try to fix problems. +-c Check local and remote configuration only, don't try to fix problems. -d Delete remote .ssh configuration. -v Report all commands sent to host and output received. -$Id$ by Eric S. Raymond -""" +Author: Eric S. Raymond -# Conditions we don't check yet: -# 1. Port 22 isn't taking connections -# 2. User has no account on machine. +$Id: ssh-installkeys,v 1.12 2003/12/03 22:58:22 esr Exp esr $ +""" -import os, sys, getopt, string, getpass +import os, sys, getopt, string, getpass, tempfile ############################################################################### # @@ -50,8 +48,8 @@ License: Python Software Foundation License Noah Spurrier -$Revision: 1.11 $ -$Date: 2003/01/28 10:40:49 $ +$Revision: 1.12 $ +$Date: 2003/12/03 22:58:22 $ """ import os, sys import select @@ -72,7 +70,7 @@ A critical module was not found. Probably this OS does not support it. Currently pexpect is intended for UNIX operating systems (including OS-X).""" __version__ = '0.94' -__revision__ = '$Revision: 1.11 $' +__revision__ = '$Revision: 1.12 $' __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', '__version__', '__revision__'] @@ -641,14 +639,17 @@ def die(msg): def fixperms(session, file, checkonly=None): "Force perms of remote file to user read on, group/other write off." perms = session.exists(file) - print "Remote %s permissions are %s" % (file, perms) - if not (perms[1] == 'r' and perms[5] == '-' and perms[8] == '-'): + ok = (perms[1] == 'r' and perms[5] == '-' and perms[8] == '-') + print "Remote %s permissions are %s which is %s." \ + % (file, perms, ("wrong", "OK")[ok]) + if not ok: print "User read should be on, Group and Other write permissions should be off." if not checkonly: print "Correcting permissions..." - session.ssh("/bin/chmod u+r,g-w,o-w %s" % file) + session.ssh("/bin/chmod u+r,g-w,o-w %s" % file) + return ok -def forcefile(session, file, command): +def forcefile(session, file, command, checkonly=None): "Create file with command if it does not already exist." perms = session.exists(file) if perms is None: @@ -665,24 +666,24 @@ def forcefile(session, file, command): if __name__ == '__main__': # Process options - (options, arguments) = getopt.getopt(sys.argv[1:], "chl:v") - login = os.environ.get("USER") + (options, arguments) = getopt.getopt(sys.argv[1:], "cdhl:v") + optlogin = None check = 0 verbose = 0 - if not login: - login = os.environ.get("LOGNAME") + delete = 0 + + print options for (switch, val) in options: if (switch == '-c'): check = 1 - elif (switch == 'd'): - os.system('ssh -l esr %s "rm -fr .ssh"' % host) - raise SystemExit, 0 + elif (switch == '-d'): + delete = 1 elif (switch == '-h'): print __doc__ % login raise SystemExit, 0 elif (switch == '-l'): - login = val + optlogin = val elif (switch == '-v'): verbose = 1 @@ -692,6 +693,10 @@ if __name__ == '__main__': raise SystemExit, 0 else: host = arguments[0] + if "@" in host: + (atlogin, host) = string.split(host, "@") + login = optlogin or atlogin \ + or os.environ.get("USER") or os.environ.get("LOGNAME") # Verify that key pairs are present on the local side print "Checking your local configuration..." @@ -738,30 +743,39 @@ if __name__ == '__main__': else: die(legend + "does not exist or is unreadable.") + print "Local configuration looks correct." + + if delete: + os.system('ssh -l %s %s "rm -fr .ssh"' % (login, host)) + print "Keys for %s on %s have been deleted." % (login, host) + raise SystemExit, 0 + + # Update or check try: - keyfile = os.tmpnam() + keyfile = tempfile.mktemp() os.system("cat " + string.join(public_keys, " ") + " >" + keyfile) if verbose: print "Public keys consolidated in %s" % keyfile - print "Local configuration looks correct." - # Get session to remote host. print "Starting session to %s..." % host session = ssh_session(login, host, verbose=verbose) # Permissions checks fixperms(session, "~", check) - forcefile(session, "~/.ssh", "mkdir ~/.ssh") + forcefile(session, "~/.ssh", "mkdir ~/.ssh", check) fixperms(session, "~/.ssh", check) # OK, install keys remotely if they don't exist - if not session.exists("~/.ssh/authorized_keys"): + if not check and not session.exists("~/.ssh/authorized_keys"): session.scp(keyfile, "~/.ssh/authorized_keys") except SystemExit: pass # It's all over now... os.remove(keyfile) - print "Done." + if check: + print "Check is complete." + else: + print "Keys for %s on %s have been installed." % (login, host) # End -- 2.43.0