Skip to content

Commit

Permalink
Add support for specifying SSL connection parameters to ovsdb
Browse files Browse the repository at this point in the history
Signed-off-by: Ethan Rahn <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
erahn authored and blp committed Nov 10, 2016
1 parent 60230e0 commit e18a1d0
Show file tree
Hide file tree
Showing 26 changed files with 243 additions and 20 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Eohyung Lee [email protected]
Eric Garver [email protected]
Eric Sesterhenn [email protected]
Ethan J. Jackson [email protected]
Ethan Rahn [email protected]
Eziz Durdyyev [email protected]
Flavio Fernandes [email protected]
Flavio Leitner [email protected]
Expand Down
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Post-v2.6.0
---------------------
- Utilities and daemons that support SSL now allow protocols and
ciphers to be configured with --ssl-protocols and --ssl-ciphers.
- OVN:
* QoS is now implemented via egress shaping rather than ingress policing.
* DSCP marking is now supported, via the new northbound QoS table.
Expand Down
2 changes: 2 additions & 0 deletions lib/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,8 @@ MAN_FRAGMENTS += \
lib/ssl-peer-ca-cert-syn.man \
lib/ssl.man \
lib/ssl-syn.man \
lib/ssl-connect.man \
lib/ssl-connect-syn.man \
lib/table.man \
lib/unixctl.man \
lib/unixctl-syn.man \
Expand Down
5 changes: 5 additions & 0 deletions lib/ssl-connect-syn.man
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.IP "SSL connection options:"
[\fB\-\-ssl\-protocols=\fIprotocols\fR]
.br
[\fB\-\-ssl\-ciphers=\fIciphers\fR]
.br
12 changes: 12 additions & 0 deletions lib/ssl-connect.man
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.IP "\fB\-\-ssl\-protocols=\fIprotocols\fR"
Specifies, in a comma- or space-delimited list, the SSL protocols
\fB\*(PN\fR will enable for SSL connections. Supported
\fIprotocols\fR include \fBTLSv1\fR, \fBTLSv1.1\fR, and \fBTLSv1.2\fR.
Regardless of order, the highest protocol supported by both sides will
be chosen when making the connection. The default when this option is
omitted is \fBTLSv1,TLSv1.1,TLSv1.2\fR.
.
.IP "\fB\-\-ssl\-ciphers=\fIciphers\fR"
Specifies, in OpenSSL cipher string format, the ciphers \fB\*(PN\fR will
support for SSL connections. The default when this option is omitted is
\fBHIGH:!aNULL:!MD5\fR.
16 changes: 15 additions & 1 deletion lib/stream-nossl.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 Nicira, Inc.
* Copyright (c) 2011, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -74,3 +74,17 @@ stream_ssl_set_key_and_cert(const char *private_key_file,
stream_ssl_set_private_key_file(private_key_file);
stream_ssl_set_certificate_file(certificate_file);
}

void
stream_ssl_set_protocols(const char *arg OVS_UNUSED)
{
/* Ignore this option since it seems harmless to set SSL protocols if SSL
* won't be used. */
}

void
stream_ssl_set_ciphers(const char *arg OVS_UNUSED)
{
/* Ignore this option since it seems harmless to set SSL ciphers if SSL
* won't be used. */
}
65 changes: 65 additions & 0 deletions lib/stream-ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ struct ssl_config_file {
static struct ssl_config_file private_key;
static struct ssl_config_file certificate;
static struct ssl_config_file ca_cert;
static char *ssl_protocols = "TLSv1,TLSv1.1,TLSv1.2";
static char *ssl_ciphers = "HIGH:!aNULL:!MD5";

/* Ordinarily, the SSL client and server verify each other's certificates using
* a CA certificate. Setting this to false disables this behavior. (This is a
Expand Down Expand Up @@ -966,6 +968,7 @@ do_ssl_init(void)
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
NULL);
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5");

return 0;
}
Expand Down Expand Up @@ -1114,6 +1117,68 @@ stream_ssl_set_key_and_cert(const char *private_key_file,
}
}

/* Sets SSL ciphers based on string input. Aborts with an error message
* if 'arg' is invalid. */
void
stream_ssl_set_ciphers(const char *arg)
{
if (ssl_init() || !arg || !strcmp(ssl_ciphers, arg)) {
return;
}
if (SSL_CTX_set_cipher_list(ctx,arg) == 0) {
VLOG_ERR("SSL_CTX_set_cipher_list: %s",
ERR_error_string(ERR_get_error(), NULL));
}
ssl_ciphers = xstrdup(arg);
}

/* Set SSL protocols based on the string input. Aborts with an error message
* if 'arg' is invalid. */
void
stream_ssl_set_protocols(const char *arg)
{
if (ssl_init() || !arg || !strcmp(arg, ssl_protocols)){
return;
}

/* Start with all the flags off and turn them on as requested. */
long protocol_flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
protocol_flags |= SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;

char *s = xstrdup(arg);
char *save_ptr = NULL;
char *word = strtok_r(s, " ,\t", &save_ptr);
if (word == NULL) {
VLOG_ERR("SSL protocol settings invalid");
goto exit;
}
while (word != NULL) {
long on_flag;
if (!strcasecmp(word, "TLSv1.2")){
on_flag = SSL_OP_NO_TLSv1_2;
} else if (!strcasecmp(word, "TLSv1.1")){
on_flag = SSL_OP_NO_TLSv1_1;
} else if (!strcasecmp(word, "TLSv1")){
on_flag = SSL_OP_NO_TLSv1;
} else {
VLOG_ERR("%s: SSL protocol not recognized", word);
goto exit;
}
/* Reverse the no flag and mask it out in the flags
* to turn on that protocol. */
protocol_flags &= ~on_flag;
word = strtok_r(NULL, " ,\t", &save_ptr);
};

/* Set the actual options. */
SSL_CTX_set_options(ctx, protocol_flags);

ssl_protocols = xstrdup(arg);

exit:
free(s);
}

/* Reads the X509 certificate or certificates in file 'file_name'. On success,
* stores the address of the first element in an array of pointers to
* certificates in '*certs' and the number of certificates in the array in
Expand Down
20 changes: 18 additions & 2 deletions lib/stream-ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,19 @@ void stream_ssl_set_ca_cert_file(const char *file_name, bool bootstrap);
void stream_ssl_set_peer_ca_cert_file(const char *file_name);
void stream_ssl_set_key_and_cert(const char *private_key_file,
const char *certificate_file);
void stream_ssl_set_protocols(const char *arg);
void stream_ssl_set_ciphers(const char *arg);

#define SSL_OPTION_ENUMS \
OPT_SSL_PROTOCOLS, \
OPT_SSL_CIPHERS

#define STREAM_SSL_LONG_OPTIONS \
{"private-key", required_argument, NULL, 'p'}, \
{"certificate", required_argument, NULL, 'c'}, \
{"ca-cert", required_argument, NULL, 'C'}
{"ca-cert", required_argument, NULL, 'C'}, \
{"ssl-protocols", required_argument, NULL, OPT_SSL_PROTOCOLS}, \
{"ssl-ciphers", required_argument, NULL, OPT_SSL_CIPHERS}

#define STREAM_SSL_OPTION_HANDLERS \
case 'p': \
Expand All @@ -42,6 +50,14 @@ void stream_ssl_set_key_and_cert(const char *private_key_file,
\
case 'C': \
stream_ssl_set_ca_cert_file(optarg, false); \
break;
break; \
\
case OPT_SSL_PROTOCOLS: \
stream_ssl_set_protocols(optarg); \
break; \
\
case OPT_SSL_CIPHERS: \
stream_ssl_set_ciphers(optarg); \
break;

#endif /* stream-ssl.h */
8 changes: 8 additions & 0 deletions manpages.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ ovsdb/ovsdb-client.1: \
lib/daemon.man \
lib/ssl-bootstrap-syn.man \
lib/ssl-bootstrap.man \
lib/ssl-connect-syn.man \
lib/ssl-connect.man \
lib/ssl-syn.man \
lib/ssl.man \
lib/table.man \
Expand All @@ -34,6 +36,8 @@ lib/daemon-syn.man:
lib/daemon.man:
lib/ssl-bootstrap-syn.man:
lib/ssl-bootstrap.man:
lib/ssl-connect-syn.man:
lib/ssl-connect.man:
lib/ssl-syn.man:
lib/ssl.man:
lib/table.man:
Expand All @@ -54,6 +58,8 @@ ovsdb/ovsdb-server.1: \
lib/service.man \
lib/ssl-bootstrap-syn.man \
lib/ssl-bootstrap.man \
lib/ssl-connect-syn.man \
lib/ssl-connect.man \
lib/ssl-peer-ca-cert-syn.man \
lib/ssl-peer-ca-cert.man \
lib/ssl-syn.man \
Expand All @@ -78,6 +84,8 @@ lib/service-syn.man:
lib/service.man:
lib/ssl-bootstrap-syn.man:
lib/ssl-bootstrap.man:
lib/ssl-connect-syn.man:
lib/ssl-connect.man:
lib/ssl-peer-ca-cert-syn.man:
lib/ssl-peer-ca-cert.man:
lib/ssl-syn.man:
Expand Down
3 changes: 2 additions & 1 deletion ovn/controller-vtep/ovn-controller-vtep.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ parse_options(int argc, char *argv[])
OPT_PEER_CA_CERT = UCHAR_MAX + 1,
OPT_BOOTSTRAP_CA_CERT,
VLOG_OPTION_ENUMS,
DAEMON_OPTION_ENUMS
DAEMON_OPTION_ENUMS,
SSL_OPTION_ENUMS,
};

static struct option long_options[] = {
Expand Down
3 changes: 2 additions & 1 deletion ovn/controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,8 @@ parse_options(int argc, char *argv[])
OPT_PEER_CA_CERT = UCHAR_MAX + 1,
OPT_BOOTSTRAP_CA_CERT,
VLOG_OPTION_ENUMS,
DAEMON_OPTION_ENUMS
DAEMON_OPTION_ENUMS,
SSL_OPTION_ENUMS,
};

static struct option long_options[] = {
Expand Down
1 change: 1 addition & 0 deletions ovn/northd/ovn-northd.c
Original file line number Diff line number Diff line change
Expand Up @@ -4696,6 +4696,7 @@ parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
enum {
DAEMON_OPTION_ENUMS,
VLOG_OPTION_ENUMS,
SSL_OPTION_ENUMS,
};
static const struct option long_options[] = {
{"ovnsb-db", required_argument, NULL, 'd'},
Expand Down
3 changes: 2 additions & 1 deletion ovn/utilities/ovn-nbctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ parse_options(int argc, char *argv[], struct shash *local_options)
OPT_COMMANDS,
OPT_OPTIONS,
VLOG_OPTION_ENUMS,
TABLE_OPTION_ENUMS
TABLE_OPTION_ENUMS,
SSL_OPTION_ENUMS,
};
static const struct option global_long_options[] = {
{"db", required_argument, NULL, OPT_DB},
Expand Down
3 changes: 2 additions & 1 deletion ovn/utilities/ovn-sbctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ parse_options(int argc, char *argv[], struct shash *local_options)
OPT_COMMANDS,
OPT_OPTIONS,
VLOG_OPTION_ENUMS,
TABLE_OPTION_ENUMS
TABLE_OPTION_ENUMS,
SSL_OPTION_ENUMS,
};
static const struct option global_long_options[] = {
{"db", required_argument, NULL, OPT_DB},
Expand Down
1 change: 1 addition & 0 deletions ovn/utilities/ovn-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ parse_options(int argc, char *argv[])
OPT_MINIMAL,
OPT_ALL,
DAEMON_OPTION_ENUMS,
SSL_OPTION_ENUMS,
VLOG_OPTION_ENUMS
};
static const struct option long_options[] = {
Expand Down
3 changes: 3 additions & 0 deletions ovsdb/ovsdb-client.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1)
.so lib/vlog-syn.man
.so lib/ssl-syn.man
.so lib/ssl-bootstrap-syn.man
.so lib/ssl-connect-syn.man
.so lib/common-syn.man
.
.SH DESCRIPTION
Expand Down Expand Up @@ -205,6 +206,8 @@ With any other command, they have no effect.
.SS "Public Key Infrastructure Options"
.so lib/ssl.man
.so lib/ssl-bootstrap.man
.SS "SSL Connection Options"
.so lib/ssl-connect.man
.SS "Other Options"
.so lib/common.man
.SH "SEE ALSO"
Expand Down
3 changes: 2 additions & 1 deletion ovsdb/ovsdb-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ parse_options(int argc, char *argv[])
OPT_TIMESTAMP,
VLOG_OPTION_ENUMS,
DAEMON_OPTION_ENUMS,
TABLE_OPTION_ENUMS
TABLE_OPTION_ENUMS,
SSL_OPTION_ENUMS,
};
static const struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
Expand Down
3 changes: 3 additions & 0 deletions ovsdb/ovsdb-server.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ovsdb\-server \- Open vSwitch database server
.so lib/ssl-syn.man
.so lib/ssl-bootstrap-syn.man
.so lib/ssl-peer-ca-cert-syn.man
.so lib/ssl-connect-syn.man
.so lib/unixctl-syn.man
.so lib/common-syn.man
.
Expand Down Expand Up @@ -135,6 +136,8 @@ one row in \fItable\fR.)
.so lib/ssl.man
.so lib/ssl-bootstrap.man
.so lib/ssl-peer-ca-cert.man
.SS "SSL Connection Options"
.so lib/ssl-connect.man
.SS "Other Options"
.so lib/unixctl.man
.so lib/common.man
Expand Down
23 changes: 19 additions & 4 deletions ovsdb/ovsdb-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ struct db {
static char *private_key_file;
static char *certificate_file;
static char *ca_cert_file;
static char *ssl_protocols;
static char *ssl_ciphers;
static bool bootstrap_ca_cert;

static unixctl_cb_func ovsdb_server_exit;
Expand Down Expand Up @@ -1110,13 +1112,19 @@ reconfigure_ssl(const struct shash *all_dbs)
const char *resolved_private_key;
const char *resolved_certificate;
const char *resolved_ca_cert;
const char *resolved_ssl_protocols;
const char *resolved_ssl_ciphers;

resolved_private_key = query_db_string(all_dbs, private_key_file, &errors);
resolved_certificate = query_db_string(all_dbs, certificate_file, &errors);
resolved_ca_cert = query_db_string(all_dbs, ca_cert_file, &errors);
resolved_ssl_protocols = query_db_string(all_dbs, ssl_protocols, &errors);
resolved_ssl_ciphers = query_db_string(all_dbs, ssl_ciphers, &errors);

stream_ssl_set_key_and_cert(resolved_private_key, resolved_certificate);
stream_ssl_set_ca_cert_file(resolved_ca_cert, bootstrap_ca_cert);
stream_ssl_set_protocols(resolved_ssl_protocols);
stream_ssl_set_ciphers(resolved_ssl_ciphers);

return errors.string;
}
Expand Down Expand Up @@ -1517,7 +1525,8 @@ parse_options(int *argcp, char **argvp[],
OPT_SYNC_EXCLUDE,
OPT_ACTIVE,
VLOG_OPTION_ENUMS,
DAEMON_OPTION_ENUMS
DAEMON_OPTION_ENUMS,
SSL_OPTION_ENUMS,
};
static const struct option long_options[] = {
{"remote", required_argument, NULL, OPT_REMOTE},
Expand All @@ -1531,9 +1540,7 @@ parse_options(int *argcp, char **argvp[],
VLOG_LONG_OPTIONS,
{"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
{"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
{"private-key", required_argument, NULL, 'p'},
{"certificate", required_argument, NULL, 'c'},
{"ca-cert", required_argument, NULL, 'C'},
STREAM_SSL_LONG_OPTIONS,
{"sync-from", required_argument, NULL, OPT_SYNC_FROM},
{"sync-exclude-tables", required_argument, NULL, OPT_SYNC_EXCLUDE},
{"active", no_argument, NULL, OPT_ACTIVE},
Expand Down Expand Up @@ -1590,6 +1597,14 @@ parse_options(int *argcp, char **argvp[],
bootstrap_ca_cert = false;
break;

case OPT_SSL_PROTOCOLS:
ssl_protocols = optarg;
break;

case OPT_SSL_CIPHERS:
ssl_ciphers = optarg;
break;

case OPT_BOOTSTRAP_CA_CERT:
ca_cert_file = optarg;
bootstrap_ca_cert = true;
Expand Down
Loading

0 comments on commit e18a1d0

Please sign in to comment.