Beispiel #1
0
static void
set_socks_server(const char *socks)
{
	struct url *url;
	enum socks_ver socksv;

	url = url_tokenize(socks);
	if (!url || !url->scheme) {
		log_error("shim: bad socks server, %s", socks);
		exit(1);
	}
	if (url->port < 0)
		url->port = 1080;

	if (!evutil_ascii_strcasecmp(url->scheme, "socks4"))
		socksv = SOCKS_4;
	else if (!evutil_ascii_strcasecmp(url->scheme, "socks4a"))
		socksv = SOCKS_4a;
	else {
		log_error("shim: unknown socks version, %s",
			  url->scheme);
		exit(1);
	}

	if (conn_set_socks_server(url->host, url->port, socksv) < 0)
		exit(1);

	url_free(url);	
}
/** Return true if the list of headers in 'headers', intepreted with respect
 * to flags, means that we should send a "connection: close" when the request
 * is done. */
static int
evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
{
	if (flags & EVHTTP_PROXY_REQUEST) {
		/* proxy connection */
		const char *connection = evhttp_find_header(headers, "Proxy-Connection");
		return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
	} else {
		const char *connection = evhttp_find_header(headers, "Connection");
		return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
	}
}
Beispiel #3
0
static void
start_listening(struct event_base *base, struct evdns_base *dns,
		const char *laddr, const char *lport)
{
	struct evutil_addrinfo hints;
	struct evutil_addrinfo *ai = NULL;
	int ret;

	if (!evutil_ascii_strcasecmp(laddr, "any"))
		laddr = NULL;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	/* turn NULL hostname into INADDR_ANY, and skip looking up any address
	 * types we don't have an interface to connect to. */
	hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;

	ret = evutil_getaddrinfo(laddr, lport, &hints, &ai);
	if (ret < 0) {
		log_error("shim: bad listen address: %s",
			  evutil_gai_strerror(ret));
		exit(1);
        }
	
	if (proxy_init(base, dns, ai->ai_addr, ai->ai_addrlen) < 0)
		exit(1);
}
Beispiel #4
0
static void
fail_server_cb(struct evdns_server_request *req, void *data)
{
	const char *question;
	int *count = data;
	struct in_addr in;

	/* Drop the first N requests that we get. */
	if (*count > 0) {
		--*count;
		tt_want(! evdns_server_request_drop(req));
		return;
	}

	if (req->nquestions != 1)
		TT_DIE(("Only handling one question at a time; got %d",
			req->nquestions));

	question = req->questions[0]->name;

	if (!evutil_ascii_strcasecmp(question, "google.com")) {
		/* Detect a probe, and get out of the loop. */
		event_base_loopexit(exit_base, NULL);
	}

	evutil_inet_pton(AF_INET, "16.32.64.128", &in);
	evdns_server_request_add_a_reply(req, question, 1, &in.s_addr,
	    100);
	tt_assert(! evdns_server_request_respond(req, 0))
	return;
end:
	tt_want(! evdns_server_request_drop(req));
}
Beispiel #5
0
int main(int argc, char **argv)
{
	struct evdns_base *dns;
	struct event_base *base;
	struct bufferevent *bev;
	struct url *socks, *host;
	int s4;

	base = event_base_new();
	dns = evdns_base_new(base, 1);
	
	log_set_file(NULL);
	log_set_min_level(LOG_DEBUG);
	if (argc >= 3) {
		socks = url_tokenize(argv[2]);
		s4 = !evutil_ascii_strcasecmp("socks4", socks->scheme);
		if (conn_set_socks_server(socks->host, socks->port, s4?
				SOCKS_4 : SOCKS_4a) < 0)
			return 0;
	}
	
	host = url_connect_tokenize(argv[1]);

	bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);

	conn_connect_bufferevent(bev, dns, AF_INET, host->host, host->port,
				 do_connect, NULL);

	event_base_dispatch(base);

	return 0;
}
Beispiel #6
0
void
regress_dns_server_cb(struct evdns_server_request *req, void *data)
{
	struct regress_dns_server_table *tab = data;
	const char *question;

	if (req->nquestions != 1)
		TT_DIE(("Only handling one question at a time; got %d",
			req->nquestions));

	question = req->questions[0]->name;

	while (tab->q && evutil_ascii_strcasecmp(question, tab->q) &&
	    strcmp("*", tab->q))
		++tab;
	if (tab->q == NULL)
		TT_DIE(("Unexpected question: '%s'", question));

	++tab->seen;

	if (!strcmp(tab->anstype, "err")) {
		int err = atoi(tab->ans);
		tt_assert(! evdns_server_request_respond(req, err));
		return;
	} else if (!strcmp(tab->anstype, "errsoa")) {
		int err = atoi(tab->ans);
		char soa_record[] =
			"\x04" "dns1" "\x05" "icann" "\x03" "org" "\0"
			"\x0a" "hostmaster" "\x05" "icann" "\x03" "org" "\0"
			"\x77\xde\x5e\xba" /* serial */
			"\x00\x00\x1c\x20" /* refreshtime = 2h */
			"\x00\x00\x0e\x10" /* retry = 1h */
			"\x00\x12\x75\x00" /* expiration = 14d */
			"\x00\x00\x0e\x10" /* min.ttl = 1h */
			;
		evdns_server_request_add_reply(
			req, EVDNS_AUTHORITY_SECTION,
			"example.com", EVDNS_TYPE_SOA, EVDNS_CLASS_INET,
			42, sizeof(soa_record) - 1, 0, soa_record);
		tt_assert(! evdns_server_request_respond(req, err));
		return;
	} else if (!strcmp(tab->anstype, "A")) {
		struct in_addr in;
		evutil_inet_pton(AF_INET, tab->ans, &in);
		evdns_server_request_add_a_reply(req, question, 1, &in.s_addr,
		    100);
	} else if (!strcmp(tab->anstype, "AAAA")) {
		struct in6_addr in6;
		evutil_inet_pton(AF_INET6, tab->ans, &in6);
		evdns_server_request_add_aaaa_reply(req,
		    question, 1, &in6.s6_addr, 100);
	} else {
		TT_DIE(("Weird table entry with type '%s'", tab->anstype));
	}
	tt_assert(! evdns_server_request_respond(req, 0))
	return;
end:
	tt_want(! evdns_server_request_drop(req));
}
Beispiel #7
0
/**
 * @brief guess_type It returns a HTTP type by guessing the file type.
 *
 * @param type Input a file type.
 *
 * @return Const string of type.
 */
