Ejemplo n.º 1
0
    def close_session(self, channel: paramiko.Channel) -> None:
        # pylint: disable=protected-access
        if channel.closed:
            return

        if not channel.eof_received:
            message = Message()
            message.add_byte(cMSG_CHANNEL_EOF)
            message.add_int(channel.remote_chanid)
            channel.transport._send_user_message(message)  # type: ignore

            message = Message()
            message.add_byte(cMSG_CHANNEL_REQUEST)
            message.add_int(channel.remote_chanid)
            message.add_string('*****@*****.**')
            message.add_boolean(False)
            channel.transport._send_user_message(message)  # type: ignore

        message = Message()
        message.add_byte(cMSG_CHANNEL_CLOSE)
        message.add_int(channel.remote_chanid)
        channel.transport._send_user_message(message)  # type: ignore

        channel._unlink()  # type: ignore

        super(SCPBaseForwarder, self).close_session(channel)
        logging.debug("[chan %d] SCP closed", channel.get_id())
Ejemplo n.º 2
0
def shell(channel: paramiko.Channel):
  stdin: paramiko.ChannelFile = channel.makefile_stdin("wb")
  stdout: paramiko.ChannelFile = channel.makefile("r")
  stderr: paramiko.ChannelFile = channel.makefile_stderr("r")
  print("Tip: F12 + I to show connection info, F12+C to close connection")

  stdoutReader = Thread(target=__buffered_reader, name="stdoutReader", args=(stdout, sys.stdout))
  stderrReader = Thread(target=__buffered_reader, name="stderrReader", args=(stderr, sys.stderr))
  stdinWriter = Thread(target=__input_handler, name="stdinWriter", args=(sys.stdin, stdin, channel))
  sizeHandler = Thread(target=__window_size_change_handler, name="TerminalSizeWatchdog", args=(channel,))

  sizeHandler.setDaemon(True)
  stdoutReader.setDaemon(True)
  stderrReader.setDaemon(True)
  stdinWriter.setDaemon(True)

  orig_sigint = signal.getsignal(signal.SIGINT)
  try:
    signal.signal(signal.SIGINT, _sigint)

    sizeHandler.start()
    stderrReader.start()
    stdoutReader.start()
    stdinWriter.start()

    stdoutReader.join()
  finally:
    print("Closing ssh session...")
    try:
      channel.close()
    except:
      pass
    signal.signal(signal.SIGINT, orig_sigint)
Ejemplo n.º 3
0
 def close_session(self, channel: paramiko.Channel) -> None:
     channel.lock.acquire()
     if not channel.closed:
         channel.lock.release()
         channel.close()
     if channel.lock.locked():
         channel.lock.release()
Ejemplo n.º 4
0
def __window_size_change_handler(channel: paramiko.Channel):
  width, height = get_terminal_size()
  while not SIGINT:
    time.sleep(1)
    nwidth, nheight = get_terminal_size()
    if nwidth != width or nheight != height:
      width, height = nwidth, nheight
      channel.resize_pty(width=width, height=height)
Ejemplo n.º 5
0
def read_out(chan: paramiko.Channel, wait_time=1) -> str:
    now = time.time()
    out = ''
    while True:
        while chan.recv_ready():
            data = chan.recv(256).decode('utf-8')
            out = out + data
            sys.stdout.write(data)
        #     and time.time() - now > 3
        while not chan.recv_ready() and time.time() - now > wait_time:
            return out
Ejemplo n.º 6
0
 def send_tree(self, chan: paramiko.Channel, path: str) -> typing.Tuple[list, list]:
     """
     Request a "send tree" request to the client given a channel and path
     :param chan: Channel to send the request for
     :param file_path: Path of the request
     :return: Dirs and files in the tree
     """
     chan.send(self.SEND_TREE)
     logging.debug("TREE:tree request sent")
     size = len(path)
     size = str(size)
     size += '.' * int((64 - len(size)))
     chan.send(str(size))
     logging.debug("TREE:tree size sent")
     chan.send(path)
     logging.debug("TREE:tree path sent")
     logging.debug("TREE:waiting for size")
     size = chan.recv(64)
     logging.debug("TREE:got size")
     size = size.decode('utf-8')
     size = size.replace('.', '')
     logging.debug("TREE:wating for tree")
     raw_tree = chan.recv(int(size))
     logging.debug("TREE:got tree")
     dirs, files = pickle.loads(raw_tree)
     return dirs, files
