ソースを参照

Force SSL option to proxies. Use getopt_long.

Joel Martin 15 年 前
コミット
459b2578b2
5 ファイル変更57 行追加26 行削除
  1. 0 2
      docs/TODO
  2. 9 3
      utils/websocket.c
  3. 7 3
      utils/websocket.py
  4. 36 16
      utils/wsproxy.c
  5. 5 2
      utils/wsproxy.py

+ 0 - 2
docs/TODO

@@ -1,7 +1,5 @@
 Medium Term:
 
-- Option to force SSL in proxy.
-
 - Implement Cursor pseudo-encoding (CSS cursor)
     http://en.wikipedia.org/wiki/ICO_(file_format)
     https://developer.mozilla.org/en/Using_URL_values_for_the_cursor_property

+ 9 - 3
utils/websocket.c

@@ -269,7 +269,7 @@ int decode(char *src, size_t srclength, u_char *target, size_t targsize) {
     return retlen;
 }
 
-ws_ctx_t *do_handshake(int sock) {
+ws_ctx_t *do_handshake(int sock, int ssl_only) {
     char handshake[4096], response[4096];
     char *scheme, *line, *path, *host, *origin;
     char *args_start, *args_end, *arg_idx;
@@ -296,6 +296,10 @@ ws_ctx_t *do_handshake(int sock) {
         if (! ws_ctx) { return NULL; }
         scheme = "wss";
         printf("Using SSL socket\n");
+    } else if (ssl_only) {
+        printf("Non-SSL connection disallowed");
+        close(sock);
+        return NULL;
     } else {
         ws_ctx = ws_socket(sock);
         if (! ws_ctx) { return NULL; }
@@ -352,7 +356,8 @@ ws_ctx_t *do_handshake(int sock) {
 
 void start_server(int listen_port,
                   void (*handler)(ws_ctx_t*),
-                  char *listen_host) {
+                  char *listen_host,
+                  int ssl_only) {
     int lsock, csock, clilen, sopt = 1, i;
     struct sockaddr_in serv_addr, cli_addr;
     ws_ctx_t *ws_ctx;
@@ -401,9 +406,10 @@ void start_server(int listen_port,
                        &clilen);
         if (csock < 0) {
             error("ERROR on accept");
+            continue;
         }
         printf("Got client connection from %s\n", inet_ntoa(cli_addr.sin_addr));
-        ws_ctx = do_handshake(csock);
+        ws_ctx = do_handshake(csock, ssl_only);
         if (ws_ctx == NULL) {
             close(csock);
             continue;

+ 7 - 3
utils/websocket.py

@@ -59,7 +59,7 @@ def encode(buf):
         return "\x00%s\xff" % buf
 
 
-def do_handshake(sock):
+def do_handshake(sock, ssl_only=False):
     global client_settings, send_seq
     send_seq = 0
     # Peek, but don't read the data
@@ -79,6 +79,10 @@ def do_handshake(sock):
                 ssl_version=ssl.PROTOCOL_TLSv1)
         scheme = "wss"
         print "Using SSL/TLS"
+    elif ssl_only:
+        print "Non-SSL connection disallowed"
+        sock.close()
+        return False
     else:
         retsock = sock
         scheme = "ws"
@@ -101,7 +105,7 @@ def do_handshake(sock):
     retsock.send(server_handshake % (origin, scheme, host, path))
     return retsock
 
-def start_server(listen_port, handler, listen_host=''):
+def start_server(listen_port, handler, listen_host='', ssl_only=False):
     lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     lsock.bind((listen_host, listen_port))
@@ -112,7 +116,7 @@ def start_server(listen_port, handler, listen_host=''):
             print 'waiting for connection on port %s' % listen_port
             startsock, address = lsock.accept()
             print 'Got client connection from %s' % address[0]
-            csock = do_handshake(startsock)
+            csock = do_handshake(startsock, ssl_only=ssl_only)
             if not csock: continue
 
             handler(csock)

+ 36 - 16
utils/wsproxy.c

@@ -7,6 +7,7 @@
  */
 #include <stdio.h>
 #include <errno.h>
+#include <getopt.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netdb.h>
@@ -27,8 +28,11 @@ Traffic Legend:\n\
     <. - Client send partial\n\
 ";
 
+char USAGE[] = "Usage: [--record FILE] [--ssl-only] " \
+               "[source_addr:]source_port target_addr:target_port";
+
 void usage() {
-    fprintf(stderr,"Usage: [--record FILE] [source_addr:]source_port target_addr:target_port\n");
+    fprintf(stderr, "%s\n", USAGE);
     exit(1);
 }
 
@@ -234,36 +238,52 @@ void proxy_handler(ws_ctx_t *ws_ctx) {
 
 int main(int argc, char *argv[])
 {
-    int listen_port, idx = 1;
+    int listen_port, c, option_index = 0;
+    static int ssl_only = 0;
     char *listen_host;
+    static struct option long_options[] = {
+        {"ssl-only", no_argument, &ssl_only, 1},
+        /* ---- */
+        {"record",   required_argument, 0, 'r'},
+        {0, 0, 0, 0}
+    };
 
-    if (argc < 2) {
-        usage();
-    }
+    while (1) {
+        c = getopt_long (argc, argv, "r:",
+                         long_options, &option_index);
 
-    if (strncmp(argv[idx], "--record", 8) == 0) {
-        idx++;
-        record_filename = argv[idx++];
+        /* Detect the end */
+        if (c == -1) { break; }
+
+        switch (c) {
+            case 0:    break; // ignore
+            case 1:    break; // ignore
+            case 'r':  record_filename = optarg; break;
+            default:   usage();
+        }
     }
 
-    if ((argc-idx) != 2) {
+    printf("ssl_only: %d\n", ssl_only);
+    printf("record_filename: %s\n", record_filename);
+
+    if ((argc-optind) != 2) {
         usage();
     }
 
-    if (strstr(argv[idx], ":")) {
-        listen_host = strtok(argv[idx], ":");
+    if (strstr(argv[optind], ":")) {
+        listen_host = strtok(argv[optind], ":");
         listen_port = strtol(strtok(NULL, ":"), NULL, 10);
     } else {
         listen_host = NULL;
-        listen_port = strtol(argv[idx], NULL, 10);
+        listen_port = strtol(argv[optind], NULL, 10);
     }
-    idx++;
+    optind++;
     if ((errno != 0) || (listen_port == 0)) {
         usage();
     }
 
-    if (strstr(argv[idx], ":")) {
-        target_host = strtok(argv[idx], ":");
+    if (strstr(argv[optind], ":")) {
+        target_host = strtok(argv[optind], ":");
         target_port = strtol(strtok(NULL, ":"), NULL, 10);
     } else {
         usage();
@@ -283,7 +303,7 @@ int main(int argc, char *argv[])
     if (! (cbuf_tmp = malloc(bufsize)) )
             { fatal("malloc()"); }
 
-    start_server(listen_port, &proxy_handler, listen_host);
+    start_server(listen_port, &proxy_handler, listen_host, ssl_only);
 
     free(tbuf);
     free(cbuf);

+ 5 - 2
utils/wsproxy.py

@@ -120,8 +120,10 @@ if __name__ == '__main__':
     usage = "%prog [--record FILE]"
     usage += " [source_addr:]source_port target_addr:target_port"
     parser = optparse.OptionParser(usage=usage)
-    parser.add_option("--record", dest="record",
+    parser.add_option("--record",
             help="record session to a file", metavar="FILE")
+    parser.add_option("--ssl-only", action="store_true",
+            help="disallow non-encrypted connections")
     (options, args) = parser.parse_args()
 
     if len(args) > 2: parser.error("Too many arguments")
@@ -140,4 +142,5 @@ if __name__ == '__main__':
     try:    target_port = int(target_port)
     except: parser.error("Error parsing target port")
 
-    start_server(listen_port, proxy_handler, listen_host=listen_host)
+    start_server(listen_port, proxy_handler, listen_host=listen_host,
+            ssl_only=options.ssl_only)