static const char * guess_type(const char *type)
{
	const struct table_entry *ent;
	for (ent = &content_type_table[0]; ent->extension; ++ent) {
		if (!evutil_ascii_strcasecmp(ent->extension, type))
			return ent->content_type;
	}
	return "application/misc";
}
Beispiel #8
0
/* Try to guess a good content-type for 'path' */
static const char *guess_content_type(const char *path)
{
    const char *last_period, *extension;
    const struct table_entry *ent;
    last_period = strrchr(path, '.');
    if (!last_period || strchr(last_period, '/'))
        goto not_found; /* no exension */
    extension = last_period + 1;
    for (ent = &content_type_table[0]; ent->extension; ++ent) {
        if (!evutil_ascii_strcasecmp(ent->extension, extension))
            return ent->content_type;
    }

not_found:
    return "application/octet-stream";
}
Beispiel #9
0
static void
process_line(struct bufferevent *bev, void *ctx, char *line)
{
    char **argv;
    int argc = split_args(line, &argv);
    int i;

    for (i = 0; cmdlist[i].cmd; i++)
	if (evutil_ascii_strcasecmp(line, cmdlist[i].cmd) == 0)
	    break;

    (cmdlist[i].func)(bev, ctx, argc - 1, argv + 1);

    free(argv);
    free(line);
}
Beispiel #10
0
void
regress_dns_server_cb(struct evdns_server_request *req, void *data)
{
	struct regress_dns_server_table *tab = data;
	const char *question;

	if (req->nquestions != 1)
		TT_DIE(("Only handling one question at a time; got %d",
			req->nquestions));

	question = req->questions[0]->name;

	while (tab->q && evutil_ascii_strcasecmp(question, tab->q) &&
	    strcmp("*", tab->q))
		++tab;
	if (tab->q == NULL)
		TT_DIE(("Unexpected question: '%s'", question));

	++tab->seen;

	if (!strcmp(tab->anstype, "err")) {
		int err = atoi(tab->ans);
		tt_assert(! evdns_server_request_respond(req, err));
		return;
	} else if (!strcmp(tab->anstype, "A")) {
		struct in_addr in;
		evutil_inet_pton(AF_INET, tab->ans, &in);
		evdns_server_request_add_a_reply(req, question, 1, &in.s_addr,
		    100);
	} else if (!strcmp(tab->anstype, "AAAA")) {
		struct in6_addr in6;
		evutil_inet_pton(AF_INET6, tab->ans, &in6);
		evdns_server_request_add_aaaa_reply(req,
		    question, 1, &in6.s6_addr, 100);
	} else {
		TT_DIE(("Weird table entry with type '%s'", tab->anstype));
	}
	tt_assert(! evdns_server_request_respond(req, 0))
	return;
end:
	tt_want(! evdns_server_request_drop(req));
}
Beispiel #11
0
static
const char*
cd_GuessContentType (const char* path)
{
    const char*          lastPeriod = strrchr(path, '.');
    const char*          extension;
    const CDContentType* type;

    if (lastPeriod == NULL || strchr(lastPeriod, '/')) {
        goto end;
    }

    extension = lastPeriod + 1;
    for (type = CDContentTypes; type->extension; type++) {
        if (!evutil_ascii_strcasecmp(type->extension, extension)) {
            return type->mime;
        }
    }

end: {
        return "application/octet-stream";
    }
}
Beispiel #12
0
/* Try to guess a good content-type for 'path' */
static const char *guess_mime_type(const char *path)
{
    char buf[12] = {0};
    char *pos = NULL;
    const char *last_period, *extension;
    const struct table_entry *ent;
    last_period = strrchr(path, '.');
    if (!last_period || strchr(last_period, '/'))
        goto not_found; /* no exension */
    extension = last_period + 1;
    strncpy(buf, extension, sizeof(buf)-1);
    pos = strpbrk(buf, "?#");
    if (pos)
        *pos = '\0';

    for (ent = &content_type_table[0]; ent->extension; ++ent)
    {
        if (!evutil_ascii_strcasecmp(ent->extension, buf))
            return ent->content_type;
    }

not_found:
    return "application/octet-stream";
}
Beispiel #13
0
	tt_str_op(buf, ==, "-200000000000");
	tt_int_op(r, ==, 13);

	r = evutil_snprintf(buf, sizeof(buf), EV_SIZE_FMT" "EV_SSIZE_FMT,
	    EV_SIZE_ARG(size), EV_SSIZE_ARG(ssize));
	tt_str_op(buf, ==, "8000 -9000");
	tt_int_op(r, ==, 10);

      end:
	;
}

