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; } }
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 ""; }