# $Id: ssh-installkeys,v 1.18 2004/06/21 12:53:48 esr Exp esr $
-import os, sys, getopt, string, getpass, tempfile
+import os, sys, getopt, getpass, tempfile
###############################################################################
#
class ExceptionPexpect(Exception):
"""Base class for all exceptions raised by this module."""
def __init__(self, value):
+ Exception.__init__(self)
self.value = value
def __str__(self):
- return `self.value`
+ return repr(self.value)
class EOF(ExceptionPexpect):
"""Raised when EOF is read from a child."""
class TIMEOUT(ExceptionPexpect):
self.before = None
self.after = None
self.match = None
+ self.flag_eof = 0
if args is None:
self.args = split_command_line(command)
Python only garbage collects Python objects. Since OS file descriptors
are not Python objects, so they must be handled manually.
"""
- self.close()
+ self.close()
def __spawn(self):
"""This starts the given command in a child process. This does
def close (self):
"""This is experimental.
- This closes the file descriptor of the child application.
- It makes no attempt to actually kill the child or wait for its status.
- """
- if self.child_fd != -1:
- os.close (self.child_fd)
- self.child_fd = -1
+ This closes the file descriptor of the child application.
+ It makes no attempt to actually kill the child or wait for its status.
+ """
+ if self.child_fd != -1:
+ os.close (self.child_fd)
+ self.child_fd = -1
def set_echo (self, on):
"""This sets the terminal echo-mode on or off."""
#
###############################################################################
-version=1.5
+version = 1.5
class ssh_session:
"Session with extra state including the password to be used."
if self.verbose:
sys.stderr.write("-> " + command + "\n")
while True:
- seen=child.expect([EOF,'assword:','continue connecting (yes/no)?','Permission denied','refused','not resolve'])
+ seen = child.expect([EOF,
+ 'assword:',
+ 'continue connecting (yes/no)?',
+ 'Permission denied',
+ 'refused',
+ 'not resolve'])
if self.verbose:
sys.stderr.write("<- " + child.before + "\n")
if seen == 0:
return child.before
def ssh(self, command):
- return self.__exec("ssh -p %s -l %s %s \"%s\""%(session.port, self.user,self.host,command))
+ "Execute a command on the remote host."
+ return self.__exec("ssh -p %s -l %s %s \"%s\"" % (session.port,
+ self.user,
+ self.host,
+ command))
def scp(self, src, dst):
+ "Copy a file to the remote host."
return self.__exec("scp -P %s %s %s@%s:%s" % (session.port, src, session.user, session.host, dst))
- def exists(self, file):
+ def exists(self, fn):
"Retrieve file permissions of specified remote file."
- seen = self.ssh("/bin/ls -ld %s" % file)
+ seen = self.ssh("/bin/ls -ld %s" % fn)
if self.verbose:
- sys.stderr.write("Existence check on %s gave %s\n" % (file,`seen`))
- if string.find(seen, "No such file") > -1:
+ sys.stderr.write("Existence check on %s gave %s\n" % (fn, repr(seen)))
+ if seen.find("No such file") > -1:
return None # File doesn't exist
else:
return seen.split()[0] # Return permission field of listing.
def die(msg):
+ "Die quietly."
print msg
print "Goodbye."
raise SystemExit, 1
-def fixperms(session, file, checkonly=None):
+def fixperms(session, fn, checkonly=False):
"Force perms of remote file to user read on, group/other write off."
- perms = session.exists(file)
+ perms = session.exists(fn)
ok = (perms[1] == 'r' and perms[5] == '-' and perms[8] == '-')
print "Remote %s permissions are %s which is %s." \
- % (file, perms, ("wrong", "OK")[ok])
+ % (fn, 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" % fn)
return ok
-def forcefile(session, file, command, checkonly=None):
+def forcefile(session, fn, command, checkonly=False):
"Create file with command if it does not already exist."
- perms = session.exists(file)
+ perms = session.exists(fn)
if perms is None:
- print "Remote %s doesn't exist." % file
- if check:
+ print "Remote %s doesn't exist." % fn
+ if checkonly:
die("Bailing out...")
else:
- print "Creating remote %s" % file
+ print "Creating remote %s" % fn
session.ssh(command)
- perms = session.exists(file)
+ perms = session.exists(fn)
else:
- print file, "already exists."
+ print fn, "already exists."
return perms
if __name__ == '__main__':
port = 22
for (switch, val) in options:
- if (switch == '-c'):
+ if (switch == '-c'):
check = 1
elif (switch == '-d'):
delete = 1
- elif (switch == '-p'):
- port = val;
- elif (switch == '-h'):
- print __doc__
+ elif (switch == '-p'):
+ port = val
+ elif (switch == '-h'):
+ print __doc__
raise SystemExit, 0
- elif (switch == '-v'):
- verbose = 1
+ elif (switch == '-v'):
+ verbose = 1
if not arguments:
print "No remote host specified."
else:
host = arguments[0]
if "@" in host:
- (login, host) = string.split(host, "@")
+ (login, host) = host.split("@")
else:
login = os.environ.get("LOGNAME") or os.environ.get("USER")
print "I don't see any key pairs. You need to generate some."
die("Try re-running this script without the check-only option.")
public_keys = []
- for (keytype, file) in (("rsa1", "identity"), ("dsa", "id_dsa")):
+ for (keytype, fn) in (("rsa1", "identity"), ("dsa", "id_dsa")):
print "About to generate a %s key. You will be prompted for a passphrase," % keytype
print "Pressing enter at that prompt will create a key with no passphrase"
- os.system("ssh-keygen -t %s -f %s" % (keytype, file))
- public_keys.append(file + ".pub")
+ os.system("ssh-keygen -t %s -f %s" % (keytype, fn))
+ public_keys.append(fn + ".pub")
- print "I see the following public keys:", string.join(public_keys,", ")
- for file in public_keys:
- private_key = file[:-4]
- legend = private_key + " corresponding to " + file + " "
+ print "I see the following public keys:", ", ".join(public_keys)
+ for filename in public_keys:
+ private_key = filename[:-4]
+ legend = private_key + " corresponding to " + filename + " "
if os.access(private_key, os.R_OK):
print legend + "exists and is readable."
else:
# Update or check
try:
- keyfile = tempfile.mktemp()
- os.system("cat " + string.join(public_keys, " ") + " >" + keyfile)
- if verbose:
- print "Public keys consolidated in %s" % keyfile
-
- # Get session to remote host.
- print "Starting session to %s..." % host
- session = ssh_session(login, port, host, verbose=verbose)
-
- # Permissions checks
- fixperms(session, "~", check)
- forcefile(session, "~/.ssh", "mkdir ~/.ssh", check)
- fixperms(session, "~/.ssh", check)
-
- # OK, install keys remotely if they don't exist
- if session.exists("~/.ssh/authorized_keys"):
- print "authorized_keys already exists on", host
- elif not check:
- print "Copying your public keys to", host
- session.scp(keyfile, "~/.ssh/authorized_keys")
+ keyfile = tempfile.mktemp()
+ os.system("cat " + " ".join(public_keys) + " >" + keyfile)
+ if verbose:
+ print "Public keys consolidated in %s" % keyfile
+
+ # Get session to remote host.
+ print "Starting session to %s..." % host
+ session = ssh_session(login, port, host, verbose=verbose)
+
+ # Permissions checks
+ fixperms(session, "~", check)
+ forcefile(session, "~/.ssh", "mkdir ~/.ssh", check)
+ fixperms(session, "~/.ssh", check)
+
+ # OK, install keys remotely if they don't exist
+ if session.exists("~/.ssh/authorized_keys"):
+ print "authorized_keys already exists on", host
+ elif not check:
+ print "Copying your public keys to", host
+ session.scp(keyfile, "~/.ssh/authorized_keys")
except SystemExit:
pass
except RuntimeError: