diff options
Diffstat (limited to 'demos')
-rwxr-xr-x | demos/demo.py | 177 | ||||
-rwxr-xr-x | demos/demo_server.py | 138 | ||||
-rwxr-xr-x | demos/demo_simple.py | 100 | ||||
-rw-r--r-- | demos/interactive.py | 97 |
4 files changed, 512 insertions, 0 deletions
diff --git a/demos/demo.py b/demos/demo.py new file mode 100755 index 00000000..18b5a983 --- /dev/null +++ b/demos/demo.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python + +# Copyright (C) 2003-2005 Robey Pointer <robey@lag.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 distrubuted 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., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + +import base64 +import getpass +import os +import select +import socket +import sys +import threading +import time +import traceback + +import paramiko +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' % paramiko.util.hexify(key.get_fingerprint()), + try: + transport.auth_publickey(username, key) + print '... success!' + return + except SSHException: + print '... nope.' + + +def manual_auth(username, hostname): + default_auth = 'p' + auth = raw_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 = raw_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 = raw_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 = raw_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, e: + print '*** Connect failed: ' + str(e) + traceback.print_exc() + sys.exit(1) + +try: + t = paramiko.Transport(sock) + t.start_client() + if not t.is_active(): + 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 = {} + + key = t.get_remote_server_key() + if not keys.has_key(hostname): + print '*** WARNING: Unknown host key!' + elif not keys[hostname].has_key(key.get_name()): + 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 = raw_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!' + print + interactive.interactive_shell(chan) + chan.close() + t.close() + +except Exception, 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_server.py b/demos/demo_server.py new file mode 100755 index 00000000..599eb46a --- /dev/null +++ b/demos/demo_server.py @@ -0,0 +1,138 @@ +#!/usr/bin/python + +# Copyright (C) 2003-2005 Robey Pointer <robey@lag.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 distrubuted 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., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +import sys, os, socket, threading, traceback, base64 +import paramiko + +# setup logging +paramiko.util.log_to_file('demo_server.log') + +#host_key = paramiko.RSAKey(filename='tests/test_rsa.key') +host_key = paramiko.DSSKey(filename='tests/test_dss.key') + +print 'Read key: ' + paramiko.util.hexify(host_key.get_fingerprint()) + + +class Server (paramiko.ServerInterface): + # 'data' is the output of base64.encodestring(str(key)) + data = 'AAAAB3NzaC1yc2EAAAABIwAAAIEAyO4it3fHlmGZWJaGrfeHOVY7RWO3P9M7hpfAu7jJ2d7eothvfeuoRFtJwhUmZDluRdFyhFY/hFAh76PJKGAusIqIQKlkJxMCKDqIexkgHAfID/6mqvmnSJf0b5W8v5h2pI/stOSwTQ+pxVhwJ9ctYDhRSlF0iTUWT10hcuO4Ks8=' + good_pub_key = paramiko.RSAKey(data=base64.decodestring(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: ' + paramiko.util.hexify(key.get_fingerprint()) + if (username == 'robey') and (key == self.good_pub_key): + return paramiko.AUTH_SUCCESSFUL + return paramiko.AUTH_FAILED + + def get_allowed_auths(self, username): + return '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 + + +# 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, 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, e: + print '*** Listen/accept failed: ' + str(e) + traceback.print_exc() + sys.exit(1) + +print 'Got a connection!' + +try: + event = threading.Event() + t = paramiko.Transport(client) + try: + t.load_server_moduli() + except: + print '(Failed to load moduli -- gex will be unsupported.)' + raise + t.add_server_key(host_key) + server = Server() + t.start_server(event, server) + while 1: + event.wait(0.1) + if not t.is_active(): + print '*** SSH negotiation failed.' + sys.exit(1) + if event.isSet(): + break + # print repr(t) + + # 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.isSet(): + 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, 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_simple.py b/demos/demo_simple.py new file mode 100755 index 00000000..1bebaa13 --- /dev/null +++ b/demos/demo_simple.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +# Copyright (C) 2003-2005 Robey Pointer <robey@lag.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 distrubuted 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., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + +import base64 +import getpass +import os +import socket +import sys +import traceback + +import paramiko +import interactive + + +# setup logging +paramiko.util.log_to_file('demo_simple.log') + +# get hostname +username = '' +if len(sys.argv) > 1: + hostname = sys.argv[1] + if hostname.find('@') >= 0: + username, hostname = hostname.split('@') +else: + hostname = raw_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) + + +# get username +if username == '': + default_username = getpass.getuser() + username = raw_input('Username [%s]: ' % default_username) + if len(username) == 0: + username = default_username +password = getpass.getpass('Password for %s@%s: ' % (username, hostname)) + + +# 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: + 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 host_keys.has_key(hostname): + 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(username=username, password=password, hostkey=hostkey) + chan = t.open_session() + chan.get_pty() + chan.invoke_shell() + print '*** Here we go!' + print + interactive.interactive_shell(chan) + chan.close() + t.close() + +except Exception, e: + print '*** Caught exception: %s: %s' % (e.__class__, e) + traceback.print_exc() + try: + t.close() + except: + pass + sys.exit(1) diff --git a/demos/interactive.py b/demos/interactive.py new file mode 100644 index 00000000..5023cb52 --- /dev/null +++ b/demos/interactive.py @@ -0,0 +1,97 @@ +# Copyright (C) 2003-2005 Robey Pointer <robey@lag.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 distrubuted 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., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + +import socket +import sys + +# 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 = chan.recv(1024) + if len(x) == 0: + print '\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 |