Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
1
venv/Lib/site-packages/jupyter_client/ssh/__init__.py
Normal file
1
venv/Lib/site-packages/jupyter_client/ssh/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from jupyter_client.ssh.tunnel import *
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
87
venv/Lib/site-packages/jupyter_client/ssh/forward.py
Normal file
87
venv/Lib/site-packages/jupyter_client/ssh/forward.py
Normal file
|
@ -0,0 +1,87 @@
|
|||
#
|
||||
# This file is adapted from a paramiko demo, and thus licensed under LGPL 2.1.
|
||||
# Original Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
|
||||
# Edits Copyright (C) 2010 The IPython Team
|
||||
#
|
||||
# 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.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02111-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 logging
|
||||
import select
|
||||
import socketserver
|
||||
|
||||
logger = logging.getLogger('ssh')
|
||||
|
||||
|
||||
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:
|
||||
logger.debug('Incoming request to %s:%d failed: %s' % (self.chain_host,
|
||||
self.chain_port,
|
||||
repr(e)))
|
||||
return
|
||||
if chan is None:
|
||||
logger.debug('Incoming request to %s:%d was rejected by the SSH server.' %
|
||||
(self.chain_host, self.chain_port))
|
||||
return
|
||||
|
||||
logger.debug('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)
|
||||
chan.close()
|
||||
self.request.close()
|
||||
logger.debug('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(('127.0.0.1', local_port), SubHander).serve_forever()
|
||||
|
||||
|
||||
__all__ = ['forward_tunnel']
|
372
venv/Lib/site-packages/jupyter_client/ssh/tunnel.py
Normal file
372
venv/Lib/site-packages/jupyter_client/ssh/tunnel.py
Normal file
|
@ -0,0 +1,372 @@
|
|||
"""Basic ssh tunnel utilities, and convenience functions for tunneling
|
||||
zeromq connections.
|
||||
"""
|
||||
|
||||
# Copyright (C) 2010-2011 IPython Development Team
|
||||
# Copyright (C) 2011- PyZMQ Developers
|
||||
#
|
||||
# Redistributed from IPython under the terms of the BSD License.
|
||||
|
||||
import atexit
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
import socket
|
||||
import sys
|
||||
import warnings
|
||||
from getpass import getpass, getuser
|
||||
from multiprocessing import Process
|
||||
|
||||
try:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
import paramiko
|
||||
SSHException = paramiko.ssh_exception.SSHException
|
||||
except ImportError:
|
||||
paramiko = None
|
||||
class SSHException(Exception):
|
||||
pass
|
||||
else:
|
||||
from .forward import forward_tunnel
|
||||
|
||||
try:
|
||||
import pexpect
|
||||
except ImportError:
|
||||
pexpect = None
|
||||
|
||||
from zmq.utils.strtypes import b
|
||||
|
||||
|
||||
def select_random_ports(n):
|
||||
"""Select and return n random ports that are available."""
|
||||
ports = []
|
||||
sockets = []
|
||||
for i in range(n):
|
||||
sock = socket.socket()
|
||||
sock.bind(('', 0))
|
||||
ports.append(sock.getsockname()[1])
|
||||
sockets.append(sock)
|
||||
for sock in sockets:
|
||||
sock.close()
|
||||
return ports
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Check for passwordless login
|
||||
#-----------------------------------------------------------------------------
|
||||
_password_pat = re.compile(b(r'pass(word|phrase):'), re.IGNORECASE)
|
||||
|
||||
|
||||
def try_passwordless_ssh(server, keyfile, paramiko=None):
|
||||
"""Attempt to make an ssh connection without a password.
|
||||
This is mainly used for requiring password input only once
|
||||
when many tunnels may be connected to the same server.
|
||||
|
||||
If paramiko is None, the default for the platform is chosen.
|
||||
"""
|
||||
if paramiko is None:
|
||||
paramiko = sys.platform == 'win32'
|
||||
if not paramiko:
|
||||
f = _try_passwordless_openssh
|
||||
else:
|
||||
f = _try_passwordless_paramiko
|
||||
return f(server, keyfile)
|
||||
|
||||
|
||||
def _try_passwordless_openssh(server, keyfile):
|
||||
"""Try passwordless login with shell ssh command."""
|
||||
if pexpect is None:
|
||||
raise ImportError("pexpect unavailable, use paramiko")
|
||||
cmd = 'ssh -f ' + server
|
||||
if keyfile:
|
||||
cmd += ' -i ' + keyfile
|
||||
cmd += ' exit'
|
||||
|
||||
# pop SSH_ASKPASS from env
|
||||
env = os.environ.copy()
|
||||
env.pop('SSH_ASKPASS', None)
|
||||
|
||||
ssh_newkey = 'Are you sure you want to continue connecting'
|
||||
p = pexpect.spawn(cmd, env=env)
|
||||
while True:
|
||||
try:
|
||||
i = p.expect([ssh_newkey, _password_pat], timeout=.1)
|
||||
if i == 0:
|
||||
raise SSHException('The authenticity of the host can\'t be established.')
|
||||
except pexpect.TIMEOUT:
|
||||
continue
|
||||
except pexpect.EOF:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def _try_passwordless_paramiko(server, keyfile):
|
||||
"""Try passwordless login with paramiko."""
|
||||
if paramiko is None:
|
||||
msg = "Paramiko unavailable, "
|
||||
if sys.platform == 'win32':
|
||||
msg += "Paramiko is required for ssh tunneled connections on Windows."
|
||||
else:
|
||||
msg += "use OpenSSH."
|
||||
raise ImportError(msg)
|
||||
username, server, port = _split_server(server)
|
||||
client = paramiko.SSHClient()
|
||||
client.load_system_host_keys()
|
||||
client.set_missing_host_key_policy(paramiko.WarningPolicy())
|
||||
try:
|
||||
client.connect(server, port, username=username, key_filename=keyfile,
|
||||
look_for_keys=True)
|
||||
except paramiko.AuthenticationException:
|
||||
return False
|
||||
else:
|
||||
client.close()
|
||||
return True
|
||||
|
||||
|
||||
def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
|
||||
"""Connect a socket to an address via an ssh tunnel.
|
||||
|
||||
This is a wrapper for socket.connect(addr), when addr is not accessible
|
||||
from the local machine. It simply creates an ssh tunnel using the remaining args,
|
||||
and calls socket.connect('tcp://localhost:lport') where lport is the randomly
|
||||
selected local port of the tunnel.
|
||||
|
||||
"""
|
||||
new_url, tunnel = open_tunnel(addr, server, keyfile=keyfile, password=password, paramiko=paramiko, timeout=timeout)
|
||||
socket.connect(new_url)
|
||||
return tunnel
|
||||
|
||||
|
||||
def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
|
||||
"""Open a tunneled connection from a 0MQ url.
|
||||
|
||||
For use inside tunnel_connection.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
(url, tunnel) : (str, object)
|
||||
The 0MQ url that has been forwarded, and the tunnel object
|
||||
"""
|
||||
|
||||
lport = select_random_ports(1)[0]
|
||||
transport, addr = addr.split('://')
|
||||
ip, rport = addr.split(':')
|
||||
rport = int(rport)
|
||||
if paramiko is None:
|
||||
paramiko = sys.platform == 'win32'
|
||||
if paramiko:
|
||||
tunnelf = paramiko_tunnel
|
||||
else:
|
||||
tunnelf = openssh_tunnel
|
||||
|
||||
tunnel = tunnelf(lport, rport, server, remoteip=ip, keyfile=keyfile, password=password, timeout=timeout)
|
||||
return 'tcp://127.0.0.1:%i' % lport, tunnel
|
||||
|
||||
|
||||
def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
|
||||
"""Create an ssh tunnel using command-line ssh that connects port lport
|
||||
on this machine to localhost:rport on server. The tunnel
|
||||
will automatically close when not in use, remaining open
|
||||
for a minimum of timeout seconds for an initial connection.
|
||||
|
||||
This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
|
||||
as seen from `server`.
|
||||
|
||||
keyfile and password may be specified, but ssh config is checked for defaults.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
lport : int
|
||||
local port for connecting to the tunnel from this machine.
|
||||
rport : int
|
||||
port on the remote machine to connect to.
|
||||
server : str
|
||||
The ssh server to connect to. The full ssh server string will be parsed.
|
||||
user@server:port
|
||||
remoteip : str [Default: 127.0.0.1]
|
||||
The remote ip, specifying the destination of the tunnel.
|
||||
Default is localhost, which means that the tunnel would redirect
|
||||
localhost:lport on this machine to localhost:rport on the *server*.
|
||||
|
||||
keyfile : str; path to public key file
|
||||
This specifies a key to be used in ssh login, default None.
|
||||
Regular default ssh keys will be used without specifying this argument.
|
||||
password : str;
|
||||
Your ssh password to the ssh server. Note that if this is left None,
|
||||
you will be prompted for it if passwordless key based login is unavailable.
|
||||
timeout : int [default: 60]
|
||||
The time (in seconds) after which no activity will result in the tunnel
|
||||
closing. This prevents orphaned tunnels from running forever.
|
||||
"""
|
||||
if pexpect is None:
|
||||
raise ImportError("pexpect unavailable, use paramiko_tunnel")
|
||||
ssh = "ssh "
|
||||
if keyfile:
|
||||
ssh += "-i " + keyfile
|
||||
|
||||
if ':' in server:
|
||||
server, port = server.split(':')
|
||||
ssh += " -p %s" % port
|
||||
|
||||
cmd = "%s -O check %s" % (ssh, server)
|
||||
(output, exitstatus) = pexpect.run(cmd, withexitstatus=True)
|
||||
if not exitstatus:
|
||||
pid = int(output[output.find(b"(pid=")+5:output.find(b")")])
|
||||
cmd = "%s -O forward -L 127.0.0.1:%i:%s:%i %s" % (
|
||||
ssh, lport, remoteip, rport, server)
|
||||
(output, exitstatus) = pexpect.run(cmd, withexitstatus=True)
|
||||
if not exitstatus:
|
||||
atexit.register(_stop_tunnel, cmd.replace("-O forward", "-O cancel", 1))
|
||||
return pid
|
||||
cmd = "%s -f -S none -L 127.0.0.1:%i:%s:%i %s sleep %i" % (
|
||||
ssh, lport, remoteip, rport, server, timeout)
|
||||
|
||||
# pop SSH_ASKPASS from env
|
||||
env = os.environ.copy()
|
||||
env.pop('SSH_ASKPASS', None)
|
||||
|
||||
ssh_newkey = 'Are you sure you want to continue connecting'
|
||||
tunnel = pexpect.spawn(cmd, env=env)
|
||||
failed = False
|
||||
while True:
|
||||
try:
|
||||
i = tunnel.expect([ssh_newkey, _password_pat], timeout=.1)
|
||||
if i == 0:
|
||||
raise SSHException('The authenticity of the host can\'t be established.')
|
||||
except pexpect.TIMEOUT:
|
||||
continue
|
||||
except pexpect.EOF as e:
|
||||
if tunnel.exitstatus:
|
||||
print(tunnel.exitstatus)
|
||||
print(tunnel.before)
|
||||
print(tunnel.after)
|
||||
raise RuntimeError("tunnel '%s' failed to start" % (cmd)) from e
|
||||
else:
|
||||
return tunnel.pid
|
||||
else:
|
||||
if failed:
|
||||
print("Password rejected, try again")
|
||||
password = None
|
||||
if password is None:
|
||||
password = getpass("%s's password: " % (server))
|
||||
tunnel.sendline(password)
|
||||
failed = True
|
||||
|
||||
|
||||
def _stop_tunnel(cmd):
|
||||
pexpect.run(cmd)
|
||||
|
||||
|
||||
def _split_server(server):
|
||||
if '@' in server:
|
||||
username, server = server.split('@', 1)
|
||||
else:
|
||||
username = getuser()
|
||||
if ':' in server:
|
||||
server, port = server.split(':')
|
||||
port = int(port)
|
||||
else:
|
||||
port = 22
|
||||
return username, server, port
|
||||
|
||||
|
||||
def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
|
||||
"""launch a tunner with paramiko in a subprocess. This should only be used
|
||||
when shell ssh is unavailable (e.g. Windows).
|
||||
|
||||
This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
|
||||
as seen from `server`.
|
||||
|
||||
If you are familiar with ssh tunnels, this creates the tunnel:
|
||||
|
||||
ssh server -L localhost:lport:remoteip:rport
|
||||
|
||||
keyfile and password may be specified, but ssh config is checked for defaults.
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
lport : int
|
||||
local port for connecting to the tunnel from this machine.
|
||||
rport : int
|
||||
port on the remote machine to connect to.
|
||||
server : str
|
||||
The ssh server to connect to. The full ssh server string will be parsed.
|
||||
user@server:port
|
||||
remoteip : str [Default: 127.0.0.1]
|
||||
The remote ip, specifying the destination of the tunnel.
|
||||
Default is localhost, which means that the tunnel would redirect
|
||||
localhost:lport on this machine to localhost:rport on the *server*.
|
||||
|
||||
keyfile : str; path to public key file
|
||||
This specifies a key to be used in ssh login, default None.
|
||||
Regular default ssh keys will be used without specifying this argument.
|
||||
password : str;
|
||||
Your ssh password to the ssh server. Note that if this is left None,
|
||||
you will be prompted for it if passwordless key based login is unavailable.
|
||||
timeout : int [default: 60]
|
||||
The time (in seconds) after which no activity will result in the tunnel
|
||||
closing. This prevents orphaned tunnels from running forever.
|
||||
|
||||
"""
|
||||
if paramiko is None:
|
||||
raise ImportError("Paramiko not available")
|
||||
|
||||
if password is None:
|
||||
if not _try_passwordless_paramiko(server, keyfile):
|
||||
password = getpass("%s's password: " % (server))
|
||||
|
||||
p = Process(target=_paramiko_tunnel,
|
||||
args=(lport, rport, server, remoteip),
|
||||
kwargs=dict(keyfile=keyfile, password=password))
|
||||
p.daemon = True
|
||||
p.start()
|
||||
return p
|
||||
|
||||
|
||||
def _paramiko_tunnel(lport, rport, server, remoteip, keyfile=None, password=None):
|
||||
"""Function for actually starting a paramiko tunnel, to be passed
|
||||
to multiprocessing.Process(target=this), and not called directly.
|
||||
"""
|
||||
username, server, port = _split_server(server)
|
||||
client = paramiko.SSHClient()
|
||||
client.load_system_host_keys()
|
||||
client.set_missing_host_key_policy(paramiko.WarningPolicy())
|
||||
|
||||
try:
|
||||
client.connect(server, port, username=username, key_filename=keyfile,
|
||||
look_for_keys=True, password=password)
|
||||
# except paramiko.AuthenticationException:
|
||||
# if password is None:
|
||||
# password = getpass("%s@%s's password: "%(username, server))
|
||||
# client.connect(server, port, username=username, password=password)
|
||||
# else:
|
||||
# raise
|
||||
except Exception as e:
|
||||
print('*** Failed to connect to %s:%d: %r' % (server, port, e))
|
||||
sys.exit(1)
|
||||
|
||||
# Don't let SIGINT kill the tunnel subprocess
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
|
||||
try:
|
||||
forward_tunnel(lport, remoteip, rport, client.get_transport())
|
||||
except KeyboardInterrupt:
|
||||
print('SIGINT: Port forwarding stopped cleanly')
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print("Port forwarding stopped uncleanly: %s" % e)
|
||||
sys.exit(255)
|
||||
|
||||
|
||||
if sys.platform == 'win32':
|
||||
ssh_tunnel = paramiko_tunnel
|
||||
else:
|
||||
ssh_tunnel = openssh_tunnel
|
||||
|
||||
|
||||
__all__ = ['tunnel_connection', 'ssh_tunnel', 'openssh_tunnel', 'paramiko_tunnel', 'try_passwordless_ssh']
|
Loading…
Add table
Add a link
Reference in a new issue