summaryrefslogtreecommitdiffstats
path: root/lldb/third_party/Python/module/pexpect-2.4/pxssh.py
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/third_party/Python/module/pexpect-2.4/pxssh.py')
-rw-r--r--lldb/third_party/Python/module/pexpect-2.4/pxssh.py367
1 files changed, 0 insertions, 367 deletions
diff --git a/lldb/third_party/Python/module/pexpect-2.4/pxssh.py b/lldb/third_party/Python/module/pexpect-2.4/pxssh.py
deleted file mode 100644
index 59db8d2a31e..00000000000
--- a/lldb/third_party/Python/module/pexpect-2.4/pxssh.py
+++ /dev/null
@@ -1,367 +0,0 @@
-"""This class extends pexpect.spawn to specialize setting up SSH connections.
-This adds methods for login, logout, and expecting the shell prompt.
-
-$Id: pxssh.py 513 2008-02-09 18:26:13Z noah $
-"""
-
-from pexpect import *
-import pexpect
-import time
-
-__all__ = ['ExceptionPxssh', 'pxssh']
-
-# Exception classes used by this module.
-
-
-class ExceptionPxssh(ExceptionPexpect):
- """Raised for pxssh exceptions.
- """
-
-
-class pxssh (spawn):
-
- """This class extends pexpect.spawn to specialize setting up SSH
- connections. This adds methods for login, logout, and expecting the shell
- prompt. It does various tricky things to handle many situations in the SSH
- login process. For example, if the session is your first login, then pxssh
- automatically accepts the remote certificate; or if you have public key
- authentication setup then pxssh won't wait for the password prompt.
-
- pxssh uses the shell prompt to synchronize output from the remote host. In
- order to make this more robust it sets the shell prompt to something more
- unique than just $ or #. This should work on most Borne/Bash or Csh style
- shells.
-
- Example that runs a few commands on a remote server and prints the result::
-
- import pxssh
- import getpass
- try:
- s = pxssh.pxssh()
- hostname = raw_input('hostname: ')
- username = raw_input('username: ')
- password = getpass.getpass('password: ')
- s.login (hostname, username, password)
- s.sendline ('uptime') # run a command
- s.prompt() # match the prompt
- print s.before # print everything before the prompt.
- s.sendline ('ls -l')
- s.prompt()
- print s.before
- s.sendline ('df')
- s.prompt()
- print s.before
- s.logout()
- except pxssh.ExceptionPxssh, e:
- print "pxssh failed on login."
- print str(e)
-
- Note that if you have ssh-agent running while doing development with pxssh
- then this can lead to a lot of confusion. Many X display managers (xdm,
- gdm, kdm, etc.) will automatically start a GUI agent. You may see a GUI
- dialog box popup asking for a password during development. You should turn
- off any key agents during testing. The 'force_password' attribute will turn
- off public key authentication. This will only work if the remote SSH server
- is configured to allow password logins. Example of using 'force_password'
- attribute::
-
- s = pxssh.pxssh()
- s.force_password = True
- hostname = raw_input('hostname: ')
- username = raw_input('username: ')
- password = getpass.getpass('password: ')
- s.login (hostname, username, password)
- """
-
- def __init__(
- self,
- timeout=30,
- maxread=2000,
- searchwindowsize=None,
- logfile=None,
- cwd=None,
- env=None):
- spawn.__init__(
- self,
- None,
- timeout=timeout,
- maxread=maxread,
- searchwindowsize=searchwindowsize,
- logfile=logfile,
- cwd=cwd,
- env=env)
-
- self.name = '<pxssh>'
-
- # SUBTLE HACK ALERT! Note that the command to set the prompt uses a
- # slightly different string than the regular expression to match it. This
- # is because when you set the prompt the command will echo back, but we
- # don't want to match the echoed command. So if we make the set command
- # slightly different than the regex we eliminate the problem. To make the
- # set command different we add a backslash in front of $. The $ doesn't
- # need to be escaped, but it doesn't hurt and serves to make the set
- # prompt command different than the regex.
-
- # used to match the command-line prompt
- self.UNIQUE_PROMPT = "\[PEXPECT\][\$\#] "
- self.PROMPT = self.UNIQUE_PROMPT
-
- # used to set shell command-line prompt to UNIQUE_PROMPT.
- self.PROMPT_SET_SH = "PS1='[PEXPECT]\$ '"
- self.PROMPT_SET_CSH = "set prompt='[PEXPECT]\$ '"
- self.SSH_OPTS = "-o'RSAAuthentication=no' -o 'PubkeyAuthentication=no'"
- # Disabling X11 forwarding gets rid of the annoying SSH_ASKPASS from
- # displaying a GUI password dialog. I have not figured out how to
- # disable only SSH_ASKPASS without also disabling X11 forwarding.
- # Unsetting SSH_ASKPASS on the remote side doesn't disable it! Annoying!
- #self.SSH_OPTS = "-x -o'RSAAuthentication=no' -o 'PubkeyAuthentication=no'"
- self.force_password = False
- self.auto_prompt_reset = True
-
- def levenshtein_distance(self, a, b):
- """This calculates the Levenshtein distance between a and b.
- """
-
- n, m = len(a), len(b)
- if n > m:
- a, b = b, a
- n, m = m, n
- current = range(n + 1)
- for i in range(1, m + 1):
- previous, current = current, [i] + [0] * n
- for j in range(1, n + 1):
- add, delete = previous[j] + 1, current[j - 1] + 1
- change = previous[j - 1]
- if a[j - 1] != b[i - 1]:
- change = change + 1
- current[j] = min(add, delete, change)
- return current[n]
-
- def sync_original_prompt(self):
- """This attempts to find the prompt. Basically, press enter and record
- the response; press enter again and record the response; if the two
- responses are similar then assume we are at the original prompt. This
- is a slow function. It can take over 10 seconds. """
-
- # All of these timing pace values are magic.
- # I came up with these based on what seemed reliable for
- # connecting to a heavily loaded machine I have.
- # If latency is worse than these values then this will fail.
-
- try:
- # GAS: Clear out the cache before getting the prompt
- self.read_nonblocking(size=10000, timeout=1)
- except TIMEOUT:
- pass
- time.sleep(0.1)
- self.sendline()
- time.sleep(0.5)
- x = self.read_nonblocking(size=1000, timeout=1)
- time.sleep(0.1)
- self.sendline()
- time.sleep(0.5)
- a = self.read_nonblocking(size=1000, timeout=1)
- time.sleep(0.1)
- self.sendline()
- time.sleep(0.5)
- b = self.read_nonblocking(size=1000, timeout=1)
- ld = self.levenshtein_distance(a, b)
- len_a = len(a)
- if len_a == 0:
- return False
- if float(ld) / len_a < 0.4:
- return True
- return False
-
- # TODO: This is getting messy and I'm pretty sure this isn't perfect.
- # TODO: I need to draw a flow chart for this.
- def login(
- self,
- server,
- username,
- password='',
- terminal_type='ansi',
- original_prompt=r"[#$]",
- login_timeout=10,
- port=None,
- auto_prompt_reset=True):
- """This logs the user into the given server. It uses the
- 'original_prompt' to try to find the prompt right after login. When it
- finds the prompt it immediately tries to reset the prompt to something
- more easily matched. The default 'original_prompt' is very optimistic
- and is easily fooled. It's more reliable to try to match the original
- prompt as exactly as possible to prevent false matches by server
- strings such as the "Message Of The Day". On many systems you can
- disable the MOTD on the remote server by creating a zero-length file
- called "~/.hushlogin" on the remote server. If a prompt cannot be found
- then this will not necessarily cause the login to fail. In the case of
- a timeout when looking for the prompt we assume that the original
- prompt was so weird that we could not match it, so we use a few tricks
- to guess when we have reached the prompt. Then we hope for the best and
- blindly try to reset the prompt to something more unique. If that fails
- then login() raises an ExceptionPxssh exception.
-
- In some situations it is not possible or desirable to reset the
- original prompt. In this case, set 'auto_prompt_reset' to False to
- inhibit setting the prompt to the UNIQUE_PROMPT. Remember that pxssh
- uses a unique prompt in the prompt() method. If the original prompt is
- not reset then this will disable the prompt() method unless you
- manually set the PROMPT attribute. """
-
- ssh_options = '-q'
- if self.force_password:
- ssh_options = ssh_options + ' ' + self.SSH_OPTS
- if port is not None:
- ssh_options = ssh_options + ' -p %s' % (str(port))
- cmd = "ssh %s -l %s %s" % (ssh_options, username, server)
-
- # This does not distinguish between a remote server 'password' prompt
- # and a local ssh 'passphrase' prompt (for unlocking a private key).
- spawn._spawn(self, cmd)
- i = self.expect(
- [
- "(?i)are you sure you want to continue connecting",
- original_prompt,
- "(?i)(?:password)|(?:passphrase for key)",
- "(?i)permission denied",
- "(?i)terminal type",
- TIMEOUT,
- "(?i)connection closed by remote host"],
- timeout=login_timeout)
-
- # First phase
- if i == 0:
- # New certificate -- always accept it.
- # This is what you get if SSH does not have the remote host's
- # public key stored in the 'known_hosts' cache.
- self.sendline("yes")
- i = self.expect(
- [
- "(?i)are you sure you want to continue connecting",
- original_prompt,
- "(?i)(?:password)|(?:passphrase for key)",
- "(?i)permission denied",
- "(?i)terminal type",
- TIMEOUT])
- if i == 2: # password or passphrase
- self.sendline(password)
- i = self.expect(
- [
- "(?i)are you sure you want to continue connecting",
- original_prompt,
- "(?i)(?:password)|(?:passphrase for key)",
- "(?i)permission denied",
- "(?i)terminal type",
- TIMEOUT])
- if i == 4:
- self.sendline(terminal_type)
- i = self.expect(
- [
- "(?i)are you sure you want to continue connecting",
- original_prompt,
- "(?i)(?:password)|(?:passphrase for key)",
- "(?i)permission denied",
- "(?i)terminal type",
- TIMEOUT])
-
- # Second phase
- if i == 0:
- # This is weird. This should not happen twice in a row.
- self.close()
- raise ExceptionPxssh(
- 'Weird error. Got "are you sure" prompt twice.')
- elif i == 1: # can occur if you have a public key pair set to authenticate.
- # TODO: May NOT be OK if expect() got tricked and matched a false
- # prompt.
- pass
- elif i == 2: # password prompt again
- # For incorrect passwords, some ssh servers will
- # ask for the password again, others return 'denied' right away.
- # If we get the password prompt again then this means
- # we didn't get the password right the first time.
- self.close()
- raise ExceptionPxssh('password refused')
- elif i == 3: # permission denied -- password was bad.
- self.close()
- raise ExceptionPxssh('permission denied')
- elif i == 4: # terminal type again? WTF?
- self.close()
- raise ExceptionPxssh(
- 'Weird error. Got "terminal type" prompt twice.')
- elif i == 5: # Timeout
- # This is tricky... I presume that we are at the command-line prompt.
- # It may be that the shell prompt was so weird that we couldn't match
- # it. Or it may be that we couldn't log in for some other reason. I
- # can't be sure, but it's safe to guess that we did login because if
- # I presume wrong and we are not logged in then this should be caught
- # later when I try to set the shell prompt.
- pass
- elif i == 6: # Connection closed by remote host
- self.close()
- raise ExceptionPxssh('connection closed')
- else: # Unexpected
- self.close()
- raise ExceptionPxssh('unexpected login response')
- if not self.sync_original_prompt():
- self.close()
- raise ExceptionPxssh('could not synchronize with original prompt')
- # We appear to be in.
- # set shell prompt to something unique.
- if auto_prompt_reset:
- if not self.set_unique_prompt():
- self.close()
- raise ExceptionPxssh(
- 'could not set shell prompt\n' + self.before)
- return True
-
- def logout(self):
- """This sends exit to the remote shell. If there are stopped jobs then
- this automatically sends exit twice. """
-
- self.sendline("exit")
- index = self.expect([EOF, "(?i)there are stopped jobs"])
- if index == 1:
- self.sendline("exit")
- self.expect(EOF)
- self.close()
-
- def prompt(self, timeout=20):
- """This matches the shell prompt. This is little more than a short-cut
- to the expect() method. This returns True if the shell prompt was
- matched. This returns False if there was a timeout. Note that if you
- called login() with auto_prompt_reset set to False then you should have
- manually set the PROMPT attribute to a regex pattern for matching the
- prompt. """
-
- i = self.expect([self.PROMPT, TIMEOUT], timeout=timeout)
- if i == 1:
- return False
- return True
-
- def set_unique_prompt(self):
- """This sets the remote prompt to something more unique than # or $.
- This makes it easier for the prompt() method to match the shell prompt
- unambiguously. This method is called automatically by the login()
- method, but you may want to call it manually if you somehow reset the
- shell prompt. For example, if you 'su' to a different user then you
- will need to manually reset the prompt. This sends shell commands to
- the remote host to set the prompt, so this assumes the remote host is
- ready to receive commands.
-
- Alternatively, you may use your own prompt pattern. Just set the PROMPT
- attribute to a regular expression that matches it. In this case you
- should call login() with auto_prompt_reset=False; then set the PROMPT
- attribute. After that the prompt() method will try to match your prompt
- pattern."""
-
- self.sendline("unset PROMPT_COMMAND")
- self.sendline(self.PROMPT_SET_SH) # sh-style
- i = self.expect([TIMEOUT, self.PROMPT], timeout=10)
- if i == 0: # csh-style
- self.sendline(self.PROMPT_SET_CSH)
- i = self.expect([TIMEOUT, self.PROMPT], timeout=10)
- if i == 0:
- return False
- return True
-
-# vi:ts=4:sw=4:expandtab:ft=python:
OpenPOWER on IntegriCloud