Ejemplo n.º 7
0
def _f12_commands(channel: paramiko.Channel):
  global F12MENU
  global SIGINT
  _k = _getch()

  if _k == FUNC_KEYS.F12.value:
    F12MENU = not F12MENU
    print(f"\n Character code debugging is: {F12MENU}")
    if F12MENU:
      print("> ", end='', flush=True)
  elif _k == (99,):  # C:
    SIGINT = True
  elif _k == (105,): # I
    t: paramiko.Transport = channel.get_transport()
    sock: socket = t.sock
    localname, peername = sock.getsockname(), sock.getpeername()
    local = localname if localname else ("unknown", 0)
    remote = peername if peername else ("unknown", 0)
    print(f"""
Connection: {t.local_version} -> {t.remote_version} ({'active' if t.active == 1 else 'inactive'}, auth: {t.authenticated})
Local endpoint: {local[0]}:{local[1]}, host key type = {t.host_key_type}
Repote Endpoint: {remote[0]}:{remote[1]}, chipher type = {t.remote_cipher}, mac = {t.remote_mac}

Preffered:
   Ciphers: {','.join(t.preferred_ciphers)}
   Keys: {','.join(t.preferred_keys)}
   Macs: {','.join(t.preferred_macs)}
""")
  else:
    return chr(7)
Ejemplo n.º 8
0
 def do_makefile(*args):
     if ch.channel_file is None:
         ch.channel_file = Channel.makefile(ch, *args)
         _override_file_close(ch.channel_file)
         return ch.channel_file
     else:
         raise FileExistsError('We allow only one file per channel')
Ejemplo n.º 9
0
 def handler(self, channel: paramiko.Channel, origin: Optional[Tuple[str,
                                                                     int]],
             destination: Optional[Tuple[str, int]]) -> None:
     try:
         logging.debug(
             "Opening forwarded-tcpip channel (%s -> %s) to client", origin,
             destination)
         f = TunnelForwarder(
             self.session.transport.open_channel("forwarded-tcpip",
                                                 destination, origin),
             channel)
         self.server_interface.forwarders.append(f)
     except paramiko.ssh_exception.ChannelException:
         channel.close()
         logging.error("Could not setup forward from %s to %s.", origin,
                       destination)
Ejemplo n.º 10
0
def _override_channel_close(ch: Channel):
    ch.channel_file = None
    ch.close_pending = False

    def do_close():
        if ch.channel_file is not None and not ch.channel_file.closed:
            ch.close_pending = True
            return
        else:
            try:
                return Channel.close(ch)
            except EOFError as e:
                # Some problems while closing yield an EOFError, which is not
                # descriptive
                raise ConnectionError('Closing channel') from e

    ch.close = do_close
Ejemplo n.º 11
0
def select_group_or_not(chan: paramiko.Channel, config: dict):
    out_info = read_out(chan, wait_time=3)
    if "elect group" not in out_info:
        return
    idx = '0'
    group_list = out_info.split("\r\n")
    for ip_addr in group_list:
        if config.get("select_ip") in ip_addr:
            idx = ip_addr[1:ip_addr.index(":")].strip()
            print("select " + idx)
            break
    if idx == '0':
        print("ip 未找到")
        return False
    chan.send(idx + '\n')
    read_out(chan, wait_time=3)
    return True
