Commit 3205a3de authored by Joel Martin's avatar Joel Martin

Add --key option for separate cert and key file.

If only --cert is specified then continue to assume both certificate
and key are in the same file (key first).
parent e70f1d94
...@@ -117,12 +117,21 @@ ws_ctx_t *ws_socket(int socket) { ...@@ -117,12 +117,21 @@ ws_ctx_t *ws_socket(int socket) {
return ctx; return ctx;
} }
ws_ctx_t *ws_socket_ssl(int socket, char * certfile) { ws_ctx_t *ws_socket_ssl(int socket, char * certfile, char * keyfile) {
int ret; int ret;
char msg[1024]; char msg[1024];
char * use_keyfile;
ws_ctx_t *ctx; ws_ctx_t *ctx;
ctx = ws_socket(socket); ctx = ws_socket(socket);
if (keyfile && (keyfile[0] != '\0')) {
// Separate key file
use_keyfile = keyfile;
} else {
// Combined key and cert file
use_keyfile = certfile;
}
// Initialize the library // Initialize the library
if (! ssl_initialized) { if (! ssl_initialized) {
SSL_library_init(); SSL_library_init();
...@@ -138,9 +147,9 @@ ws_ctx_t *ws_socket_ssl(int socket, char * certfile) { ...@@ -138,9 +147,9 @@ ws_ctx_t *ws_socket_ssl(int socket, char * certfile) {
fatal("Failed to configure SSL context"); fatal("Failed to configure SSL context");
} }
if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, certfile, if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, use_keyfile,
SSL_FILETYPE_PEM) <= 0) { SSL_FILETYPE_PEM) <= 0) {
sprintf(msg, "Unable to load private key file %s\n", certfile); sprintf(msg, "Unable to load private key file %s\n", use_keyfile);
fatal(msg); fatal(msg);
} }
...@@ -354,7 +363,7 @@ ws_ctx_t *do_handshake(int sock) { ...@@ -354,7 +363,7 @@ ws_ctx_t *do_handshake(int sock) {
(bcmp(handshake, "\x80", 1) == 0)) { (bcmp(handshake, "\x80", 1) == 0)) {
// SSL // SSL
if (! settings.cert) { return NULL; } if (! settings.cert) { return NULL; }
ws_ctx = ws_socket_ssl(sock, settings.cert); ws_ctx = ws_socket_ssl(sock, settings.cert, settings.key);
if (! ws_ctx) { return NULL; } if (! ws_ctx) { return NULL; }
scheme = "wss"; scheme = "wss";
handler_msg("using SSL socket\n"); handler_msg("using SSL socket\n");
......
...@@ -12,9 +12,10 @@ typedef struct { ...@@ -12,9 +12,10 @@ typedef struct {
int listen_port; int listen_port;
void (*handler)(ws_ctx_t*); void (*handler)(ws_ctx_t*);
int handler_id; int handler_id;
char *cert;
char *key;
int ssl_only; int ssl_only;
int daemon; int daemon;
char *cert;
} settings_t; } settings_t;
typedef struct { typedef struct {
......
...@@ -28,6 +28,7 @@ settings = { ...@@ -28,6 +28,7 @@ settings = {
'handler' : None, 'handler' : None,
'handler_id' : 1, 'handler_id' : 1,
'cert' : None, 'cert' : None,
'key' : None,
'ssl_only' : False, 'ssl_only' : False,
'daemon' : True, 'daemon' : True,
'record' : None, } 'record' : None, }
...@@ -114,7 +115,8 @@ def do_handshake(sock): ...@@ -114,7 +115,8 @@ def do_handshake(sock):
retsock = ssl.wrap_socket( retsock = ssl.wrap_socket(
sock, sock,
server_side=True, server_side=True,
certfile=settings['cert']) certfile=settings['cert'],
keyfile=settings['key'])
scheme = "wss" scheme = "wss"
handler_msg("using SSL/TLS") handler_msg("using SSL/TLS")
elif settings['ssl_only']: elif settings['ssl_only']:
......
...@@ -33,9 +33,11 @@ Traffic Legend:\n\ ...@@ -33,9 +33,11 @@ Traffic Legend:\n\
char USAGE[] = "Usage: [options] " \ char USAGE[] = "Usage: [options] " \
"[source_addr:]source_port target_addr:target_port\n\n" \ "[source_addr:]source_port target_addr:target_port\n\n" \
" --cert CERT load CERT as SSL certificate\n" \ " --verbose|-v verbose messages and per frame traffic\n" \
" --foreground|-f run in the foreground\n" \ " --foreground|-f stay in foreground, do not daemonize\n" \
" --ssl-only disallow non-SSL connections"; " --cert CERT SSL certificate file\n" \
" --key KEY SSL key file (if separate from cert)\n" \
" --ssl-only disallow non-encrypted connections";
#define usage(fmt, args...) \ #define usage(fmt, args...) \
fprintf(stderr, "%s\n\n", USAGE); \ fprintf(stderr, "%s\n\n", USAGE); \
...@@ -250,13 +252,15 @@ int main(int argc, char *argv[]) ...@@ -250,13 +252,15 @@ int main(int argc, char *argv[])
{"foreground", no_argument, &foreground, 'f'}, {"foreground", no_argument, &foreground, 'f'},
/* ---- */ /* ---- */
{"cert", required_argument, 0, 'c'}, {"cert", required_argument, 0, 'c'},
{"key", required_argument, 0, 'k'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
settings.cert = realpath("self.pem", NULL); settings.cert = realpath("self.pem", NULL);
settings.key = "";
while (1) { while (1) {
c = getopt_long (argc, argv, "vfc:", c = getopt_long (argc, argv, "vfc:k:",
long_options, &option_index); long_options, &option_index);
/* Detect the end */ /* Detect the end */
...@@ -279,6 +283,12 @@ int main(int argc, char *argv[]) ...@@ -279,6 +283,12 @@ int main(int argc, char *argv[])
usage("No cert file at %s\n", optarg); usage("No cert file at %s\n", optarg);
} }
break; break;
case 'k':
settings.key = realpath(optarg, NULL);
if (! settings.key) {
usage("No key file at %s\n", optarg);
}
break;
default: default:
usage(""); usage("");
} }
...@@ -316,7 +326,6 @@ int main(int argc, char *argv[]) ...@@ -316,7 +326,6 @@ int main(int argc, char *argv[])
} }
if (ssl_only) { if (ssl_only) {
printf("cert: %s\n", settings.cert);
if (!settings.cert || !access(settings.cert, R_OK)) { if (!settings.cert || !access(settings.cert, R_OK)) {
usage("SSL only and cert file not found\n"); usage("SSL only and cert file not found\n");
} }
...@@ -326,6 +335,7 @@ int main(int argc, char *argv[]) ...@@ -326,6 +335,7 @@ int main(int argc, char *argv[])
//printf(" ssl_only: %d\n", settings.ssl_only); //printf(" ssl_only: %d\n", settings.ssl_only);
//printf(" daemon: %d\n", settings.daemon); //printf(" daemon: %d\n", settings.daemon);
//printf(" cert: %s\n", settings.cert); //printf(" cert: %s\n", settings.cert);
//printf(" key: %s\n", settings.key);
settings.handler = proxy_handler; settings.handler = proxy_handler;
start_server(); start_server();
......
...@@ -137,10 +137,12 @@ if __name__ == '__main__': ...@@ -137,10 +137,12 @@ if __name__ == '__main__':
parser.add_option("--foreground", "-f", parser.add_option("--foreground", "-f",
dest="daemon", default=True, action="store_false", dest="daemon", default=True, action="store_false",
help="stay in foreground, do not daemonize") help="stay in foreground, do not daemonize")
parser.add_option("--cert", default="self.pem",
help="SSL certificate file")
parser.add_option("--key", default=None,
help="SSL key file (if separate from cert)")
parser.add_option("--ssl-only", action="store_true", parser.add_option("--ssl-only", action="store_true",
help="disallow non-encrypted connections") help="disallow non-encrypted connections")
parser.add_option("--cert", default="self.pem",
help="SSL certificate")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
if len(args) > 2: parser.error("Too many arguments") if len(args) > 2: parser.error("Too many arguments")
...@@ -166,6 +168,8 @@ if __name__ == '__main__': ...@@ -166,6 +168,8 @@ if __name__ == '__main__':
settings['listen_port'] = port settings['listen_port'] = port
settings['handler'] = proxy_handler settings['handler'] = proxy_handler
settings['cert'] = os.path.abspath(options.cert) settings['cert'] = os.path.abspath(options.cert)
if settings['key']:
settings['key'] = os.path.abspath(options.key)
settings['ssl_only'] = options.ssl_only settings['ssl_only'] = options.ssl_only
settings['daemon'] = options.daemon settings['daemon'] = options.daemon
if options.record: if options.record:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment