summaryrefslogtreecommitdiffstats
path: root/demos
diff options
context:
space:
mode:
Diffstat (limited to 'demos')
-rwxr-xr-xdemos/demo.py187
-rwxr-xr-xdemos/demo_keygen.py174
-rw-r--r--demos/demo_server.py185
-rw-r--r--demos/demo_sftp.py143
-rw-r--r--demos/demo_simple.py116
-rw-r--r--demos/forward.py257
-rw-r--r--demos/interactive.py101
-rwxr-xr-xdemos/rforward.py230
-rw-r--r--demos/test_rsa.key15
-rw-r--r--demos/user_rsa_key15
-rw-r--r--demos/user_rsa_key.pub1
11 files changed, 1424 insertions, 0 deletions
diff --git a/demos/demo.py b/demos/demo.py
new file mode 100755
index 0000000..5252db7
--- /dev/null
+++ b/demos/demo.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+import base64
+from binascii import hexlify
+import getpass
+import os
+import select
+import socket
+import sys
+import time
+import traceback
+from paramiko.py3compat import input
+
+import paramiko
+
+try:
+ import interactive
+except ImportError:
+ from . import interactive
+
+
+def agent_auth(transport, username):
+ """
+ Attempt to authenticate to the given transport using any of the private
+ keys available from an SSH agent.
+ """
+
+ agent = paramiko.Agent()
+ agent_keys = agent.get_keys()
+ if len(agent_keys) == 0:
+ return
+
+ for key in agent_keys:
+ print("Trying ssh-agent key %s" % hexlify(key.get_fingerprint()))
+ try:
+ transport.auth_publickey(username, key)
+ print("... success!")
+ return
+ except paramiko.SSHException:
+ print("... nope.")
+
+
+def manual_auth(username, hostname):
+ default_auth = "p"
+ auth = input(
+ "Auth by (p)assword, (r)sa key, or (d)ss key? [%s] " % default_auth
+ )
+ if len(auth) == 0:
+ auth = default_auth
+
+ if auth == "r":
+ default_path = os.path.join(os.environ["HOME"], ".ssh", "id_rsa")
+ path = input("RSA key [%s]: " % default_path)
+ if len(path) == 0:
+ path = default_path
+ try:
+ key = paramiko.RSAKey.from_private_key_file(path)
+ except paramiko.PasswordRequiredException:
+ password = getpass.getpass("RSA key password: ")
+ key = paramiko.RSAKey.from_private_key_file(path, password)
+ t.auth_publickey(username, key)
+ elif auth == "d":
+ default_path = os.path.join(os.environ["HOME"], ".ssh", "id_dsa")
+ path = input("DSS key [%s]: " % default_path)
+ if len(path) == 0:
+ path = default_path
+ try:
+ key = paramiko.DSSKey.from_private_key_file(path)
+ except paramiko.PasswordRequiredException:
+ password = getpass.getpass("DSS key password: ")
+ key = paramiko.DSSKey.from_private_key_file(path, password)
+ t.auth_publickey(username, key)
+ else:
+ pw = getpass.getpass("Password for %s@%s: " % (username, hostname))
+ t.auth_password(username, pw)
+
+
+# setup logging
+paramiko.util.log_to_file("demo.log")
+
+username = ""
+if len(sys.argv) > 1:
+ hostname = sys.argv[1]
+ if hostname.find("@") >= 0:
+ username, hostname = hostname.split("@")
+else:
+ hostname = input("Hostname: ")
+if len(hostname) == 0:
+ print("*** Hostname required.")
+ sys.exit(1)
+port = 22
+if hostname.find(":") >= 0:
+ hostname, portstr = hostname.split(":")
+ port = int(portstr)
+
+# now connect
+try:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.connect((hostname, port))
+except Exception as e:
+ print("*** Connect failed: " + str(e))
+ traceback.print_exc()
+ sys.exit(1)
+
+try:
+ t = paramiko.Transport(sock)
+ try:
+ t.start_client()
+ except paramiko.SSHException:
+ print("*** SSH negotiation failed.")
+ sys.exit(1)
+
+ try:
+ keys = paramiko.util.load_host_keys(
+ os.path.expanduser("~/.ssh/known_hosts")
+ )
+ except IOError:
+ try:
+ keys = paramiko.util.load_host_keys(
+ os.path.expanduser("~/ssh/known_hosts")
+ )
+ except IOError:
+ print("*** Unable to open host keys file")
+ keys = {}
+
+ # check server's host key -- this is important.
+ key = t.get_remote_server_key()
+ if hostname not in keys:
+ print("*** WARNING: Unknown host key!")
+ elif key.get_name() not in keys[hostname]:
+ print("*** WARNING: Unknown host key!")
+ elif keys[hostname][key.get_name()] != key:
+ print("*** WARNING: Host key has changed!!!")
+ sys.exit(1)
+ else:
+ print("*** Host key OK.")
+
+ # get username
+ if username == "":
+ default_username = getpass.getuser()
+ username = input("Username [%s]: " % default_username)
+ if len(username) == 0:
+ username = default_username
+
+ agent_auth(t, username)
+ if not t.is_authenticated():
+ manual_auth(username, hostname)
+ if not t.is_authenticated():
+ print("*** Authentication failed. :(")
+ t.close()
+ sys.exit(1)
+
+ chan = t.open_session()
+ chan.get_pty()
+ chan.invoke_shell()
+ print("*** Here we go!\n")
+ interactive.interactive_shell(chan)
+ chan.close()
+ t.close()
+
+except Exception as e:
+ print("*** Caught exception: " + str(e.__class__) + ": " + str(e))
+ traceback.print_exc()
+ try:
+ t.close()
+ except:
+ pass
+ sys.exit(1)
diff --git a/demos/demo_keygen.py b/demos/demo_keygen.py
new file mode 100755
index 0000000..12637ed
--- /dev/null
+++ b/demos/demo_keygen.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2010 Sofian Brabez <sbz@6dev.net>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+
+from binascii import hexlify
+from optparse import OptionParser
+
+from paramiko import DSSKey
+from paramiko import RSAKey
+from paramiko.ssh_exception import SSHException
+from paramiko.py3compat import u
+
+usage = """
+%prog [-v] [-b bits] -t type [-N new_passphrase] [-f output_keyfile]"""
+
+default_values = {
+ "ktype": "dsa",
+ "bits": 1024,
+ "filename": "output",
+ "comment": "",
+}
+
+key_dispatch_table = {"dsa": DSSKey, "rsa": RSAKey}
+
+
+def progress(arg=None):
+
+ if not arg:
+ sys.stdout.write("0%\x08\x08\x08 ")
+ sys.stdout.flush()
+ elif arg[0] == "p":
+ sys.stdout.write("25%\x08\x08\x08\x08 ")
+ sys.stdout.flush()
+ elif arg[0] == "h":
+ sys.stdout.write("50%\x08\x08\x08\x08 ")
+ sys.stdout.flush()
+ elif arg[0] == "x":
+ sys.stdout.write("75%\x08\x08\x08\x08 ")
+ sys.stdout.flush()
+
+
+if __name__ == "__main__":
+
+ phrase = None
+ pfunc = None
+
+ parser = OptionParser(usage=usage)
+ parser.add_option(
+ "-t",
+ "--type",
+ type="string",
+ dest="ktype",
+ help="Specify type of key to create (dsa or rsa)",
+ metavar="ktype",
+ default=default_values["ktype"],
+ )
+ parser.add_option(
+ "-b",
+ "--bits",
+ type="int",
+ dest="bits",
+ help="Number of bits in the key to create",
+ metavar="bits",
+ default=default_values["bits"],
+ )
+ parser.add_option(
+ "-N",
+ "--new-passphrase",
+ dest="newphrase",
+ help="Provide new passphrase",
+ metavar="phrase",
+ )
+ parser.add_option(
+ "-P",
+ "--old-passphrase",
+ dest="oldphrase",
+ help="Provide old passphrase",
+ metavar="phrase",
+ )
+ parser.add_option(
+ "-f",
+ "--filename",
+ type="string",
+ dest="filename",
+ help="Filename of the key file",
+ metavar="filename",
+ default=default_values["filename"],
+ )
+ parser.add_option(
+ "-q", "--quiet", default=False, action="store_false", help="Quiet"
+ )
+ parser.add_option(
+ "-v", "--verbose", default=False, action="store_true", help="Verbose"
+ )
+ parser.add_option(
+ "-C",
+ "--comment",
+ type="string",
+ dest="comment",
+ help="Provide a new comment",
+ metavar="comment",
+ default=default_values["comment"],
+ )
+
+ (options, args) = parser.parse_args()
+
+ if len(sys.argv) == 1:
+ parser.print_help()
+ sys.exit(0)
+
+ for o in list(default_values.keys()):
+ globals()[o] = getattr(options, o, default_values[o.lower()])
+
+ if options.newphrase:
+ phrase = getattr(options, "newphrase")
+
+ if options.verbose:
+ pfunc = progress
+ sys.stdout.write(
+ "Generating priv/pub %s %d bits key pair (%s/%s.pub)..."
+ % (ktype, bits, filename, filename)
+ )
+ sys.stdout.flush()
+
+ if ktype == "dsa" and bits > 1024:
+ raise SSHException("DSA Keys must be 1024 bits")
+
+ if ktype not in key_dispatch_table:
+ raise SSHException(
+ "Unknown %s algorithm to generate keys pair" % ktype
+ )
+
+ # generating private key
+ prv = key_dispatch_table[ktype].generate(bits=bits, progress_func=pfunc)
+ prv.write_private_key_file(filename, password=phrase)
+
+ # generating public key
+ pub = key_dispatch_table[ktype](filename=filename, password=phrase)
+ with open("%s.pub" % filename, "w") as f:
+ f.write("%s %s" % (pub.get_name(), pub.get_base64()))
+ if options.comment:
+ f.write(" %s" % comment)
+
+ if options.verbose:
+ print("done.")
+
+ hash = u(hexlify(pub.get_fingerprint()))
+ print(
+ "Fingerprint: %d %s %s.pub (%s)"
+ % (
+ bits,
+ ":".join([hash[i : 2 + i] for i in range(0, len(hash), 2)]),
+ filename,
+ ktype.upper(),
+ )
+ )
diff --git a/demos/demo_server.py b/demos/demo_server.py
new file mode 100644
index 0000000..6cb2dc5
--- /dev/null
+++ b/demos/demo_server.py
@@ -0,0 +1,185 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import base64
+from binascii import hexlify
+import os
+import socket
+import sys
+import threading
+import traceback
+
+import paramiko
+from paramiko.py3compat import b, u, decodebytes
+
+
+# setup logging
+paramiko.util.log_to_file("demo_server.log")
+
+host_key = paramiko.RSAKey(filename="test_rsa.key")
+# host_key = paramiko.DSSKey(filename='test_dss.key')
+
+print("Read key: " + u(hexlify(host_key.get_fingerprint())))
+
+
+class Server(paramiko.ServerInterface):
+ # 'data' is the output of base64.b64encode(key)
+ # (using the "user_rsa_key" files)
+ data = (
+ b"AAAAB3NzaC1yc2EAAAABIwAAAIEAyO4it3fHlmGZWJaGrfeHOVY7RWO3P9M7hp"
+ b"fAu7jJ2d7eothvfeuoRFtJwhUmZDluRdFyhFY/hFAh76PJKGAusIqIQKlkJxMC"
+ b"KDqIexkgHAfID/6mqvmnSJf0b5W8v5h2pI/stOSwTQ+pxVhwJ9ctYDhRSlF0iT"
+ b"UWT10hcuO4Ks8="
+ )
+ good_pub_key = paramiko.RSAKey(data=decodebytes(data))
+
+ def __init__(self):
+ self.event = threading.Event()
+
+ def check_channel_request(self, kind, chanid):
+ if kind == "session":
+ return paramiko.OPEN_SUCCEEDED
+ return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
+
+ def check_auth_password(self, username, password):
+ if (username == "robey") and (password == "foo"):
+ return paramiko.AUTH_SUCCESSFUL
+ return paramiko.AUTH_FAILED
+
+ def check_auth_publickey(self, username, key):
+ print("Auth attempt with key: " + u(hexlify(key.get_fingerprint())))
+ if (username == "robey") and (key == self.good_pub_key):
+ return paramiko.AUTH_SUCCESSFUL
+ return paramiko.AUTH_FAILED
+
+ def check_auth_gssapi_with_mic(
+ self, username, gss_authenticated=paramiko.AUTH_FAILED, cc_file=None
+ ):
+ """
+ .. note::
+ We are just checking in `AuthHandler` that the given user is a
+ valid krb5 principal! We don't check if the krb5 principal is
+ allowed to log in on the server, because there is no way to do that
+ in python. So if you develop your own SSH server with paramiko for
+ a certain platform like Linux, you should call ``krb5_kuserok()`` in
+ your local kerberos library to make sure that the krb5_principal
+ has an account on the server and is allowed to log in as a user.
+
+ .. seealso::
+ `krb5_kuserok() man page
+ <http://www.unix.com/man-page/all/3/krb5_kuserok/>`_
+ """
+ if gss_authenticated == paramiko.AUTH_SUCCESSFUL:
+ return paramiko.AUTH_SUCCESSFUL
+ return paramiko.AUTH_FAILED
+
+ def check_auth_gssapi_keyex(
+ self, username, gss_authenticated=paramiko.AUTH_FAILED, cc_file=None
+ ):
+ if gss_authenticated == paramiko.AUTH_SUCCESSFUL:
+ return paramiko.AUTH_SUCCESSFUL
+ return paramiko.AUTH_FAILED
+
+ def enable_auth_gssapi(self):
+ return True
+
+ def get_allowed_auths(self, username):
+ return "gssapi-keyex,gssapi-with-mic,password,publickey"
+
+ def check_channel_shell_request(self, channel):
+ self.event.set()
+ return True
+
+ def check_channel_pty_request(
+ self, channel, term, width, height, pixelwidth, pixelheight, modes
+ ):
+ return True
+
+
+DoGSSAPIKeyExchange = True
+
+# now connect
+try:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ sock.bind(("", 2200))
+except Exception as e:
+ print("*** Bind failed: " + str(e))
+ traceback.print_exc()
+ sys.exit(1)
+
+try:
+ sock.listen(100)
+ print("Listening for connection ...")
+ client, addr = sock.accept()
+except Exception as e:
+ print("*** Listen/accept failed: " + str(e))
+ traceback.print_exc()
+ sys.exit(1)
+
+print("Got a connection!")
+
+try:
+ t = paramiko.Transport(client, gss_kex=DoGSSAPIKeyExchange)
+ t.set_gss_host(socket.getfqdn(""))
+ try:
+ t.load_server_moduli()
+ except:
+ print("(Failed to load moduli -- gex will be unsupported.)")
+ raise
+ t.add_server_key(host_key)
+ server = Server()
+ try:
+ t.start_server(server=server)
+ except paramiko.SSHException:
+ print("*** SSH negotiation failed.")
+ sys.exit(1)
+
+ # wait for auth
+ chan = t.accept(20)
+ if chan is None:
+ print("*** No channel.")
+ sys.exit(1)
+ print("Authenticated!")
+
+ server.event.wait(10)
+ if not server.event.is_set():
+ print("*** Client never asked for a shell.")
+ sys.exit(1)
+
+ chan.send("\r\n\r\nWelcome to my dorky little BBS!\r\n\r\n")
+ chan.send(
+ "We are on fire all the time! Hooray! Candy corn for everyone!\r\n"
+ )
+ chan.send("Happy birthday to Robot Dave!\r\n\r\n")
+ chan.send("Username: ")
+ f = chan.makefile("rU")
+ username = f.readline().strip("\r\n")
+ chan.send("\r\nI don't like you, " + username + ".\r\n")
+ chan.close()
+
+except Exception as e:
+ print("*** Caught exception: " + str(e.__class__) + ": " + str(e))
+ traceback.print_exc()
+ try:
+ t.close()
+ except:
+ pass
+ sys.exit(1)
diff --git a/demos/demo_sftp.py b/demos/demo_sftp.py
new file mode 100644
index 0000000..dbcb2cb
--- /dev/null
+++ b/demos/demo_sftp.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# based on code provided by raymond mosteller (thanks!)
+
+import base64
+import getpass
+import os
+import socket
+import sys
+import traceback
+
+import paramiko
+from paramiko.py3compat import input
+
+
+# setup logging
+paramiko.util.log_to_file("demo_sftp.log")
+
+# Paramiko client configuration
+UseGSSAPI = True # enable GSS-API / SSPI authentication
+DoGSSAPIKeyExchange = True
+Port = 22
+
+# get hostname
+username = ""
+if len(sys.argv) > 1:
+ hostname = sys.argv[1]
+ if hostname.find("@") >= 0:
+ username, hostname = hostname.split("@")
+else:
+ hostname = input("Hostname: ")
+if len(hostname) == 0:
+ print("*** Hostname required.")
+ sys.exit(1)
+
+if hostname.find(":") >= 0:
+ hostname, portstr = hostname.split(":")
+ Port = int(portstr)
+
+
+# get username
+if username == "":
+ default_username = getpass.getuser()
+ username = input("Username [%s]: " % default_username)
+ if len(username) == 0:
+ username = default_username
+if not UseGSSAPI:
+ password = getpass.getpass("Password for %s@%s: " % (username, hostname))
+else:
+ password = None
+
+
+# get host key, if we know one
+hostkeytype = None
+hostkey = None
+try:
+ host_keys = paramiko.util.load_host_keys(
+ os.path.expanduser("~/.ssh/known_hosts")
+ )
+except IOError:
+ try:
+ # try ~/ssh/ too, because windows can't have a folder named ~/.ssh/
+ host_keys = paramiko.util.load_host_keys(
+ os.path.expanduser("~/ssh/known_hosts")
+ )
+ except IOError:
+ print("*** Unable to open host keys file")
+ host_keys = {}
+
+if hostname in host_keys:
+ hostkeytype = host_keys[hostname].keys()[0]
+ hostkey = host_keys[hostname][hostkeytype]
+ print("Using host key of type %s" % hostkeytype)
+
+
+# now, connect and use paramiko Transport to negotiate SSH2 across the connection
+try:
+ t = paramiko.Transport((hostname, Port))
+ t.connect(
+ hostkey,
+ username,
+ password,
+ gss_host=socket.getfqdn(hostname),
+ gss_auth=UseGSSAPI,
+ gss_kex=DoGSSAPIKeyExchange,
+ )
+ sftp = paramiko.SFTPClient.from_transport(t)
+
+ # dirlist on remote host
+ dirlist = sftp.listdir(".")
+ print("Dirlist: %s" % dirlist)
+
+ # copy this demo onto the server
+ try:
+ sftp.mkdir("demo_sftp_folder")
+ except IOError:
+ print("(assuming demo_sftp_folder/ already exists)")
+ with sftp.open("demo_sftp_folder/README", "w") as f:
+ f.write("This was created by demo_sftp.py.\n")
+ with open("demo_sftp.py", "r") as f:
+ data = f.read()
+ sftp.open("demo_sftp_folder/demo_sftp.py", "w").write(data)
+ print("created demo_sftp_folder/ on the server")
+
+ # copy the README back here
+ with sftp.open("demo_sftp_folder/README", "r") as f:
+ data = f.read()
+ with open("README_demo_sftp", "w") as f:
+ f.write(data)
+ print("copied README back here")
+
+ # BETTER: use the get() and put() methods
+ sftp.put("demo_sftp.py", "demo_sftp_folder/demo_sftp.py")
+ sftp.get("demo_sftp_folder/README", "README_demo_sftp")
+
+ t.close()
+
+except Exception as e:
+ print("*** Caught exception: %s: %s" % (e.__class__, e))
+ traceback.print_exc()
+ try:
+ t.close()
+ except:
+ pass
+ sys.exit(1)
diff --git a/demos/demo_simple.py b/demos/demo_simple.py
new file mode 100644
index 0000000..bd932c3
--- /dev/null
+++ b/demos/demo_simple.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+import base64
+import getpass
+import os
+import socket
+import sys
+import traceback
+from paramiko.py3compat import input
+
+import paramiko
+
+try:
+ import interactive
+except ImportError:
+ from . import interactive
+
+
+# setup logging
+paramiko.util.log_to_file("demo_simple.log")
+# Paramiko client configuration
+UseGSSAPI = (
+ paramiko.GSS_AUTH_AVAILABLE
+) # enable "gssapi-with-mic" authentication, if supported by your python installation
+DoGSSAPIKeyExchange = (
+ paramiko.GSS_AUTH_AVAILABLE
+) # enable "gssapi-kex" key exchange, if supported by your python installation
+# UseGSSAPI = False
+# DoGSSAPIKeyExchange = False
+port = 22
+
+# get hostname
+username = ""
+if len(sys.argv) > 1:
+ hostname = sys.argv[1]
+ if hostname.find("@") >= 0:
+ username, hostname = hostname.split("@")
+else:
+ hostname = input("Hostname: ")
+if len(hostname) == 0:
+ print("*** Hostname required.")
+ sys.exit(1)
+
+if hostname.find(":") >= 0:
+ hostname, portstr = hostname.split(":")
+ port = int(portstr)
+
+
+# get username
+if username == "":
+ default_username = getpass.getuser()
+ username = input("Username [%s]: " % default_username)
+ if len(username) == 0:
+ username = default_username
+if not UseGSSAPI and not DoGSSAPIKeyExchange:
+ password = getpass.getpass("Password for %s@%s: " % (username, hostname))
+
+
+# now, connect and use paramiko Client to negotiate SSH2 across the connection
+try:
+ client = paramiko.SSHClient()
+ client.load_system_host_keys()
+ client.set_missing_host_key_policy(paramiko.WarningPolicy())
+ print("*** Connecting...")
+ if not UseGSSAPI and not DoGSSAPIKeyExchange:
+ client.connect(hostname, port, username, password)
+ else:
+ try:
+ client.connect(
+ hostname,
+ port,
+ username,
+ gss_auth=UseGSSAPI,
+ gss_kex=DoGSSAPIKeyExchange,
+ )
+ except Exception:
+ # traceback.print_exc()
+ password = getpass.getpass(
+ "Password for %s@%s: " % (username, hostname)
+ )
+ client.connect(hostname, port, username, password)
+
+ chan = client.invoke_shell()
+ print(repr(client.get_transport()))
+ print("*** Here we go!\n")
+ interactive.interactive_shell(chan)
+ chan.close()
+ client.close()
+
+except Exception as e:
+ print("*** Caught exception: %s: %s" % (e.__class__, e))
+ traceback.print_exc()
+ try:
+ client.close()
+ except:
+ pass
+ sys.exit(1)
diff --git a/demos/forward.py b/demos/forward.py
new file mode 100644
index 0000000..869e390
--- /dev/null
+++ b/demos/forward.py
@@ -0,0 +1,257 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""
+Sample script showing how to do local port forwarding over paramiko.
+
+This script connects to the requested SSH server and sets up local port
+forwarding (the openssh -L option) from a local port through a tunneled
+connection to a destination reachable from the SSH server machine.
+"""
+
+import getpass
+import os
+import socket
+import select
+
+try:
+ import SocketServer
+except ImportError:
+ import socketserver as SocketServer
+
+import sys
+from optparse import OptionParser
+
+import paramiko
+
+SSH_PORT = 22
+DEFAULT_PORT = 4000
+
+g_verbose = True
+
+
+class ForwardServer(SocketServer.ThreadingTCPServer):
+ daemon_threads = True
+ allow_reuse_address = True
+
+
+class Handler(SocketServer.BaseRequestHandler):
+ def handle(self):
+ try:
+ chan = self.ssh_transport.open_channel(
+ "direct-tcpip",
+ (self.chain_host, self.chain_port),
+ self.request.getpeername(),
+ )
+ except Exception as e:
+ verbose(
+ "Incoming request to %s:%d failed: %s"
+ % (self.chain_host, self.chain_port, repr(e))
+ )
+ return
+ if chan is None:
+ verbose(
+ "Incoming request to %s:%d was rejected by the SSH server."
+ % (self.chain_host, self.chain_port)
+ )
+ return
+
+ verbose(
+ "Connected! Tunnel open %r -> %r -> %r"
+ % (
+ self.request.getpeername(),
+ chan.getpeername(),
+ (self.chain_host, self.chain_port),
+ )
+ )
+ while True:
+ r, w, x = select.select([self.request, chan], [], [])
+ if self.request in r:
+ data = self.request.recv(1024)
+ if len(data) == 0:
+ break
+ chan.send(data)
+ if chan in r:
+ data = chan.recv(1024)
+ if len(data) == 0:
+ break
+ self.request.send(data)
+
+ peername = self.request.getpeername()
+ chan.close()
+ self.request.close()
+ verbose("Tunnel closed from %r" % (peername,))
+
+
+def forward_tunnel(local_port, remote_host, remote_port, transport):
+ # this is a little convoluted, but lets me configure things for the Handler
+ # object. (SocketServer doesn't give Handlers any way to access the outer
+ # server normally.)
+ class SubHander(Handler):
+ chain_host = remote_host
+ chain_port = remote_port
+ ssh_transport = transport
+
+ ForwardServer(("", local_port), SubHander).serve_forever()
+
+
+def verbose(s):
+ if g_verbose:
+ print(s)
+
+
+HELP = """\
+Set up a forward tunnel across an SSH server, using paramiko. A local port
+(given with -p) is forwarded across an SSH session to an address:port from
+the SSH server. This is similar to the openssh -L option.
+"""
+
+
+def get_host_port(spec, default_port):
+ "parse 'hostname:22' into a host and port, with the port optional"
+ args = (spec.split(":", 1) + [default_port])[:2]
+ args[1] = int(args[1])
+ return args[0], args[1]
+
+
+def parse_options():
+ global g_verbose
+
+ parser = OptionParser(
+ usage="usage: %prog [options] <ssh-server>[:<server-port>]",
+ version="%prog 1.0",
+ description=HELP,
+ )
+ parser.add_option(
+ "-q",
+ "--quiet",
+ action="store_false",
+ dest="verbose",
+ default=True,
+ help="squelch all informational output",
+ )
+ parser.add_option(
+ "-p",
+ "--local-port",
+ action="store",
+ type="int",
+ dest="port",
+ default=DEFAULT_PORT,
+ help="local port to forward (default: %d)" % DEFAULT_PORT,
+ )
+ parser.add_option(
+ "-u",
+ "--user",
+ action="store",
+ type="string",
+ dest="user",
+ default=getpass.getuser(),
+ help="username for SSH authentication (default: %s)"
+ % getpass.getuser(),
+ )
+ parser.add_option(
+ "-K",
+ "--key",
+ action="store",
+ type="string",
+ dest="keyfile",
+ default=None,
+ help="private key file to use for SSH authentication",
+ )
+ parser.add_option(
+ "",
+ "--no-key",
+ action="store_false",
+ dest="look_for_keys",
+ default=True,
+ help="don't look for or use a private key file",
+ )
+ parser.add_option(
+ "-P",
+ "--password",
+ action="store_true",
+ dest="readpass",
+ default=False,
+ help="read password (for key or password auth) from stdin",
+ )
+ parser.add_option(
+ "-r",
+ "--remote",
+ action="store",
+ type="string",
+ dest="remote",
+ default=None,
+ metavar="host:port",
+ help="remote host and port to forward to",
+ )
+ options, args = parser.parse_args()
+
+ if len(args) != 1:
+ parser.error("Incorrect number of arguments.")
+ if options.remote is None:
+ parser.error("Remote address required (-r).")
+
+ g_verbose = options.verbose
+ server_host, server_port = get_host_port(args[0], SSH_PORT)
+ remote_host, remote_port = get_host_port(options.remote, SSH_PORT)
+ return options, (server_host, server_port), (remote_host, remote_port)
+
+
+def main():
+ options, server, remote = parse_options()
+
+ password = None
+ if options.readpass:
+ password = getpass.getpass("Enter SSH password: ")
+
+ client = paramiko.SSHClient()
+ client.load_system_host_keys()
+ client.set_missing_host_key_policy(paramiko.WarningPolicy())
+
+ verbose("Connecting to ssh host %s:%d ..." % (server[0], server[1]))
+ try:
+ client.connect(
+ server[0],
+ server[1],
+ username=options.user,
+ key_filename=options.keyfile,
+ look_for_keys=options.look_for_keys,
+ password=password,
+ )
+ except Exception as e:
+ print("*** Failed to connect to %s:%d: %r" % (server[0], server[1], e))
+ sys.exit(1)
+
+ verbose(
+ "Now forwarding port %d to %s:%d ..."
+ % (options.port, remote[0], remote[1])
+ )
+
+ try:
+ forward_tunnel(
+ options.port, remote[0], remote[1], client.get_transport()
+ )
+ except KeyboardInterrupt:
+ print("C-c: Port forwarding stopped.")
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/demos/interactive.py b/demos/interactive.py
new file mode 100644
index 0000000..16eae0e
--- /dev/null
+++ b/demos/interactive.py
@@ -0,0 +1,101 @@
+# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+import socket
+import sys
+from paramiko.py3compat import u
+
+# windows does not have termios...
+try:
+ import termios
+ import tty
+
+ has_termios = True
+except ImportError:
+ has_termios = False
+
+
+def interactive_shell(chan):
+ if has_termios:
+ posix_shell(chan)
+ else:
+ windows_shell(chan)
+
+
+def posix_shell(chan):
+ import select
+
+ oldtty = termios.tcgetattr(sys.stdin)
+ try:
+ tty.setraw(sys.stdin.fileno())
+ tty.setcbreak(sys.stdin.fileno())
+ chan.settimeout(0.0)
+
+ while True:
+ r, w, e = select.select([chan, sys.stdin], [], [])
+ if chan in r:
+ try:
+ x = u(chan.recv(1024))
+ if len(x) == 0:
+ sys.stdout.write("\r\n*** EOF\r\n")
+ break
+ sys.stdout.write(x)
+ sys.stdout.flush()
+ except socket.timeout:
+ pass
+ if sys.stdin in r:
+ x = sys.stdin.read(1)
+ if len(x) == 0:
+ break
+ chan.send(x)
+
+ finally:
+ termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
+
+
+# thanks to Mike Looijmans for this code
+def windows_shell(chan):
+ import threading
+
+ sys.stdout.write(
+ "Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n"
+ )
+
+ def writeall(sock):
+ while True:
+ data = sock.recv(256)
+ if not data:
+ sys.stdout.write("\r\n*** EOF ***\r\n\r\n")
+ sys.stdout.flush()
+ break
+ sys.stdout.write(data)
+ sys.stdout.flush()
+
+ writer = threading.Thread(target=writeall, args=(chan,))
+ writer.start()
+
+ try:
+ while True:
+ d = sys.stdin.read(1)
+ if not d:
+ break
+ chan.send(d)
+ except EOFError:
+ # user hit ^Z or F6
+ pass
diff --git a/demos/rforward.py b/demos/rforward.py
new file mode 100755
index 0000000..200634a
--- /dev/null
+++ b/demos/rforward.py
@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2008 Robey Pointer <robeypointer@gmail.com>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""
+Sample script showing how to do remote port forwarding over paramiko.
+
+This script connects to the requested SSH server and sets up remote port
+forwarding (the openssh -R option) from a remote port through a tunneled
+connection to a destination reachable from the local machine.
+"""
+
+import getpass
+import os
+import socket
+import select
+import sys
+import threading
+from optparse import OptionParser
+
+import paramiko
+
+SSH_PORT = 22
+DEFAULT_PORT = 4000
+
+g_verbose = True
+
+
+def handler(chan, host, port):
+ sock = socket.socket()
+ try:
+ sock.connect((host, port))
+ except Exception as e:
+ verbose("Forwarding request to %s:%d failed: %r" % (host, port, e))
+ return
+
+ verbose(
+ "Connected! Tunnel open %r -> %r -> %r"
+ % (chan.origin_addr, chan.getpeername(), (host, port))
+ )
+ while True:
+ r, w, x = select.select([sock, chan], [], [])
+ if sock in r:
+ data = sock.recv(1024)
+ if len(data) == 0:
+ break
+ chan.send(data)
+ if chan in r:
+ data = chan.recv(1024)
+ if len(data) == 0:
+ break
+ sock.send(data)
+ chan.close()
+ sock.close()
+ verbose("Tunnel closed from %r" % (chan.origin_addr,))
+
+
+def reverse_forward_tunnel(server_port, remote_host, remote_port, transport):
+ transport.request_port_forward("", server_port)
+ while True:
+ chan = transport.accept(1000)
+ if chan is None:
+ continue
+ thr = threading.Thread(
+ target=handler, args=(chan, remote_host, remote_port)
+ )
+ thr.setDaemon(True)
+ thr.start()
+
+
+def verbose(s):
+ if g_verbose:
+ print(s)
+
+
+HELP = """\
+Set up a reverse forwarding tunnel across an SSH server, using paramiko. A
+port on the SSH server (given with -p) is forwarded across an SSH session
+back to the local machine, and out to a remote site reachable from this
+network. This is similar to the openssh -R option.
+"""
+
+
+def get_host_port(spec, default_port):
+ "parse 'hostname:22' into a host and port, with the port optional"
+ args = (spec.split(":", 1) + [default_port])[:2]
+ args[1] = int(args[1])
+ return args[0], args[1]
+
+
+def parse_options():
+ global g_verbose
+
+ parser = OptionParser(
+ usage="usage: %prog [options] <ssh-server>[:<server-port>]",
+ version="%prog 1.0",
+ description=HELP,
+ )
+ parser.add_option(
+ "-q",
+ "--quiet",
+ action="store_false",
+ dest="verbose",
+ default=True,
+ help="squelch all informational output",
+ )
+ parser.add_option(
+ "-p",
+ "--remote-port",
+ action="store",
+ type="int",
+ dest="port",
+ default=DEFAULT_PORT,
+ help="port on server to forward (default: %d)" % DEFAULT_PORT,
+ )
+ parser.add_option(
+ "-u",
+ "--user",
+ action="store",
+ type="string",
+ dest="user",
+ default=getpass.getuser(),
+ help="username for SSH authentication (default: %s)"
+ % getpass.getuser(),
+ )
+ parser.add_option(
+ "-K",
+ "--key",
+ action="store",
+ type="string",
+ dest="keyfile",
+ default=None,
+ help="private key file to use for SSH authentication",
+ )
+ parser.add_option(
+ "",
+ "--no-key",
+ action="store_false",
+ dest="look_for_keys",
+ default=True,
+ help="don't look for or use a private key file",
+ )
+ parser.add_option(
+ "-P",
+ "--password",
+ action="store_true",
+ dest="readpass",
+ default=False,
+ help="read password (for key or password auth) from stdin",
+ )
+ parser.add_option(
+ "-r",
+ "--remote",
+ action="store",
+ type="string",
+ dest="remote",
+ default=None,
+ metavar="host:port",
+ help="remote host and port to forward to",
+ )
+ options, args = parser.parse_args()
+
+ if len(args) != 1:
+ parser.error("Incorrect number of arguments.")
+ if options.remote is None:
+ parser.error("Remote address required (-r).")
+
+ g_verbose = options.verbose
+ server_host, server_port = get_host_port(args[0], SSH_PORT)
+ remote_host, remote_port = get_host_port(options.remote, SSH_PORT)
+ return options, (server_host, server_port), (remote_host, remote_port)
+
+
+def main():
+ options, server, remote = parse_options()
+
+ password = None
+ if options.readpass:
+ password = getpass.getpass("Enter SSH password: ")
+
+ client = paramiko.SSHClient()
+ client.load_system_host_keys()
+ client.set_missing_host_key_policy(paramiko.WarningPolicy())
+
+ verbose("Connecting to ssh host %s:%d ..." % (server[0], server[1]))
+ try:
+ client.connect(
+ server[0],
+ server[1],
+ username=options.user,
+ key_filename=options.keyfile,
+ look_for_keys=options.look_for_keys,
+ password=password,
+ )
+ except Exception as e:
+ print("*** Failed to connect to %s:%d: %r" % (server[0], server[1], e))
+ sys.exit(1)
+
+ verbose(
+ "Now forwarding remote port %d to %s:%d ..."
+ % (options.port, remote[0], remote[1])
+ )
+
+ try:
+ reverse_forward_tunnel(
+ options.port, remote[0], remote[1], client.get_transport()
+ )
+ except KeyboardInterrupt:
+ print("C-c: Port forwarding stopped.")
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/demos/test_rsa.key b/demos/test_rsa.key
new file mode 100644
index 0000000..f50e9c5
--- /dev/null
+++ b/demos/test_rsa.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWgIBAAKBgQDTj1bqB4WmayWNPB+8jVSYpZYk80Ujvj680pOTh2bORBjbIAyz
+oWGW+GUjzKxTiiPvVmxFgx5wdsFvF03v34lEVVhMpouqPAYQ15N37K/ir5XY+9m/
+d8ufMCkjeXsQkKqFbAlQcnWMCRnOoPHS3I4vi6hmnDDeeYTSRvfLbW0fhwIBIwKB
+gBIiOqZYaoqbeD9OS9z2K9KR2atlTxGxOJPXiP4ESqP3NVScWNwyZ3NXHpyrJLa0
+EbVtzsQhLn6rF+TzXnOlcipFvjsem3iYzCpuChfGQ6SovTcOjHV9z+hnpXvQ/fon
+soVRZY65wKnF7IAoUwTmJS9opqgrN6kRgCd3DASAMd1bAkEA96SBVWFt/fJBNJ9H
+tYnBKZGw0VeHOYmVYbvMSstssn8un+pQpUm9vlG/bp7Oxd/m+b9KWEh2xPfv6zqU
+avNwHwJBANqzGZa/EpzF4J8pGti7oIAPUIDGMtfIcmqNXVMckrmzQ2vTfqtkEZsA
+4rE1IERRyiJQx6EJsz21wJmGV9WJQ5kCQQDwkS0uXqVdFzgHO6S++tjmjYcxwr3g
+H0CoFYSgbddOT6miqRskOQF3DZVkJT3kyuBgU2zKygz52ukQZMqxCb1fAkASvuTv
+qfpH87Qq5kQhNKdbbwbmd2NxlNabazPijWuphGTdW0VfJdWfklyS2Kr+iqrs/5wV
+HhathJt636Eg7oIjAkA8ht3MQ+XSl9yIJIS8gVpbPxSw5OMfw0PjVE7tBdQruiSc
+nvuQES5C9BMHjF39LZiGH1iLQy7FgdHyoP+eodI7
+-----END RSA PRIVATE KEY-----
diff --git a/demos/user_rsa_key b/demos/user_rsa_key
new file mode 100644
index 0000000..ee64f23
--- /dev/null
+++ b/demos/user_rsa_key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDI7iK3d8eWYZlYloat94c5VjtFY7c/0zuGl8C7uMnZ3t6i2G99
+66hEW0nCFSZkOW5F0XKEVj+EUCHvo8koYC6wiohAqWQnEwIoOoh7GSAcB8gP/qaq
++adIl/Rvlby/mHakj+y05LBND6nFWHAn1y1gOFFKUXSJNRZPXSFy47gqzwIBIwKB
+gQCbANjz7q/pCXZLp1Hz6tYHqOvlEmjK1iabB1oqafrMpJ0eibUX/u+FMHq6StR5
+M5413BaDWHokPdEJUnabfWXXR3SMlBUKrck0eAer1O8m78yxu3OEdpRk+znVo4DL
+guMeCdJB/qcF0kEsx+Q8HP42MZU1oCmk3PbfXNFwaHbWuwJBAOQ/ry/hLD7AqB8x
+DmCM82A9E59ICNNlHOhxpJoh6nrNTPCsBAEu/SmqrL8mS6gmbRKUaya5Lx1pkxj2
+s/kWOokCQQDhXCcYXjjWiIfxhl6Rlgkk1vmI0l6785XSJNv4P7pXjGmShXfIzroh
+S8uWK3tL0GELY7+UAKDTUEVjjQdGxYSXAkEA3bo1JzKCwJ3lJZ1ebGuqmADRO6UP
+40xH977aadfN1mEI6cusHmgpISl0nG5YH7BMsvaT+bs1FUH8m+hXDzoqOwJBAK3Z
+X/za+KV/REya2z0b+GzgWhkXUGUa/owrEBdHGriQ47osclkUgPUdNqcLmaDilAF4
+1Z4PHPrI5RJIONAx+JECQQC/fChqjBgFpk6iJ+BOdSexQpgfxH/u/457W10Y43HR
+soS+8btbHqjQkowQ/2NTlUfWvqIlfxs6ZbFsIp/HrhZL
+-----END RSA PRIVATE KEY-----
diff --git a/demos/user_rsa_key.pub b/demos/user_rsa_key.pub
new file mode 100644
index 0000000..ac722f1
--- /dev/null
+++ b/demos/user_rsa_key.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyO4it3fHlmGZWJaGrfeHOVY7RWO3P9M7hpfAu7jJ2d7eothvfeuoRFtJwhUmZDluRdFyhFY/hFAh76PJKGAusIqIQKlkJxMCKDqIexkgHAfID/6mqvmnSJf0b5W8v5h2pI/stOSwTQ+pxVhwJ9ctYDhRSlF0iTUWT10hcuO4Ks8= robey@ralph.lag.net