diff options
| author | thibauth <thibauth@30fcff6e-8de6-41c7-acce-77ff6d1dd07b> | 2011-08-01 16:05:49 +0000 |
|---|---|---|
| committer | thibauth <thibauth@30fcff6e-8de6-41c7-acce-77ff6d1dd07b> | 2011-08-01 16:05:49 +0000 |
| commit | 3bb7785b59ef92278b24f2636b5250b07ce788ee (patch) | |
| tree | 44679a6548631ff2f278bcf941cdb6c56349cdf5 /planetlab/pssh/psshlib/askpass_client.py | |
| parent | a33698d5d7d4bb49fadb4e29daef0d6d58c7c2fc (diff) | |
| download | pacemaker-3bb7785b59ef92278b24f2636b5250b07ce788ee.tar.gz | |
Planetlab utilities
git-svn-id: https://scm.gforge.inria.fr/svn/pacemaker@50 30fcff6e-8de6-41c7-acce-77ff6d1dd07b
Diffstat (limited to 'planetlab/pssh/psshlib/askpass_client.py')
| -rw-r--r-- | planetlab/pssh/psshlib/askpass_client.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/planetlab/pssh/psshlib/askpass_client.py b/planetlab/pssh/psshlib/askpass_client.py new file mode 100644 index 0000000..fa4d40a --- /dev/null +++ b/planetlab/pssh/psshlib/askpass_client.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- Mode: python -*- + +# Copyright (c) 2009, Andrew McNabb + +"""Implementation of SSH_ASKPASS to get a password to ssh from pssh. + +The password is read from the socket specified by the environment variable +PSSH_ASKPASS_SOCKET. The other end of this socket is pssh. + +The ssh man page discusses SSH_ASKPASS as follows: + If ssh needs a passphrase, it will read the passphrase from the current + terminal if it was run from a terminal. If ssh does not have a terminal + associated with it but DISPLAY and SSH_ASKPASS are set, it will execute + the program specified by SSH_ASKPASS and open an X11 window to read the + passphrase. This is particularly useful when calling ssh from a .xsession + or related script. (Note that on some machines it may be necessary to + redirect the input from /dev/null to make this work.) +""" + +import os +import socket +import sys +import textwrap + +bin_dir = os.path.dirname(os.path.abspath(sys.argv[0])) +askpass_bin_path = os.path.join(bin_dir, 'pssh-askpass') +ASKPASS_PATHS = (askpass_bin_path, + '/usr/libexec/pssh/pssh-askpass', + '/usr/local/libexec/pssh/pssh-askpass', + '/usr/lib/pssh/pssh-askpass', + '/usr/local/lib/pssh/pssh-askpass') + +_executable_path = None + +def executable_path(): + """Determines the value to use for SSH_ASKPASS. + + The value is cached since this may be called many times. + """ + global _executable_path + if _executable_path is None: + for path in ASKPASS_PATHS: + if os.access(path, os.X_OK): + _executable_path = path + break + else: + _executable_path = '' + sys.stderr.write(textwrap.fill("Warning: could not find an" + " executable path for askpass because PSSH was not" + " installed correctly. Password prompts will not work.")) + sys.stderr.write('\n') + return _executable_path + +def askpass_main(): + """Connects to pssh over the socket specified at PSSH_ASKPASS_SOCKET.""" + + # It's not documented anywhere, as far as I can tell, but ssh may prompt + # for a password or ask a yes/no question. The command-line argument + # specifies what is needed. + if len(sys.argv) > 1: + prompt = sys.argv[1] + if not prompt.lower().endswith('password: '): + sys.stderr.write(prompt) + sys.stderr.write('\n') + sys.exit(1) + + address = os.getenv('PSSH_ASKPASS_SOCKET') + if not address: + sys.stderr.write(textwrap.fill("pssh error: SSH requested a password." + " Please create SSH keys or use the -A option to provide a" + " password.")) + sys.stderr.write('\n') + sys.exit(1) + + sock = socket.socket(socket.AF_UNIX) + try: + sock.connect(address) + except socket.error: + _, e, _ = sys.exc_info() + message = e.args[1] + sys.stderr.write("Couldn't bind to %s: %s.\n" % (address, message)) + sys.exit(2) + + try: + password = sock.makefile().read() + except socket.error: + sys.stderr.write("Socket error.\n") + sys.exit(3) + + print(password) + + +if __name__ == '__main__': + askpass_main() |
