summaryrefslogtreecommitdiffhomepage
path: root/demos
diff options
context:
space:
mode:
authorRobey Pointer <robey@master-shake.local>2006-01-26 19:13:02 -0800
committerRobey Pointer <robey@master-shake.local>2006-01-26 19:13:02 -0800
commitb955ee02cc0888928163963b57f78ba9ca318627 (patch)
treefe1bd7395e62ed9b682753b59c72a1088a4ee32f /demos
parent77eada9fb4a458d9f8e6b9ebfd6db4de09e1130d (diff)
[project @ robey@master-shake.local-20060127031302-7bb0582ea98a60bd]
move another demo script in, and do a bit more cleanup
Diffstat (limited to 'demos')
-rwxr-xr-xdemos/demo.py5
-rw-r--r--[-rwxr-xr-x]demos/demo_server.py37
-rwxr-xr-xdemos/forward.py219
-rw-r--r--demos/test_rsa.key15
4 files changed, 259 insertions, 17 deletions
diff --git a/demos/demo.py b/demos/demo.py
index 18b5a983..1eb33e82 100755
--- a/demos/demo.py
+++ b/demos/demo.py
@@ -116,8 +116,9 @@ except Exception, e:
try:
t = paramiko.Transport(sock)
- t.start_client()
- if not t.is_active():
+ try:
+ t.start_client()
+ except SSHException:
print '*** SSH negotiation failed.'
sys.exit(1)
diff --git a/demos/demo_server.py b/demos/demo_server.py
index 599eb46a..b1e66c39 100755..100644
--- a/demos/demo_server.py
+++ b/demos/demo_server.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# Copyright (C) 2003-2005 Robey Pointer <robey@lag.net>
#
@@ -18,21 +18,32 @@
# 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 base64
+import os
+import socket
+import sys
+import threading
+import traceback
+
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')
+host_key = paramiko.RSAKey(filename='test_rsa.key')
+#host_key = paramiko.DSSKey(filename='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='
+ # (using the "user_rsa_key" files)
+ data = 'AAAAB3NzaC1yc2EAAAABIwAAAIEAyO4it3fHlmGZWJaGrfeHOVY7RWO3P9M7hp' + \
+ 'fAu7jJ2d7eothvfeuoRFtJwhUmZDluRdFyhFY/hFAh76PJKGAusIqIQKlkJxMC' + \
+ 'KDqIexkgHAfID/6mqvmnSJf0b5W8v5h2pI/stOSwTQ+pxVhwJ9ctYDhRSlF0iT' + \
+ 'UWT10hcuO4Ks8='
good_pub_key = paramiko.RSAKey(data=base64.decodestring(data))
def __init__(self):
@@ -88,7 +99,6 @@ except Exception, e:
print 'Got a connection!'
try:
- event = threading.Event()
t = paramiko.Transport(client)
try:
t.load_server_moduli()
@@ -97,15 +107,11 @@ try:
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)
+ try:
+ t.start_server(server=server)
+ except SSHException, x:
+ print '*** SSH negotiation failed.'
+ sys.exit(1)
# wait for auth
chan = t.accept(20)
@@ -113,6 +119,7 @@ try:
print '*** No channel.'
sys.exit(1)
print 'Authenticated!'
+
server.event.wait(10)
if not server.event.isSet():
print '*** Client never asked for a shell.'
diff --git a/demos/forward.py b/demos/forward.py
new file mode 100755
index 00000000..f91e969e
--- /dev/null
+++ b/demos/forward.py
@@ -0,0 +1,219 @@
+#!/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.
+
+"""
+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 sys
+import os
+import socket
+import select
+import SocketServer
+import getpass
+import base64
+from optparse import OptionParser
+
+import paramiko
+
+DEFAULT_PORT = 4000
+SSH_PORT = 22
+VERBOSE = True
+READPASS = False
+
+
+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, e:
+ verbose('Incoming request to %s:%d failed: %s' % (self.chain_host,
+ self.chain_port,
+ repr(e)))
+ return
+
+ verbose('Connected! Tunnel open.')
+ 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)
+ chan.close()
+ self.request.close()
+ verbose('Tunnel closed.')
+
+
+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 find_default_key_file():
+ filename = os.path.expanduser('~/.ssh/id_rsa')
+ if os.access(filename, os.R_OK):
+ return filename
+ filename = os.path.expanduser('~/ssh/id_rsa')
+ if os.access(filename, os.R_OK):
+ return filename
+ filename = os.path.expanduser('~/.ssh/id_dsa')
+ if os.access(filename, os.R_OK):
+ return filename
+ filename = os.path.expanduser('~/ssh/id_dsa')
+ if os.access(filename, os.R_OK):
+ return filename
+ return ''
+
+def verbose(s):
+ if VERBOSE:
+ print s
+
+
+#####
+
+
+parser = OptionParser(usage='usage: %prog [options] <remote-addr>:<remote-port>',
+ version='%prog 1.0')
+parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=VERBOSE,
+ help='squelch all informational output')
+parser.add_option('-l', '--local-port', action='store', type='int', dest='port',
+ default=DEFAULT_PORT,
+ help='local port to forward (default: %d)' % DEFAULT_PORT)
+parser.add_option('-r', '--host', action='store', type='string', dest='ssh_host',
+ help='SSH host to tunnel through (required)')
+parser.add_option('-p', '--port', action='store', type='int', dest='ssh_port', default=SSH_PORT,
+ help='SSH port to tunnel through (default: %d)' % SSH_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=find_default_key_file(),
+ help='private key file to use for SSH authentication')
+parser.add_option('', '--no-key', action='store_false', dest='use_key', default=True,
+ help='don\'t look for or use a private key file')
+parser.add_option('-P', '--password', action='store_true', dest='readpass', default=READPASS,
+ help='read password (for key or password auth) from stdin')
+options, args = parser.parse_args()
+
+VERBOSE = options.verbose
+READPASS = options.readpass
+
+
+if len(args) != 1:
+ parser.error('Incorrect number of arguments.')
+remote_host = args[0]
+if ':' not in remote_host:
+ parser.error('Remote port missing.')
+remote_host, remote_port = remote_host.split(':', 1)
+try:
+ remote_port = int(remote_port)
+except:
+ parser.error('Remote port must be a number.')
+
+if not options.ssh_host:
+ parser.error('SSH host is required.')
+if ':' in options.ssh_host:
+ options.ssh_host, options.ssh_port = options.ssh_host.split(':', 1)
+ try:
+ options.ssh_port = int(options.ssh_port)
+ except:
+ parser.error('SSH port must be a number.')
+
+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 not host_keys.has_key(options.ssh_host):
+ print '*** Warning: no host key for %s' % options.ssh_host
+ expected_host_key_type = None
+ expected_host_key = None
+else:
+ expected_host_key_type = host_keys[options.ssh_host].keys()[0]
+ expected_host_key = host_keys[options.ssh_host][expected_host_key_type]
+
+key = None
+password = None
+if options.use_key:
+ try:
+ key = paramiko.RSAKey.from_private_key_file(options.keyfile)
+ except paramiko.PasswordRequiredException:
+ if not READPASS:
+ print '*** Password needed for keyfile (use -P): %s' % options.keyfile
+ sys.exit(1)
+ key_password = getpass.getpass('Enter password for key: ')
+ try:
+ key = paramiko.RSAKey.from_private_key_file(options.keyfile, key_password)
+ except:
+ print '*** Unable to read keyfile: %s' % options.keyfile
+ sys.exit(1)
+ except:
+ pass
+
+if key is None:
+ # try reading a password then
+ if not READPASS:
+ print '*** Either a valid private key or password is required (use -K or -P).'
+ sys.exit(1)
+ password = getpass.getpass('Enter password: ')
+
+verbose('Connecting to ssh host %s:%d ...' % (options.ssh_host, options.ssh_port))
+
+transport = paramiko.Transport((options.ssh_host, options.ssh_port))
+transport.connect(hostkeytype=expected_host_key_type,
+ hostkey=expected_host_key,
+ username=options.user,
+ password=password,
+ pkey=key)
+
+verbose('Now forwarding port %d to %s:%d ...' % (options.port, remote_host, remote_port))
+
+try:
+ forward_tunnel(options.port, remote_host, remote_port, transport)
+except KeyboardInterrupt:
+ print 'Port forwarding stopped.'
+ sys.exit(0)
diff --git a/demos/test_rsa.key b/demos/test_rsa.key
new file mode 100644
index 00000000..f50e9c53
--- /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-----