示例#1
0
def need_tunnel(server):
    """
    Reports whether a tunnel is needed to connect to the server.

    This needs to be able to handle fully qualified host names and IP addresses

    @param server : fully qualified server name or IP address
    """
    output = search_response(['ip', 'route', 'show'], ['grep', 'default'])
    gateway = output[0].strip().split()[2]
    # This will fail if the gateway is ever not a single digit.
    local_domain = get_domain(gateway[:-2])

    parts = server.split('.')
    if parts[-1].isalpha():
        if re.search("fltops", server):
            remote_domain = "fltops"
        elif re.search("jpl", server):
            remote_domain = "jpl"
        else:
            remote_domain = "other"
    elif parts[0].isdigit():
        remote_domain = get_domain('.'.join(parts[:-1]))

    module_logger.debug("need_tunnel: local domain is %s, remote domain is %s",
                        local_domain, remote_domain)
    if remote_domain == "fltops" and local_domain != "fltops":
        need = True
    elif remote_domain == "jpl" and local_domain == "other":
        need = True
    else:
        need = False
    return need
示例#2
0
    def _get_child(self):
        """
        Gets the PID of the process sustaining the tunnel

        @return: int
        """
        output = search_response(["ps", "-ef"], ["grep", "xterm"])
        # p1 = Popen(["ps", "-ef"], stdout=PIPE)
        # p2 = Popen(["grep", "xterm"],  stdin=p1.stdout, stdout=PIPE)
        # waiting = True
        # while waiting:
        #  try:
        #    output = p2.stdout.read()
        #    waiting = False
        #  except IOError:
        #    # probably an interrupted system call.  Try again
        #    continue
        module_logger.debug("_get_child: search_response gave\n%s", output)
        parts = output[0].split()
        pid = parts[1]
        user = parts[0]
        if pid.isdigit():
            return int(pid)
        else:
            return None
示例#3
0
def free_socket():
    """
    Return a free socket
    """
    found = 1
    while found:
        trial = random.randrange(1024, 65535)
        found = search_response(['netstat', '-vatn'], ['grep', str(trial)])
    return trial
示例#4
0
    def do_mount(self, tunnel, remoteMP="/"):
        """
        mount ssh source as local filesystem by calling sshfs

        Example:
        do_mount(mytunnel, "/home/me")

        @param tunnel : ssh tunnel to a remote host
        @type  tunnel : Tunnel() instance

        @return: True on success
        """
        self.user = tunnel.user
        self.port = tunnel.port
        self.path = remoteMP
        self.mp = self._get_possible_mountpoint()
        if not os.path.exists(self.mp):
            self.logger.debug(
                "do_mount: Creating mountpoint *s", str(self.mp))
            os.mkdir(self.mp)
        sshfs = "%s@localhost:%s" % (self.user, self.path)
        # already mounted?
        response = search_response(['mount'], ['grep', sshfs])
        if response:
            self.logger.debug(
                "do_mount: already mounted:\n%s", str(response))
            self.mp = response[0].strip().split()[2]
            self.mountpoint = os.path.basename(self.mp)
            self.mountroot = os.path.dirname(self.mp)
            status = 0
        else:
            command = 'sshfs -p %d -o uid=%d -o cache=no "%s" "%s"' % (self.port,
                                                                       self.uid,
                                                                       sshfs,
                                                                       self.mp)
            self.logger.debug("do_mount: login: %s", sshfs)
            self.logger.debug("do_mount: mount command:\n%s", command)
            status = os.system(command)
        if status == 0:
            self.logger.debug("do_mount: %s: %s mounted as %s in %s",
                              self.host, self.path, self.mountpoint,
                              self.mountroot)
            return True
        else:
            self.logger.warning("do_mount: Mount failed")
            try:
                os.rmdir(self.mp)
            except OSError as details:
                self.logger.error("do_mount: could not remove %s", self.mp,
                                  exc_info=True)
            return False
示例#5
0
    def get_user(self):
        """
        Get the owner of the tunnel

        @return: owner
        """
        self.user = '******'
        output = search_response(["ps", "-ef"], ["grep", str(self.pid)])
        for line in output:
            parts = line.strip().split()
            if int(parts[1]) == self.pid:
                self.user = parts[0]
                break
        return self.user
示例#6
0
def arbitrary_tunnel(remote_ip,
                     relay_ip,
                     local_port,
                     remote_port,
                     port=22,
                     username='',
                     reverse=False):
    """
    Create an arbitrary ssh tunnel, after checking to see if a tunnel already exists.
    This just spawns the process that creates the tunnel, it doesn't check to see if the tunnel
    has successfully connected.

    Executes the following command:
    ```
    ssh  -p {port} -l {username} -L {local_port}:{relay_ip}:{remote_port} {remote_ip}
    ```
    Args:
        remote_ip (str): The remote, or target ip address.
            For local port forwarding this can be localhost
        relay_ip (str): The relay ip address.
        local_port (int): The local port on which we listen
        remote_port (int): The remote port on which we listen
    Keyword Args:
        port (int): The -p argument for ssh
        username (str): The username to use for tunneling
    Returns:
        subprocess.Popen: if there isn't an existing process corresponding to tunnel:
            or else BasicProcess instance, the corresponds to already running tunnel command.

    """
    #-c arcfour -o ServerAliveInterval=60 -o TCPKeepAlive=no
    # First thing is check to see if the remote_ip is ~/.ssh/config
    home_dir = os.path.expanduser("~")
    ssh_config = os.path.join(home_dir, ".ssh/config")
    with open(ssh_config, 'r') as config:
        contents = config.read()

    pattern = "host (.*)\n"
    hosts = [match for match in re.findall(pattern, contents)]

    r_option = "-L"
    if reverse:
        r_option = "-R"

    if remote_ip in hosts:
        command = "ssh -N {0} {1}:{2}:{3} {4}"
        command = command.format(r_option, local_port, relay_ip, remote_port,
                                 remote_ip)
    else:
        command = "ssh -N -l {0} -p {1} {2} {3}:{4}:{5} {6}"
        command = command.format(username, port, r_option, local_port,
                                 relay_ip, remote_port, remote_ip)

    command_relay = "{0} {1}:{2}:{3} {4}".format(r_option, local_port,
                                                 relay_ip, remote_port,
                                                 remote_ip)
    # module_logger.debug(command_relay)
    ssh_proc = search_response(['ps', 'x'], ['grep', 'ssh'])
    # re_pid = re.compile("\d+")
    # re_name = re.compile("ssh.*")
    for proc in ssh_proc:
        if command_relay in proc:
            module_logger.debug("Found matching process: {}".format(proc))
            # proc_id = int(re_pid.findall(proc)[0])
            # proc_name = re_name.findall(proc)[0]
            return BasicProcess(ps_line=proc, command_name='ssh')
            # return BasicProcess(name=proc_name, pid=proc_id)

    module_logger.debug("Invoking command {}".format(command))
    p = invoke(command)
    return p