diff -purb httptunnel-3.3-orig/AUTHORS httptunnel-3.3-work/AUTHORS --- httptunnel-3.3-orig/AUTHORS Sun Feb 25 12:59:04 2001 +++ httptunnel-3.3-work/AUTHORS Tue Jul 27 12:42:41 2004 @@ -21,6 +21,7 @@ Patches: Tomas Berndtsson Brian Somers Sampo Niskanen + Florian Forster Testing: Philip Craig FAQ: Lars Brinkhoff Christian Brideau diff -purb httptunnel-3.3-orig/htc.c httptunnel-3.3-work/htc.c --- httptunnel-3.3-orig/htc.c Sun Feb 25 12:46:49 2001 +++ httptunnel-3.3-work/htc.c Tue Jul 27 12:46:32 2004 @@ -40,6 +40,8 @@ typedef struct int max_connection_age; char *proxy_authorization; char *user_agent; + char *peer_host; + int peer_port; } Arguments; #define NO_PROXY_BUFFER 0 @@ -85,6 +87,8 @@ usage (FILE *f, const char *me) " -U, --user-agent STRING specify User-Agent value in HTTP requests\n" " -V, --version output version information and exit\n" " -w, --no-daemon don't fork into the background\n" +" -p, --peer HOSTNAME:PORT tell the server to connect to this Host/Port\n" +" (Must be enabled by the server)\n" "\n" "Report bugs to %s.\n", me, DEFAULT_HOST_PORT, DEFAULT_KEEP_ALIVE, @@ -131,6 +135,8 @@ parse_arguments (int argc, char **argv, arg->max_connection_age = DEFAULT_CONNECTION_MAX_TIME; arg->proxy_authorization = NULL; arg->user_agent = NULL; + arg->peer_host = NULL; + arg->peer_port = 0; for (;;) { @@ -157,10 +163,11 @@ parse_arguments (int argc, char **argv, { "proxy-authorization", required_argument, 0, 'A' }, { "max-connection-age", required_argument, 0, 'M' }, { "proxy-authorization-file", required_argument, 0, 'z' }, + { "peer", required_argument, 0, 'p' }, { 0, 0, 0, 0 } }; - static const char *short_options = "A:B:c:d:F:hk:M:P:sST:U:Vwz:" + static const char *short_options = "A:B:c:d:F:hk:M:p:P:sST:U:Vwz:" #ifdef DEBUG_MODE "D:l:" #endif @@ -231,6 +238,12 @@ parse_arguments (int argc, char **argv, usage (stdout, arg->me); exit (0); + case 'p': + name_and_port (optarg, &arg->peer_host, &arg->peer_port); + if (arg->peer_port == -1) + arg->peer_port = 0; + break; + case 'P': name_and_port (optarg, &arg->proxy_name, &arg->proxy_port); if (arg->proxy_port == -1) @@ -435,6 +448,8 @@ main (int argc, char **argv) arg.proxy_authorization ? arg.proxy_authorization : "(null)"); log_notice (" user_agent = %s", arg.user_agent ? arg.user_agent : "(null)"); log_notice (" debug_level = %d", debug_level); + log_notice (" peer_host = %s", arg.peer_host ? arg.peer_host : "(null)"); + log_notice (" peer_port = %d", arg.peer_port); if (arg.forward_port != -1) @@ -518,6 +533,7 @@ main (int argc, char **argv) log_debug ("creating a new tunnel"); tunnel = tunnel_new_client (arg.host_name, arg.host_port, arg.proxy_name, arg.proxy_port, + arg.peer_host, arg.peer_port, arg.content_length); if (tunnel == NULL) { diff -purb httptunnel-3.3-orig/hts.c httptunnel-3.3-work/hts.c --- httptunnel-3.3-orig/hts.c Sun Feb 25 12:56:37 2001 +++ httptunnel-3.3-work/hts.c Tue Jul 27 12:50:46 2004 @@ -31,6 +31,7 @@ typedef struct int strict_content_length; int keep_alive; int max_connection_age; + int remote_dest; } Arguments; int debug_level = 0; @@ -67,6 +68,8 @@ usage (FILE *f, const char *me) " -V, --version output version information and exit\n" " -w, --no-daemon don't fork into the background\n" " -p, --pid-file LOCATION write a PID file to LOCATION\n" +" -r, --remote-destination Allow remote (= client) side to set\n" +" forward-destination\n" "\n" "Report bugs to %s.\n", me, DEFAULT_HOST_PORT, DEFAULT_KEEP_ALIVE, @@ -93,6 +96,7 @@ parse_arguments (int argc, char **argv, arg->strict_content_length = FALSE; arg->keep_alive = DEFAULT_KEEP_ALIVE; arg->max_connection_age = DEFAULT_CONNECTION_MAX_TIME; + arg->remote_dest = 0; for (;;) { @@ -114,10 +118,11 @@ parse_arguments (int argc, char **argv, { "forward-port", required_argument, 0, 'F' }, { "content-length", required_argument, 0, 'c' }, { "max-connection-age", required_argument, 0, 'M' }, + { "remote-destination", no_argument, 0, 'r' }, { 0, 0, 0, 0 } }; - static const char *short_options = "c:d:F:hk:M:p:sSVw" + static const char *short_options = "c:d:F:hk:M:p:rsSVw" #ifdef DEBUG_MODE "D:l:" #endif @@ -200,6 +205,10 @@ parse_arguments (int argc, char **argv, printf ("hts (%s) %s\n", PACKAGE, VERSION); exit (0); + case 'r': + arg->remote_dest++; + break; + case 'p': arg->pid_filename = optarg; break; @@ -307,6 +316,7 @@ main (int argc, char **argv) log_notice (" debug_level = %d", debug_level); log_notice (" pid_filename = %s", arg.pid_filename ? arg.pid_filename : "(null)"); + log_notice (" remote_dest = %d", arg.remote_dest); tunnel = tunnel_new_server (arg.host, arg.port, arg.content_length); if (tunnel == NULL) @@ -400,17 +410,25 @@ main (int argc, char **argv) if (arg.forward_port != -1) { struct sockaddr_in addr; + char *host; + int port; + + if ((arg.remote_dest == 0) || (tunnel_get_peer_address (&host, &port, tunnel) == 0)) + { + host = arg.forward_host; + port = arg.forward_port; + } - if (set_address (&addr, arg.forward_host, arg.forward_port) == -1) + if (set_address (&addr, host, port) == -1) { log_error ("couldn't forward port to %s:%d: %s\n", - arg.forward_host, arg.forward_port, strerror (errno)); + host, port, strerror (errno)); log_exit (1); } fd = do_connect (&addr); log_debug ("do_connect (\"%s:%d\") = %d", - arg.forward_host, arg.forward_port, fd); + host, port, fd); if (fd == -1) { log_error ("couldn't connect to %s:%d: %s\n", diff -purb httptunnel-3.3-orig/http.c httptunnel-3.3-work/http.c --- httptunnel-3.3-orig/http.c Tue Jul 11 13:37:48 2000 +++ httptunnel-3.3-work/http.c Tue Jul 27 12:56:54 2004 @@ -16,6 +16,7 @@ over multiple lines. static inline ssize_t http_method (int fd, Http_destination *dest, + const char *peer_host, int peer_port, Http_method method, ssize_t length) { char str[1024]; /* FIXME: possible buffer overflow */ @@ -31,6 +32,10 @@ http_method (int fd, Http_destination *d n = 0; if (dest->proxy_name != NULL) n = sprintf (str, "http://%s:%d", dest->host_name, dest->host_port); + + if (peer_host != NULL) + sprintf (str + n, "/%s/%i/tunnel.cgi?time=%ld", peer_host, peer_port, time (NULL)); + else sprintf (str + n, "/index.html?crap=%ld", time (NULL)); request = http_create_request (method, str, 1, 1); @@ -68,21 +73,24 @@ http_method (int fd, Http_destination *d } ssize_t -http_get (int fd, Http_destination *dest) +http_get (int fd, Http_destination *dest, + const char *peer_host, int peer_port) { - return http_method (fd, dest, HTTP_GET, -1); + return http_method (fd, dest, peer_host, peer_port, HTTP_GET, -1); } ssize_t -http_put (int fd, Http_destination *dest, size_t length) +http_put (int fd, Http_destination *dest, + const char *peer_host, int peer_port, size_t length) { - return http_method (fd, dest, HTTP_PUT, (ssize_t)length); + return http_method (fd, dest, peer_host, peer_port, HTTP_PUT, (ssize_t)length); } ssize_t -http_post (int fd, Http_destination *dest, size_t length) +http_post (int fd, Http_destination *dest, + const char *peer_host, int peer_port, size_t length) { - return http_method (fd, dest, HTTP_POST, (ssize_t)length); + return http_method (fd, dest, peer_host, peer_port, HTTP_POST, (ssize_t)length); } int diff -purb httptunnel-3.3-orig/http.h httptunnel-3.3-work/http.h --- httptunnel-3.3-orig/http.h Tue May 18 21:12:47 1999 +++ httptunnel-3.3-work/http.h Tue Jul 27 09:48:05 2004 @@ -55,10 +55,13 @@ typedef struct const char *user_agent; } Http_destination; -extern ssize_t http_get (int fd, Http_destination *dest); +extern ssize_t http_get (int fd, Http_destination *dest, + const char *peer_host, int peer_port); extern ssize_t http_put (int fd, Http_destination *dest, + const char *peer_host, int peer_port, size_t content_length); extern ssize_t http_post (int fd, Http_destination *dest, + const char *peer_host, int peer_port, size_t content_length); extern int http_error_to_errno (int err); diff -purb httptunnel-3.3-orig/tunnel.c httptunnel-3.3-work/tunnel.c --- httptunnel-3.3-orig/tunnel.c Fri Sep 1 10:46:10 2000 +++ httptunnel-3.3-work/tunnel.c Tue Jul 27 12:48:04 2004 @@ -90,6 +90,9 @@ struct tunnel int strict_content_length; int keep_alive; int max_connection_age; + + char *peer_host; + int peer_port; }; static const size_t sizeof_header = sizeof (Request) + sizeof (Length); @@ -376,6 +379,7 @@ tunnel_out_connect (Tunnel *tunnel) /* + 1 to allow for TUNNEL_DISCONNECT */ n = http_post (tunnel->out_fd, &tunnel->dest, + tunnel->peer_host, tunnel->peer_port, tunnel->content_length + 1); if (n == -1) return -1; @@ -420,7 +424,8 @@ tunnel_in_connect (Tunnel *tunnel) tunnel_in_setsockopts (tunnel->in_fd); - if (http_get (tunnel->in_fd, &tunnel->dest) == -1) + if (http_get (tunnel->in_fd, &tunnel->dest, + tunnel->peer_host, tunnel->peer_port) == -1) return -1; #ifdef USE_SHUTDOWN @@ -1095,6 +1100,7 @@ tunnel_accept (Tunnel *tunnel) int len; int n; int s; + char *temp; p.fd = tunnel->server_socket; p.events = POLLIN; @@ -1223,6 +1229,39 @@ tunnel_accept (Tunnel *tunnel) close (s); } + if (tunnel->peer_host != NULL) + { + free (tunnel->peer_host); + tunnel->peer_host = NULL; + tunnel->peer_port = 0; + } + + if (strlen (request->uri) > 5) + { + if ((temp = strdup (request->uri + 1)) == NULL) + { + log_error ("tunnel_accept: Out of memory"); + } + else + { + char *p; + int port = 0; + + p = strchr (temp, '/'); + if ((p != NULL) && (p != temp)) + { + port = atoi (p + 1); + *p = '\0'; + } + + if ((port > 0) && (port < 65536)) + { + tunnel->peer_host = temp; + tunnel->peer_port = port; + } + } + } + http_destroy_request (request); } @@ -1285,6 +1324,8 @@ tunnel_new_server (const char *host, int tunnel->out_total_data = 0; tunnel->strict_content_length = FALSE; tunnel->bytes = 0; + tunnel->peer_host = NULL; + tunnel->peer_port = 0; tunnel->server_socket = server_socket (addr, tunnel->dest.host_port, 1); if (tunnel->server_socket == -1) @@ -1301,6 +1342,7 @@ tunnel_new_server (const char *host, int Tunnel * tunnel_new_client (const char *host, int host_port, const char *proxy, int proxy_port, + const char *peer_host, int peer_port, size_t content_length) { const char *remote; @@ -1337,6 +1379,8 @@ tunnel_new_client (const char *host, int tunnel->out_total_data = 0; tunnel->strict_content_length = FALSE; tunnel->bytes = 0; + tunnel->peer_host = NULL; + tunnel->peer_port = 0; if (tunnel->dest.proxy_name == NULL) { @@ -1349,6 +1393,15 @@ tunnel_new_client (const char *host, int remote_port = tunnel->dest.proxy_port; } + if ((peer_host != NULL) && (peer_port > 0) + && (peer_port < 65535)) + { + if ((tunnel->peer_host = strdup (peer_host)) == NULL) + log_error ("tunnel_new_client: Out of memory"); + else + tunnel->peer_port = peer_port; + } + if (set_address (&tunnel->address, remote, remote_port) == -1) { log_error ("tunnel_new_client: set_address: %s", strerror (errno)); @@ -1368,6 +1421,9 @@ tunnel_destroy (Tunnel *tunnel) if (tunnel->server_socket != -1) close (tunnel->server_socket); + if (tunnel->peer_host != NULL) + free (tunnel->peer_host); + free (tunnel); } @@ -1451,3 +1507,20 @@ tunnel_getopt (Tunnel *tunnel, const cha { return tunnel_opt (tunnel, opt, data, TRUE); } + +int +tunnel_get_peer_address (char **host, int *port, Tunnel *tunnel) +{ + if ((tunnel->peer_host == NULL) + || (tunnel->peer_port == 0)) + { + return (0); + } + + log_verbose ("tunnel_set_peer_address: %s:%d", tunnel->peer_host, tunnel->peer_port); + + *host = tunnel->peer_host; + *port = tunnel->peer_port; + + return (1); +} diff -purb httptunnel-3.3-orig/tunnel.h httptunnel-3.3-work/tunnel.h --- httptunnel-3.3-orig/tunnel.h Tue Jul 25 12:46:50 2000 +++ httptunnel-3.3-work/tunnel.h Tue Jul 27 11:06:21 2004 @@ -69,6 +69,7 @@ typedef struct tunnel Tunnel; extern Tunnel *tunnel_new_client (const char *host, int host_port, const char *proxy, int proxy_port, + const char *peer_host, int peer_port, size_t content_length); extern Tunnel *tunnel_new_server (const char *host, int port, size_t content_length); @@ -83,5 +84,6 @@ extern int tunnel_setopt (Tunnel *tunnel extern int tunnel_getopt (Tunnel *tunnel, const char *opt, void *data); extern int tunnel_close (Tunnel *tunnel); extern void tunnel_destroy (Tunnel *tunnel); +extern int tunnel_get_peer_address (char **host, int *port, Tunnel *tunnel); #endif /* TUNNEL_H */