From f2898eabd30af3f1eb81136f5b74c4ebe956cea1 Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Wed, 16 Jun 2010 12:37:03 -0500 Subject: [PATCH] Add listen address to proxy (C and python). This allows forwarding from an external port to the same port on localhost (loopback). I.e. ./utils/wsproxy `hostname -f`:5901 localhost:5901 --- README.md | 4 ++-- utils/websocket.c | 33 ++++++++++++++++++++++++++++----- utils/websocket.py | 4 ++-- utils/wsproxy.c | 44 ++++++++++++++++++++++++++++++++++---------- utils/wsproxy.py | 25 +++++++++++++++++-------- 5 files changed, 83 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index e7eb7d68..d8b4912b 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,9 @@ Usage * run the python proxy: - `./utils/wsproxy.py [listen_port] [vnc_host] [vnc_port]` + `./utils/wsproxy.py source_port target_addr:target_port - `./utils/wsproxy.py 8787 localhost 5901` + `./utils/wsproxy.py 8787 localhost:5901` * run the mini python web server to serve the directory: diff --git a/utils/websocket.c b/utils/websocket.c index d8ed693a..fd7ae73e 100644 --- a/utils/websocket.c +++ b/utils/websocket.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -326,9 +327,11 @@ ws_ctx_t *do_handshake(int sock) { } void start_server(int listen_port, - void (*handler)(ws_ctx_t*)) { - int lsock, csock, clilen, sopt = 1; + void (*handler)(ws_ctx_t*), + char *listen_host) { + int lsock, csock, clilen, sopt = 1, i; struct sockaddr_in serv_addr, cli_addr; + struct hostent *lhost; ws_ctx_t *ws_ctx; /* Initialize buffers */ @@ -346,17 +349,37 @@ void start_server(int listen_port, if (lsock < 0) { error("ERROR creating listener socket"); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(listen_port); + + /* Resolve listen address */ + if ((listen_host == NULL) || (listen_host[0] == '\0')) { + serv_addr.sin_addr.s_addr = INADDR_ANY; + } else { + lhost = gethostbyname(listen_host); + if (lhost == NULL) { + fatal("Could not resolve self address"); + } + bcopy((char *) lhost->h_addr, + (char *) &serv_addr.sin_addr.s_addr, + lhost->h_length); + for (i=0; i < strlen(lhost->h_addr); i++) { + printf("%d: %d\n", i, lhost->h_addr[i]); + } + } + setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *)&sopt, sizeof(sopt)); if (bind(lsock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - error("ERROR on binding listener socket"); + fatal("ERROR on binding listener socket"); } listen(lsock,100); while (1) { clilen = sizeof(cli_addr); - printf("waiting for connection on port %d\n", listen_port); + if (listen_host) { + printf("waiting for connection on %s:%d\n", listen_host, listen_port); + } else { + printf("waiting for connection on port %d\n", listen_port); + } csock = accept(lsock, (struct sockaddr *) &cli_addr, &clilen); diff --git a/utils/websocket.py b/utils/websocket.py index c9b33c54..fd4ef3f3 100755 --- a/utils/websocket.py +++ b/utils/websocket.py @@ -101,10 +101,10 @@ def do_handshake(sock): retsock.send(server_handshake % (origin, scheme, host, path)) return retsock -def start_server(listen_port, handler): +def start_server(listen_port, handler, listen_host=''): lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - lsock.bind(('', listen_port)) + lsock.bind((listen_host, listen_port)) lsock.listen(100) while True: try: diff --git a/utils/wsproxy.c b/utils/wsproxy.c index b8744423..3326a5f9 100644 --- a/utils/wsproxy.c +++ b/utils/wsproxy.c @@ -28,7 +28,7 @@ Traffic Legend:\n\ "; void usage() { - fprintf(stderr,"Usage: \n"); + fprintf(stderr,"Usage: [--record FILE] [source_addr:]source_port target_addr:target_port\n"); exit(1); } @@ -239,19 +239,43 @@ void proxy_handler(ws_ctx_t *ws_ctx) { int main(int argc, char *argv[]) { - int listen_port, idx=1; + int listen_port, idx = 1; + char *listen_host; - if (strcmp(argv[idx], "--record") == 0) { + if (argc < 2) { + usage(); + } + + if (strncmp(argv[idx], "--record", 8) == 0) { idx++; record_filename = argv[idx++]; } - if ((argc-idx) != 3) { usage(); } - listen_port = strtol(argv[idx++], NULL, 10); - if (errno != 0) { usage(); } - target_host = argv[idx++]; - target_port = strtol(argv[idx++], NULL, 10); - if (errno != 0) { usage(); } + if ((argc-idx) != 2) { + usage(); + } + + if (strstr(argv[idx], ":")) { + listen_host = strtok(argv[idx], ":"); + listen_port = strtol(strtok(NULL, ":"), NULL, 10); + } else { + listen_host = NULL; + listen_port = strtol(argv[idx], NULL, 10); + } + idx++; + if ((errno != 0) || (listen_port == 0)) { + usage(); + } + + if (strstr(argv[idx], ":")) { + target_host = strtok(argv[idx], ":"); + target_port = strtol(strtok(NULL, ":"), NULL, 10); + } else { + usage(); + } + if ((errno != 0) || (target_port == 0)) { + usage(); + } /* Initialize buffers */ bufsize = 65536; @@ -264,7 +288,7 @@ int main(int argc, char *argv[]) if (! (cbuf_tmp = malloc(bufsize)) ) { fatal("malloc()"); } - start_server(listen_port, &proxy_handler); + start_server(listen_port, &proxy_handler, listen_host); free(tbuf); free(cbuf); diff --git a/utils/wsproxy.py b/utils/wsproxy.py index 8d252552..568a8a51 100755 --- a/utils/wsproxy.py +++ b/utils/wsproxy.py @@ -117,18 +117,27 @@ def proxy_handler(client): raise if __name__ == '__main__': - parser = optparse.OptionParser() + usage = "%prog [--record FILE]" + usage += " [source_addr:]source_port target_addr:target_port" + parser = optparse.OptionParser(usage=usage) parser.add_option("--record", dest="record", help="record session to a file", metavar="FILE") (options, args) = parser.parse_args() - if len(args) > 3: parser.error("Too many arguments") - if len(args) < 3: parser.error("Too few arguments") - try: listen_port = int(args[0]) + if len(args) > 2: parser.error("Too many arguments") + if len(args) < 2: parser.error("Too few arguments") + if args[0].count(':') > 0: + listen_host,listen_port = args[0].split(':') + else: + listen_host = '' + listen_port = args[0] + if args[1].count(':') > 0: + target_host,target_port = args[1].split(':') + else: + parser.error("Error parsing target") + try: listen_port = int(listen_port) except: parser.error("Error parsing listen port") - try: target_host = args[1] - except: parser.error("Error parsing target host") - try: target_port = int(args[2]) + try: target_port = int(target_port) except: parser.error("Error parsing target port") - start_server(listen_port, proxy_handler) + start_server(listen_port, proxy_handler, listen_host=listen_host)