Ejemplo n.º 12
0
Archivo: main.py Proyecto: hyzyla/dhavn
def right_forwarder(channel: Channel, local_port: int):
    selector = selectors.DefaultSelector()

    def from_localhost():
        data = sock.recv(1024)
        if len(data) == 0:
            return data
        channel.send(data)
        return data

    def to_localhost():
        data = sock.recv(1024)
        if len(data) == 0:
            return data
        channel.send(data)
        return data


    selector.register(socket, selectors.EVENT_READ, from_localhost)
    selector.register(channel, selectors.EVENT_READ, to_localhost)

    # connect to localhost via sockets
    sock = socket.socket()
    try:
        sock.connect((LOCALHOST, local_port))
    except Exception as e:
        logger.error(f'Forwarding request to {local_port} failed: e')
        return

    # read data from channel or socket and send to opposite site
    while True:
        r, _, _ = select.select([sock, channel], [], [])
        if sock in r:
            data = sock.recv(1024)
            if len(data) == 0:
                break
            channel.send(data)
        if channel in r:
            data = channel.recv(1024)
            if len(data) == 0:
                break
            sock.send(data)
    channel.close()
    sock.close()
    logger.info(f'Tunnel closed from {channel.origin_addr}')
Ejemplo n.º 13
0
def _override_makefile(ch: Channel):
    # makefile for channels should work the same way as for sockets, but that's
    # not the case. In particular, if you close the channel the file remains
    # unusable, which is bad.
    # When doing makefile on a channel, we store a pointer to the file, so that
    # when trying to close the channel we can check if the file is still open
    # and leave the closure pending. We override the close method in the file
    # as to execute the pending closure if needed.
    ch.channel_file = None

    def do_makefile(*args):
        if ch.channel_file is None:
            ch.channel_file = Channel.makefile(ch, *args)
            _override_file_close(ch.channel_file)
            return ch.channel_file
        else:
            raise FileExistsError('We allow only one file per channel')

    ch.makefile = do_makefile
Ejemplo n.º 14
0
    def __get_data_from_channel(self, channel: paramiko.Channel,
                                stream_name: str,
                                timeout: float) -> Tuple[bool, str]:
        """Reads text from standard output or standard error."""
        if stream_name == 'stdout':
            receive = paramiko.Channel.recv
        else:
            receive = paramiko.Channel.recv_stderr

        channel.settimeout(timeout)

        data = bytearray()
        try:
            new_data = receive(channel, 1024 * 1024)
            while len(new_data) > 0:
                data.extend(new_data)
                new_data = receive(channel, 1024 * 1024)
        except socket.timeout:
            return False, data.decode('utf-8')

        return True, data.decode('utf-8')
Ejemplo n.º 15
0
 def _handle_client(self, channel: paramiko.Channel) -> None:
     try:
         command = self.command_queues[channel.chanid].get(block=True)
         _logger.debug(f"Channel {channel.chanid}, executing {command}")
         command_result = self._command_handler(command.decode())
         channel.sendall(command_result.stdout)
         channel.sendall_stderr(command_result.stderr)
         channel.send_exit_status(command_result.returncode)
     except Exception:  # pylint: disable=broad-except
         _logger.exception(f"Error handling client (channel: {channel})")
     finally:
         try:
             channel.close()
         except EOFError:
             _logger.debug("Tried to close already closed channel")
Ejemplo n.º 16
0
 def sendall(self, channel: paramiko.Channel, data: bytes,
             sendfunc: Callable[[bytes], int]) -> int:
     if not data:
         return 0
     if channel.exit_status_ready():
         return 0
     sent = 0
     newsent = 0
     while sent != len(data):
         newsent = sendfunc(data[sent:])
         if newsent == 0:
             return 0
         sent += newsent
     return sent
Ejemplo n.º 17
0
    def _initiate_channel(self, channel: paramiko.Channel, email: str):
        """
        Initiates channel with given channel object and email
        :param channel: SSH Channel object
        :param email: user's email
        """
        data = channel.recv(5)
        data = data.decode("utf-8")
        logging.debug("Data recived: {data}".format(data=data))

        if data == self.READY:
            size = channel.recv(64)
            size = size.decode('utf-8')
            size = size.replace('.', '')
            name = channel.recv(int(size))
            setattr(channel,"anylink_name",name.decode('utf-8'))
            channel.send(self.CONFIRM_READY)
            self.channels[channel] = email
        else:
            channel.close()
