Просмотр исходного кода

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
Joel Martin 15 лет назад
Родитель
Сommit
f2898eabd3
5 измененных файлов с 83 добавлено и 27 удалено
  1. 2 2
      README.md
  2. 28 5
      utils/websocket.c
  3. 2 2
      utils/websocket.py
  4. 34 10
      utils/wsproxy.c
  5. 17 8
      utils/wsproxy.py

+ 2 - 2
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:

+ 28 - 5
utils/websocket.c

@@ -12,6 +12,7 @@
 #include <sys/types.h> 
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netdb.h>
 #include <arpa/inet.h>
 #include <openssl/err.h>
 #include <openssl/ssl.h>
@@ -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);

+ 2 - 2
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:

+ 34 - 10
utils/wsproxy.c

@@ -28,7 +28,7 @@ Traffic Legend:\n\
 ";
 
 void usage() {
-    fprintf(stderr,"Usage: <listen_port> <target_host> <target_port>\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);

+ 17 - 8
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)