diff options
author | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2009-09-02 20:29:42 +0000 |
---|---|---|
committer | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2009-09-02 20:29:42 +0000 |
commit | 1588eb9916c0ac8bb02010e91599fe3e78823165 (patch) | |
tree | a90c41a9ad343d3266df5f1f705ea7ef425cc097 | |
parent | 163858a5390a5347c6b84a4a75956a646755cac4 (diff) | |
download | neon-1588eb9916c0ac8bb02010e91599fe3e78823165.tar.gz |
Merge r1713, r1714 from trunk:
* src/ne_request.c (socks_origin_lookup): New function.
(open_connection): Use it to fix support for SOCKSv4 servers.
* test/request.c (socks_v4_proxy): Add test case.
* macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Require inet_pton for
getaddrinfo support.
git-svn-id: http://svn.webdav.org/repos/projects/neon/branches/0.29.x@1715 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
-rw-r--r-- | macros/neon.m4 | 3 | ||||
-rw-r--r-- | src/ne_request.c | 71 | ||||
-rw-r--r-- | test/request.c | 25 |
3 files changed, 86 insertions, 13 deletions
diff --git a/macros/neon.m4 b/macros/neon.m4 index ca9bf12..a673027 100644 --- a/macros/neon.m4 +++ b/macros/neon.m4 @@ -645,7 +645,8 @@ NE_SEARCH_LIBS(getaddrinfo, nsl,, AC_MSG_NOTICE([getaddrinfo support disabled on HP-UX 11.0x/11.1x]) ;; *) ne_enable_gai=yes - NE_CHECK_FUNCS(gai_strerror getnameinfo inet_ntop,,[ne_enable_gai=no; break]) ;; + NE_CHECK_FUNCS(gai_strerror getnameinfo inet_ntop inet_pton,, + [ne_enable_gai=no; break]) ;; esac ]) diff --git a/src/ne_request.c b/src/ne_request.c index 72ce448..6eaacde 100644 --- a/src/ne_request.c +++ b/src/ne_request.c @@ -1122,7 +1122,7 @@ static int read_response_headers(ne_request *req) } /* Perform any necessary DNS lookup for the host given by *info; - * return NE_ code. */ + * returns NE_ code with error string set on error. */ static int lookup_host(ne_session *sess, struct host_info *info) { NE_DEBUG(NE_DBG_HTTP, "Doing DNS lookup on %s...\n", info->hostname); @@ -1514,6 +1514,42 @@ static int do_connect(ne_session *sess, struct host_info *host) return NE_OK; } +/* For a SOCKSv4 proxy only, the IP address of the origin server (in + * addition to the proxy) must be known, and must be an IPv4 address. + * Returns NE_*; connection closed and error string set on error. */ +static int socks_origin_lookup(ne_session *sess) +{ + const ne_inet_addr *ia; + int ret; + + ret = lookup_host(sess, &sess->server); + if (ret) { + /* lookup_host already set the error string. */ + ne_close_connection(sess); + return ret; + } + + /* Find the first IPv4 address available for the server. */ + for (ia = ne_addr_first(sess->server.address); + ia && ne_iaddr_typeof(ia) == ne_iaddr_ipv6; + ia = ne_addr_next(sess->server.address)) { + /* noop */ + } + + /* ... if any */ + if (ia == NULL) { + ne_set_error(sess, _("Could not find IPv4 address of " + "hostname %s for SOCKS v4 proxy"), + sess->server.hostname); + ne_close_connection(sess); + return NE_LOOKUP; + } + + sess->server.current = ia; + + return ret; +} + static int open_connection(ne_session *sess) { int ret; @@ -1545,17 +1581,28 @@ static int open_connection(ne_session *sess) } if (ret == NE_OK && sess->nexthop->proxy == PROXY_SOCKS) { - ret = ne_sock_proxy(sess->socket, sess->socks_ver, NULL, - sess->server.hostname, sess->server.port, - sess->socks_user, sess->socks_password); - if (ret) { - ne_set_error(sess, - _("Could not establish connection from " - "SOCKS proxy (%s:%u): %s"), - sess->nexthop->hostname, - sess->nexthop->port, - ne_sock_error(sess->socket)); - ne_close_connection(sess); + /* Special-case for SOCKS v4 proxies, which require the + * client to resolve the origin server IP address. */ + if (sess->socks_ver == NE_SOCK_SOCKSV4) { + ret = socks_origin_lookup(sess); + } + + if (ret == NE_OK) { + /* Perform the SOCKS handshake, instructing the proxy + * to set up the connection to the origin server. */ + ret = ne_sock_proxy(sess->socket, sess->socks_ver, + sess->server.current, + sess->server.hostname, sess->server.port, + sess->socks_user, sess->socks_password); + if (ret) { + ne_set_error(sess, + _("Could not establish connection from " + "SOCKS proxy (%s:%u): %s"), + sess->nexthop->hostname, + sess->nexthop->port, + ne_sock_error(sess->socket)); + ne_close_connection(sess); + } } } diff --git a/test/request.c b/test/request.c index d95223a..55f9c8d 100644 --- a/test/request.c +++ b/test/request.c @@ -2212,6 +2212,30 @@ static int socks_proxy(void) return await_server(); } +static int socks_v4_proxy(void) +{ + ne_session *sess; + struct socks_server srv = {0}; + + srv.version = NE_SOCK_SOCKSV4; + srv.failure = fail_none; + srv.expect_port = 4242; + srv.expect_addr = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4); + srv.expect_fqdn = "localhost"; + srv.username = "bloggs"; + srv.password = "guessme"; + + CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port, + single_serve_string, EMPTY_RESP)); + + CALL(any_2xx_request(sess, "/blee")); + + ne_iaddr_free(srv.expect_addr); + + ne_session_destroy(sess); + return await_server(); +} + /* TODO: test that ne_set_notifier(, NULL, NULL) DTRT too. */ ne_test tests[] = { @@ -2302,5 +2326,6 @@ ne_test tests[] = { T(dereg_progress), T(addrlist), T(socks_proxy), + T(socks_v4_proxy), T(NULL) }; |