Пример #1
0
static void
follow_arg_filter(const char **opt_argp, follow_info_t *follow_info)
{
  int           len;
  unsigned int  ii;
  char          addr[ADDR_LEN];
  cli_follow_info_t* cli_follow_info = (cli_follow_info_t*)follow_info->gui_data;

  if (sscanf(*opt_argp, ",%u%n", &cli_follow_info->stream_index, &len) == 1 &&
      ((*opt_argp)[len] == 0 || (*opt_argp)[len] == ','))
  {
    *opt_argp += len;
  }
  else
  {
    for (ii = 0; ii < sizeof cli_follow_info->addr/sizeof *cli_follow_info->addr; ii++)
    {
      if ((sscanf(*opt_argp, ADDRv6_FMT, addr, &cli_follow_info->port[ii], &len) != 2 &&
           sscanf(*opt_argp, ADDRv4_FMT, addr, &cli_follow_info->port[ii], &len) != 2) ||
          cli_follow_info->port[ii] <= 0 || cli_follow_info->port[ii] > G_MAXUINT16)
      {
        follow_exit("Invalid address:port pair.");
      }

      if (strcmp("ip6", host_ip_af(addr)) == 0)
      {
        if (!get_host_ipaddr6(addr, (struct e_in6_addr *)cli_follow_info->addrBuf[ii]))
        {
          follow_exit("Can't get IPv6 address");
        }
        set_address(&cli_follow_info->addr[ii], AT_IPv6, 16, cli_follow_info->addrBuf[ii]);
      }
      else
      {
        if (!get_host_ipaddr(addr, (guint32 *)cli_follow_info->addrBuf[ii]))
        {
          follow_exit("Can't get IPv4 address");
        }
        set_address(&cli_follow_info->addr[ii], AT_IPv4, 4, cli_follow_info->addrBuf[ii]);
      }

      *opt_argp += len;
    }

    if (cli_follow_info->addr[0].type != cli_follow_info->addr[1].type)
    {
      follow_exit("Mismatched IP address types.");
    }
    cli_follow_info->stream_index = -1;
  }
}
Пример #2
0
const gchar *get_conn_cfilter(void) {
    static GString *filter_str = NULL;
    gchar *env, **tokens;
    char *lastp, *lastc, *p;
    char *pprotocol = NULL;
    char *phostname = NULL;
    size_t hostlen;
    char *remip, *locip;

    if (filter_str == NULL) {
        filter_str = g_string_new("");
    }
    if ((env = getenv("SSH_CONNECTION")) != NULL) {
        tokens = g_strsplit(env, " ", 4);
        if (tokens[3]) {
            remip = sanitize_filter_ip(tokens[0]);
            locip = sanitize_filter_ip(tokens[2]);
            g_string_printf(filter_str, "not (tcp port %s and %s host %s "
                             "and tcp port %s and %s host %s)", tokens[1], host_ip_af(remip), remip,
                tokens[3], host_ip_af(locip), locip);
            g_free(remip);
            g_free(locip);
            return filter_str->str;
        }
    } else if ((env = getenv("SSH_CLIENT")) != NULL) {
        tokens = g_strsplit(env, " ", 3);
        remip = sanitize_filter_ip(tokens[2]);
        g_string_printf(filter_str, "not (tcp port %s and %s host %s "
            "and tcp port %s)", tokens[1], host_ip_af(remip), tokens[0], remip);
        g_free(remip);
        return filter_str->str;
    } else if ((env = getenv("REMOTEHOST")) != NULL) {
        /* FreeBSD 7.0 sets REMOTEHOST to an empty string */
        if (g_ascii_strcasecmp(env, "localhost") == 0 ||
            strcmp(env, "127.0.0.1") == 0 ||
            strcmp(env, "") == 0) {
            return "";
        }
        remip = sanitize_filter_ip(env);
        g_string_printf(filter_str, "not %s host %s", host_ip_af(remip), remip);
        g_free(remip);
        return filter_str->str;
    } else if ((env = getenv("DISPLAY")) != NULL) {
        /*
         * This mirrors what _X11TransConnectDisplay() does.
         * Note that, on some systems, the hostname can
         * begin with "/", which means that it's a pathname
         * of a UNIX domain socket to connect to.
         *
         * The comments mirror those in _X11TransConnectDisplay(),
         * too. :-)
         *
         * Display names may be of the following format:
         *
         *    [protoco./] [hostname] : [:] displaynumber [.screennumber]
         *
         * A string with exactly two colons separating hostname
         * from the display indicates a DECnet style name.  Colons
         * in the hostname may occur if an IPv6 numeric address
         * is used as the hostname.  An IPv6 numeric address may
         * also end in a double colon, so three colons in a row
         * indicates an IPv6 address ending in :: followed by
         * :display.  To make it easier for people to read, an
         * IPv6 numeric address hostname may be surrounded by []
         * in a similar fashion to the IPv6 numeric address URL
         * syntax defined by IETF RFC 2732.
         *
         * If no hostname and no protocol is specified, the string
         * is interpreted as the most efficient local connection
         * to a server on the same machine.  This is usually:
         *
         *    o shared memory
         *    o local stream
         *    o UNIX domain socket
         *    o TCP to local host.
         */

        p = env;

        /*
         * Step 0, find the protocol.  This is delimited by
         * the optional slash ('/').
         */
        for (lastp = p; *p != '\0' && *p != ':' && *p != '/'; p++)
            ;
        if (*p == '\0')
            return "";    /* must have a colon */

        if (p != lastp && *p != ':') {    /* protocol given? */
            /* Yes */
            pprotocol = p;

            /* Is it TCP? */
            if (p - lastp != 3 || g_ascii_strncasecmp(lastp, "tcp", 3) != 0)
                return "";    /* not TCP */
            p++;            /* skip the '/' */
        } else
            p = env;        /* reset the pointer in
                           case no protocol was given */

        /*
         * Step 1, find the hostname.  This is delimited either by
         * one colon, or two colons in the case of DECnet (DECnet
         * Phase V allows a single colon in the hostname).  (See
         * note above regarding IPv6 numeric addresses with
         * triple colons or [] brackets.)
         */
        lastp = p;
        lastc = NULL;
        for (; *p != '\0'; p++)
            if (*p == ':')
                lastc = p;

        if (lastc == NULL)
            return "";        /* must have a colon */

        if ((lastp != lastc) && (*(lastc - 1) == ':')
            && (((lastc - 1) == lastp) || (*(lastc - 2) != ':'))) {
                /* DECnet display specified */
                return "";
        } else
            hostlen = lastc - lastp;

        if (hostlen == 0)
            return "";    /* no hostname supplied */

        phostname = (char *)g_malloc(hostlen + 1);
        memcpy(phostname, lastp, hostlen);
        phostname[hostlen] = '\0';

        if (pprotocol == NULL) {
            /*
             * No protocol was explicitly specified, so it
             * could be a local connection over a transport
             * that we won't see.
             *
             * Does the host name refer to the local host?
             * If so, the connection would probably be a
             * local connection.
             *
             * XXX - compare against our host name?
             * _X11TransConnectDisplay() does.
             */
            if (g_ascii_strcasecmp(phostname, "localhost") == 0 ||
                strcmp(phostname, "127.0.0.1") == 0) {
                    g_free(phostname);
                return "";
            }

            /*
             * A host name of "unix" (case-sensitive) also
             * causes a local connection.
             */
            if (strcmp(phostname, "unix") == 0) {
                    g_free(phostname);
                return "";
            }

            /*
             * Does the host name begin with "/"?  If so,
             * it's presumed to be the pathname of a
             * UNIX domain socket.
             */
            if (phostname[0] == '/') {
                g_free(phostname);
                return "";
            }
        }

        g_string_printf(filter_str, "not %s host %s",
            host_ip_af(phostname), phostname);
        g_free(phostname);
        return filter_str->str;
#ifdef _WIN32
    } else if (GetSystemMetrics(SM_REMOTESESSION)) {
        /* We have a remote session: http://msdn.microsoft.com/en-us/library/aa380798%28VS.85%29.aspx */
        g_string_printf(filter_str, "not tcp port 3389");
        return filter_str->str;
#endif /* _WIN32 */
    }
    return "";
}