static void
test_evutil_casecmp(void *ptr)
{
	tt_int_op(evutil_ascii_strcasecmp("ABC", "ABC"), ==, 0);
	tt_int_op(evutil_ascii_strcasecmp("ABC", "abc"), ==, 0);
	tt_int_op(evutil_ascii_strcasecmp("ABC", "abcd"), <, 0);
	tt_int_op(evutil_ascii_strcasecmp("ABC", "abb"), >, 0);
	tt_int_op(evutil_ascii_strcasecmp("ABCd", "abc"), >, 0);

	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 100), ==, 0);
	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 4), ==, 0);
	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEXXXX", 4), ==, 0);
	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibE", 4), ==, 0);
	tt_int_op(evutil_ascii_strncasecmp("Libe", "LibEvEnT", 4), ==, 0);
	tt_int_op(evutil_ascii_strncasecmp("Lib", "LibEvEnT", 4), <, 0);
	tt_int_op(evutil_ascii_strncasecmp("abc", "def", 99), <, 0);
	tt_int_op(evutil_ascii_strncasecmp("Z", "qrst", 1), >, 0);
end:
	;
Beispiel #14
0
static int
options_parse_resolver(ProxyContext * const proxy_context,
                       char * const * const headers, const size_t headers_count,
                       char * const * const cols, const size_t cols_count)
{
    const char *dnssec;
    const char *namecoin;
    const char *nologs;
    const char *provider_name;
    const char *provider_publickey_s;
    const char *resolver_ip;
    const char *resolver_name;

    resolver_name = options_get_col(headers, headers_count,
                                    cols, cols_count, "Name");
    if (resolver_name == NULL) {
        logger(proxy_context, LOG_ERR,
               "Invalid resolvers list file: missing 'Name' column");
        exit(1);
    }
    if (*resolver_name == 0) {
        logger(proxy_context, LOG_ERR, "Resolver with an empty name");
        return -1;
    }
    if (evutil_ascii_strcasecmp(resolver_name,
                                proxy_context->resolver_name) != 0) {
        return 0;
    }
    provider_name = options_get_col(headers, headers_count,
                                    cols, cols_count, "Provider name");
    provider_publickey_s = options_get_col(headers, headers_count,
                                           cols, cols_count,
                                           "Provider public key");
    resolver_ip = options_get_col(headers, headers_count,
                                  cols, cols_count, "Resolver address");
    if (provider_name == NULL || *provider_name == 0) {
        logger(proxy_context, LOG_ERR,
               "Resolvers list is missing a provider name for [%s]",
               resolver_name);
        return -1;
    }
    if (provider_publickey_s == NULL || *provider_publickey_s == 0) {
        logger(proxy_context, LOG_ERR,
               "Resolvers list is missing a public key for [%s]",
               resolver_name);
        return -1;
    }
    if (resolver_ip == NULL || *resolver_ip == 0) {
        logger(proxy_context, LOG_ERR,
               "Resolvers list is missing a resolver address for [%s]",
               resolver_name);
        return -1;
    }
    dnssec = options_get_col(headers, headers_count,
                             cols, cols_count, "DNSSEC validation");
    if (dnssec != NULL && evutil_ascii_strcasecmp(dnssec, "yes") != 0) {
        logger(proxy_context, LOG_INFO,
               "- [%s] does not support DNS Security Extensions",
               resolver_name);
    } else {
        logger(proxy_context, LOG_INFO,
               "+ DNS Security Extensions are supported");
    }
    namecoin = options_get_col(headers, headers_count,
                               cols, cols_count, "Namecoin");
    if (namecoin != NULL && evutil_ascii_strcasecmp(namecoin, "yes") == 0) {
        logger(proxy_context, LOG_INFO,
               "+ Namecoin domains can be resolved");
    }
    nologs = options_get_col(headers, headers_count,
                             cols, cols_count, "No logs");
    if (nologs != NULL && evutil_ascii_strcasecmp(nologs, "no") == 0) {
        logger(proxy_context, LOG_WARNING,
               "- [%s] logs your activity - "
               "a different provider might be better a choice if privacy is a concern",
               resolver_name);
    } else {
        logger(proxy_context, LOG_INFO,
               "+ Provider supposedly doesn't keep logs");
    }

    proxy_context->provider_name = strdup(provider_name);
    proxy_context->provider_publickey_s = strdup(provider_publickey_s);
    proxy_context->resolver_ip = strdup(resolver_ip);
    if (proxy_context->provider_name == NULL ||
        proxy_context->provider_publickey_s == NULL ||
        proxy_context->resolver_ip == NULL) {
        logger_noformat(proxy_context, LOG_EMERG, "Out of memory");
        exit(1);
    }
    return 1;
}
Beispiel #15
0
/* Implements a DNS server for the connect_hostname test and the
 * getaddrinfo_async test */
