diff --git a/docs/TODO b/docs/TODO index dd3b835a..0dc7ff80 100644 --- a/docs/TODO +++ b/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 diff --git a/utils/websocket.c b/utils/websocket.c index b08c2785..7a67f223 100644 --- a/utils/websocket.c +++ b/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; diff --git a/utils/websocket.py b/utils/websocket.py index fd4ef3f3..a46f7945 100755 --- a/utils/websocket.py +++ b/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) diff --git a/utils/wsproxy.c b/utils/wsproxy.c index 5b7676ac..0f362297 100644 --- a/utils/wsproxy.c +++ b/utils/wsproxy.c @@ -7,6 +7,7 @@ */ #include #include +#include #include #include #include @@ -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) { + while (1) { + c = getopt_long (argc, argv, "r:", + long_options, &option_index); + + /* 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(); + } + } + + printf("ssl_only: %d\n", ssl_only); + printf("record_filename: %s\n", record_filename); + + if ((argc-optind) != 2) { usage(); } - if (strncmp(argv[idx], "--record", 8) == 0) { - idx++; - record_filename = argv[idx++]; - } - - if ((argc-idx) != 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); diff --git a/utils/wsproxy.py b/utils/wsproxy.py index 568a8a51..a82ce70e 100755 --- a/utils/wsproxy.py +++ b/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)