From 58dc1947ded37983c0add02ac6a7859510a52a5b Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Tue, 4 Jan 2011 13:14:46 -0600 Subject: [PATCH] wsproxy: warn when no cert. C sock close cleanup. Warn early about no SSL cert and add clearer warning when a connection comes in as SSL but no cert file exists. For the C version, cleanup closing of the connection socket. Use shutdown for a cleaner cleanup with the client. --- utils/websocket.c | 31 +++++++++++++++++++++---------- utils/websocket.py | 5 +++++ utils/wsproxy.c | 10 ++++++++-- utils/wsproxy.py | 2 ++ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/utils/websocket.c b/utils/websocket.c index 4a124f15..f73bb22a 100644 --- a/utils/websocket.c +++ b/utils/websocket.c @@ -187,6 +187,7 @@ int ws_socket_free(ws_ctx_t *ctx) { ctx->ssl_ctx = NULL; } if (ctx->sockfd) { + shutdown(ctx->sockfd, SHUT_RDWR); close(ctx->sockfd); ctx->sockfd = 0; } @@ -350,26 +351,30 @@ ws_ctx_t *do_handshake(int sock) { handshake[len] = 0; if (len == 0) { handler_msg("ignoring empty handshake\n"); - close(sock); return NULL; } else if (bcmp(handshake, "", 22) == 0) { len = recv(sock, handshake, 1024, 0); handshake[len] = 0; handler_msg("sending flash policy response\n"); send(sock, policy_response, sizeof(policy_response), 0); - close(sock); return NULL; } else if ((bcmp(handshake, "\x16", 1) == 0) || (bcmp(handshake, "\x80", 1) == 0)) { // SSL - if (! settings.cert) { return NULL; } + if (!settings.cert) { + handler_msg("SSL connection but no cert specified\n"); + return NULL; + } else if (access(settings.cert, R_OK) != 0) { + handler_msg("SSL connection but '%s' not found\n", + settings.cert); + return NULL; + } ws_ctx = ws_socket_ssl(sock, settings.cert, settings.key); if (! ws_ctx) { return NULL; } scheme = "wss"; handler_msg("using SSL socket\n"); } else if (settings.ssl_only) { handler_msg("non-SSL connection disallowed\n"); - close(sock); return NULL; } else { ws_ctx = ws_socket(sock); @@ -380,14 +385,12 @@ ws_ctx_t *do_handshake(int sock) { len = ws_recv(ws_ctx, handshake, 4096); if (len == 0) { handler_emsg("Client closed during handshake\n"); - close(sock); return NULL; } handshake[len] = 0; if (!parse_handshake(handshake, &headers)) { handler_emsg("Invalid WS request\n"); - close(sock); return NULL; } @@ -524,8 +527,7 @@ void start_server() { if (pid == 0) { // handler process ws_ctx = do_handshake(csock); if (ws_ctx == NULL) { - close(csock); - handler_msg("No connection after handshake"); + handler_msg("No connection after handshake\n"); break; // Child process exits } @@ -533,13 +535,22 @@ void start_server() { if (pipe_error) { handler_emsg("Closing due to SIGPIPE\n"); } - close(csock); - handler_msg("handler exit\n"); break; // Child process exits } else { // parent process settings.handler_id += 1; } } + if (pid == 0) { + if (ws_ctx) { + ws_socket_free(ws_ctx); + } else { + shutdown(csock, SHUT_RDWR); + close(csock); + } + handler_msg("handler exit\n"); + } else { + handler_msg("wsproxy exit\n"); + } } diff --git a/utils/websocket.py b/utils/websocket.py index b4bc01ec..70748c1d 100755 --- a/utils/websocket.py +++ b/utils/websocket.py @@ -112,6 +112,11 @@ def do_handshake(sock): sock.close() return False elif handshake[0] in ("\x16", "\x80"): + if not os.path.exists(settings['cert']): + handler_msg("SSL connection but '%s' not found" + % settings['cert']) + sock.close() + return False retsock = ssl.wrap_socket( sock, server_side=True, diff --git a/utils/wsproxy.c b/utils/wsproxy.c index dc8b5f7d..5ba22063 100644 --- a/utils/wsproxy.c +++ b/utils/wsproxy.c @@ -257,6 +257,10 @@ int main(int argc, char *argv[]) }; settings.cert = realpath("self.pem", NULL); + if (!settings.cert) { + /* Make sure it's always set to something */ + settings.cert = "self.pem"; + } settings.key = ""; while (1) { @@ -326,9 +330,11 @@ int main(int argc, char *argv[]) } if (ssl_only) { - if (!settings.cert || !access(settings.cert, R_OK)) { - usage("SSL only and cert file not found\n"); + if (!access(settings.cert, R_OK)) { + usage("SSL only and cert file '%s' not found\n", settings.cert); } + } else if (access(settings.cert, R_OK) != 0) { + fprintf(stderr, "Warning: '%s' not found\n", settings.cert); } //printf(" verbose: %d\n", settings.verbose); diff --git a/utils/wsproxy.py b/utils/wsproxy.py index c5339b7a..378e4743 100755 --- a/utils/wsproxy.py +++ b/utils/wsproxy.py @@ -162,6 +162,8 @@ if __name__ == '__main__': if options.ssl_only and not os.path.exists(options.cert): parser.error("SSL only and %s not found" % options.cert) + elif not os.path.exists(options.cert): + print "Warning: %s not found" % options.cert settings['verbose'] = options.verbose settings['listen_host'] = host