static void
be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data)
{
	int i;
	int *n_got_p=data;
	int added_any=0;
	++*n_got_p;

	for (i=0;i<req->nquestions;++i) {
		const int qtype = req->questions[i]->type;
		const int qclass = req->questions[i]->dns_question_class;
		const char *qname = req->questions[i]->name;
		struct in_addr ans;
		struct in6_addr ans6;
		memset(&ans6, 0, sizeof(ans6));

		if (qtype == EVDNS_TYPE_A &&
		    qclass == EVDNS_CLASS_INET &&
		    !evutil_ascii_strcasecmp(qname, "nobodaddy.example.com")) {
			ans.s_addr = htonl(0x7f000001);
			evdns_server_request_add_a_reply(req, qname,
			    1, &ans.s_addr, 2000);
			added_any = 1;
		} else if (!evutil_ascii_strcasecmp(qname,
			"nosuchplace.example.com")) {
			/* ok, just say notfound. */
		} else if (!evutil_ascii_strcasecmp(qname,
			"both.example.com")) {
			if (qtype == EVDNS_TYPE_A) {
				ans.s_addr = htonl(0x50502020);
				evdns_server_request_add_a_reply(req, qname,
				    1, &ans.s_addr, 2000);
				added_any = 1;
			} else if (qtype == EVDNS_TYPE_AAAA) {
				ans6.s6_addr[0] = 0x80;
				ans6.s6_addr[1] = 0xff;
				ans6.s6_addr[14] = 0xbb;
				ans6.s6_addr[15] = 0xbb;
				evdns_server_request_add_aaaa_reply(req, qname,
				    1, &ans6.s6_addr, 2000);
				added_any = 1;
			}
			evdns_server_request_add_cname_reply(req, qname,
			    "both-canonical.example.com", 1000);
		} else if (!evutil_ascii_strcasecmp(qname,
			"v4only.example.com") ||
		    !evutil_ascii_strcasecmp(qname, "v4assert.example.com")) {
			if (qtype == EVDNS_TYPE_A) {
				ans.s_addr = htonl(0x12345678);
				evdns_server_request_add_a_reply(req, qname,
				    1, &ans.s_addr, 2000);
				added_any = 1;
			} else if (!evutil_ascii_strcasecmp(qname,
				"v4assert.example.com")) {
				TT_FAIL(("Got an AAAA request for v4assert"));
			}
		} else if (!evutil_ascii_strcasecmp(qname,
			"v6only.example.com") ||
		    !evutil_ascii_strcasecmp(qname, "v6assert.example.com")) {
			if (qtype == EVDNS_TYPE_AAAA) {
				ans6.s6_addr[0] = 0x0b;
				ans6.s6_addr[1] = 0x0b;
				ans6.s6_addr[14] = 0xf0;
				ans6.s6_addr[15] = 0x0d;
				evdns_server_request_add_aaaa_reply(req, qname,
				    1, &ans6.s6_addr, 2000);
				added_any = 1;
			}  else if (!evutil_ascii_strcasecmp(qname,
				"v6assert.example.com")) {
				TT_FAIL(("Got a A request for v6assert"));
			}
		} else if (!evutil_ascii_strcasecmp(qname,
			"v6timeout.example.com")) {
			if (qtype == EVDNS_TYPE_A) {
				ans.s_addr = htonl(0xabcdef01);
				evdns_server_request_add_a_reply(req, qname,
				    1, &ans.s_addr, 2000);
				added_any = 1;
			} else if (qtype == EVDNS_TYPE_AAAA) {
				/* Let the v6 request time out.*/
				evdns_server_request_drop(req);
				return;
			}
		} else if (!evutil_ascii_strcasecmp(qname,
			"v4timeout.example.com")) {
			if (qtype == EVDNS_TYPE_AAAA) {
				ans6.s6_addr[0] = 0x0a;
				ans6.s6_addr[1] = 0x0a;
				ans6.s6_addr[14] = 0xff;
				ans6.s6_addr[15] = 0x01;
				evdns_server_request_add_aaaa_reply(req, qname,
				    1, &ans6.s6_addr, 2000);
				added_any = 1;
			} else if (qtype == EVDNS_TYPE_A) {
				/* Let the v4 request time out.*/
				evdns_server_request_drop(req);
				return;
			}
		} else if (!evutil_ascii_strcasecmp(qname,
			"v6timeout-nonexist.example.com")) {
			if (qtype == EVDNS_TYPE_A) {
				/* Fall through, give an nexist. */
			} else if (qtype == EVDNS_TYPE_AAAA) {
				/* Let the v6 request time out.*/
				evdns_server_request_drop(req);
				return;
			}
		} else if (!evutil_ascii_strcasecmp(qname,
			"all-timeout.example.com")) {
			/* drop all requests */
			evdns_server_request_drop(req);
			return;
		} else {
			TT_GRIPE(("Got weird request for %s",qname));
		}
	}
	if (added_any)
		evdns_server_request_respond(req, 0);
	else
		evdns_server_request_respond(req, 3);
}
Beispiel #16
0
static void
dns_server_request_cb(struct evdns_server_request *req, void *data)
{
	int i, r;
	const char TEST_ARPA[] = "11.11.168.192.in-addr.arpa";
	const char TEST_IN6[] =
	    "f.e.f.e." "0.0.0.0." "0.0.0.0." "1.1.1.1."
	    "a.a.a.a." "0.0.0.0." "0.0.0.0." "0.f.f.f.ip6.arpa";

	for (i = 0; i < req->nquestions; ++i) {
		const int qtype = req->questions[i]->type;
		const int qclass = req->questions[i]->dns_question_class;
		const char *qname = req->questions[i]->name;

		struct in_addr ans;
		ans.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
		if (qtype == EVDNS_TYPE_A &&
		    qclass == EVDNS_CLASS_INET &&
		    !evutil_ascii_strcasecmp(qname, "zz.example.com")) {
			r = evdns_server_request_add_a_reply(req, qname,
			    1, &ans.s_addr, 12345);
			if (r<0)
				dns_ok = 0;
		} else if (qtype == EVDNS_TYPE_AAAA &&
		    qclass == EVDNS_CLASS_INET &&
		    !evutil_ascii_strcasecmp(qname, "zz.example.com")) {
			char addr6[17] = "abcdefghijklmnop";
			r = evdns_server_request_add_aaaa_reply(req,
			    qname, 1, addr6, 123);
			if (r<0)
				dns_ok = 0;
		} else if (qtype == EVDNS_TYPE_PTR &&
		    qclass == EVDNS_CLASS_INET &&
		    !evutil_ascii_strcasecmp(qname, TEST_ARPA)) {
			r = evdns_server_request_add_ptr_reply(req, NULL,
			    qname, "ZZ.EXAMPLE.COM", 54321);
			if (r<0)
				dns_ok = 0;
		} else if (qtype == EVDNS_TYPE_PTR &&
		    qclass == EVDNS_CLASS_INET &&
		    !evutil_ascii_strcasecmp(qname, TEST_IN6)){
			r = evdns_server_request_add_ptr_reply(req, NULL,
			    qname,
			    "ZZ-INET6.EXAMPLE.COM", 54322);
			if (r<0)
				dns_ok = 0;
                } else if (qtype == EVDNS_TYPE_A &&
		    qclass == EVDNS_CLASS_INET &&
		    !evutil_ascii_strcasecmp(qname, "drop.example.com")) {
			if (evdns_server_request_drop(req)<0)
				dns_ok = 0;
			return;
		} else {
			printf("Unexpected question %d %d \"%s\" ",
			    qtype, qclass, qname);
			dns_ok = 0;
		}
	}
	r = evdns_server_request_respond(req, 0);
	if (r<0) {
		printf("Couldn't send reply. ");
		dns_ok = 0;
	}
}