summaryrefslogtreecommitdiff
path: root/demos
diff options
context:
space:
mode:
authorRobey Pointer <robey@master-shake.local>2006-01-26 19:01:14 -0800
committerRobey Pointer <robey@master-shake.local>2006-01-26 19:01:14 -0800
commit0efdc8af5f529a24c9602ae7578e20de1176e55d (patch)
treecd83e66ee5c8932c376b2996b2d5945c640af947 /demos
parent7058195e3848467c3f2635797f675efba4650bef (diff)
downloadparamiko-0efdc8af5f529a24c9602ae7578e20de1176e55d.tar.gz
[project @ robey@master-shake.local-20060127030114-b6810c4c29964a4e]
code from mike looijmans for a windows interactive shell -- while i'm mucking around in here, clean up the demos a bit too
Diffstat (limited to 'demos')
-rwxr-xr-xdemos/demo.py177
-rwxr-xr-xdemos/demo_server.py138
-rwxr-xr-xdemos/demo_simple.py100
-rw-r--r--demos/interactive.py97
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