Ejemplo n.º 18
0
    def send_file(self, chan: paramiko.Channel, file_path: str) -> bool:
        """
        Request a "send file" request to the client given a channel and file path
        :param chan: Channel to send the request for
        :param file_path: Path of the file of the request
        :return: File transfer succeeded/faild - True/False
        """
        chan.send(self.SEND_FILE)
        size = str(len(file_path))
        size += '.' * int((64 - len(size)))
        chan.send(str(size))
        chan.send(file_path)
        size = chan.recv(64)
        size = size.decode('utf-8')
        size = size.replace('.', '')
        msg = chan.recv(int(size))
        msg = msg.decode('utf-8')
        logging.debug("Message recived: {msg}".format(msg=msg))
        if msg == "finishfile":
            return True

        return False
Ejemplo n.º 19
0
def make_interactive(
    channel: paramiko.Channel
) -> typing.Tuple[int, typing.BinaryIO, typing.BinaryIO]:
    """
    Manages an interactive command
    Takes in a paramiko.Channel shared by stdin, stdout, stderr of a currently running command
    The current interpreter stdin is duplicated and written to the command's stdin
    The command's stdout and stderr are written to the interpreter's stdout and stderr
    and also buffered in a ByteStream for later reading
    Returns (exit status, Stdout buffer, Stderr bufer)
    """
    infd = sys.stdin.fileno()
    channelfd = channel.fileno()
    poll = select.poll()
    poll.register(
        infd, select.POLLIN + select.POLLPRI + select.POLLERR + select.POLLHUP)
    poll.register(
        channelfd,
        select.POLLIN + select.POLLPRI + select.POLLERR + select.POLLHUP)
    stdout = io.BytesIO()
    stderr = io.BytesIO()
    while not channel.exit_status_ready():
        for fd, event in poll.poll(0.5):
            if fd == infd and event & (select.POLLIN + select.POLLPRI):
                # Text available on python stdin
                channel.send(os.read(infd, 4096))
        if channel.recv_ready():
            content = channel.recv(4096)
            sys.stdout.write(content.decode())
            sys.stdout.flush()
            stdout.write(content)
        if channel.recv_stderr_ready():
            content = channel.recv_stderr(4096)
            sys.stderr.write(content.decode())
            sys.stderr.flush()
            stderr.write(content)
    if channel.recv_ready():
        content = channel.recv(4096)
        sys.stdout.write(content.decode())
        sys.stdout.flush()
        stdout.write(content)
    if channel.recv_stderr_ready():
        content = channel.recv_stderr(4096)
        sys.stderr.write(content.decode())
        sys.stderr.flush()
        stderr.write(content)
    stdout.seek(0, 0)
    stderr.seek(0, 0)
    return channel.recv_exit_status(), stdout, stderr
Ejemplo n.º 20
0
def exec_command(chan: paramiko.Channel, commands: list):
    for cmd in commands:
        chan.send(cmd + '\n')
        read_out(chan, wait_time=2)
Ejemplo n.º 21
0
 def __init__(self, chan: Channel):
     self.chan = chan
     # need that U. no universal new line = pressing enter might not stop sending data..
     self.chanfile = chan.makefile('rU')
Ejemplo n.º 22
0
 def check_channel_exec_request(self, channel: paramiko.Channel,
                                command: bytes) -> bool:
     self.command_queues.setdefault(channel.get_id(), Queue()).put(command)
     return True
Ejemplo n.º 23
0
 def test_can_override_mode_and_bufsize(self, setmode):
     self.klass(Channel(None), mode="w", bufsize=25)
     setmode.assert_called_once_with("w", 25)
Ejemplo n.º 24
0
 def test_defaults_to_unbuffered_reading(self, setmode):
     self.klass(Channel(None))
     setmode.assert_called_once_with("r", -1)
Ejemplo n.º 25
0
 def close_channel(self, channel: Channel):
     channel.close()
Ejemplo n.º 26
0
 def wait_until_end(self, channel: Channel):
     status = channel.recv_exit_status()
     return status