summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2018-03-30 09:22:48 +0200
committerChristophe Fergeau <cfergeau@redhat.com>2018-04-05 10:46:43 +0200
commite5172dff9bcf8c2de8426a74fbddbe3bbf1851e4 (patch)
tree5c7d5783192dea588bd06964b7c1e76e1e28e23c
parent89f0dfa01ed2ab8c2a2b0067ecd4a3d17fc67191 (diff)
Add public spice_server_set_tls_options() methodtls-min-version
Its main goal is to allow to set the minimum TLS version that we want spice-server to use. By default we limit ourselves to TLSv1.1 or newer connections. By using this API, one can configure spice-server to accept TLSv1.0 connections too, or on the contrary it can restrict connections to TLSv1.2-only. The other arguments are redundant with the ones already present in spice_server_set_tls(). However, tying this with the setting of the TLS port is a bit odd if one day we want to support multiple TLS ports.
-rw-r--r--server/reds.c72
-rw-r--r--server/spice-server.h10
-rw-r--r--server/spice-server.syms5
3 files changed, 70 insertions, 17 deletions
diff --git a/server/reds.c b/server/reds.c
index f3f6e24c..df0b225b 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -161,6 +161,7 @@ typedef struct RedSSLParameters {
char ca_certificate_file[256];
char dh_key_file[256];
char ciphersuite[256];
+ SpiceTLSProtocolVersion min_version;
} RedSSLParameters;
/* SPICE configuration set through the public spice_server_set_xxx APIS */
@@ -2770,6 +2771,44 @@ static gpointer openssl_global_init(gpointer arg)
return NULL;
}
+static int reds_set_min_tls_version(RedsState *reds)
+{
+ /* By default, connections will be restricted to TLSv1.1 or newer. */
+#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
+ int min_tls_version;
+
+ switch (reds->config->ssl_parameters.min_version) {
+ case SPICE_TLS_PROTOCOL_TLSv1_0:
+ min_tls_version = TLS1_VERSION;
+ break;
+ case SPICE_TLS_PROTOCOL_TLSv1_1:
+ min_tls_version = TLS1_1_VERSION;
+ break;
+ case SPICE_TLS_PROTOCOL_TLSv1_2:
+ min_tls_version = TLS1_2_VERSION;
+ break;
+ default:
+ g_return_val_if_reached(-1);
+ }
+ SSL_CTX_set_min_proto_version(reds->ctx, min_tls_version);
+ /* This should be set by default with OpenSSL 1.1.0, which is also the
+ * version which introduced SSL_CTX_set_min_proto_version
+ */
+ SSL_CTX_set_options(reds->ctx, SSL_OP_NO_COMPRESSION);
+#else
+ long ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
+ if (reds->config->ssl_parameters.min_version > SPICE_TLS_PROTOCOL_TLSv1_0) {
+ ssl_options |= SSL_OP_NO_TLSv1_0;
+ }
+ if (reds->config->ssl_parameters.min_tls_version > SPICE_TLS_PROTOCOL_TLSv1_1) {
+ ssl_options |= SSL_OP_NO_TLSv1_1;
+ }
+ SSL_CTX_set_options(reds->ctx, ssl_options);
+#endif
+
+ return 0;
+}
+
static int reds_init_ssl(RedsState *reds)
{
static GOnce openssl_once = G_ONCE_INIT;
@@ -2787,17 +2826,11 @@ static int reds_init_ssl(RedsState *reds)
return -1;
}
- /* Limit connection to TLSv1.1 or newer. */
-#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
- SSL_CTX_set_min_proto_version(reds->ctx, TLS1_1_VERSION);
- /* This should be set by default with OpenSSL 1.1.0, which is also the
- * version which introduced SSL_CTX_set_min_proto_version
- */
- SSL_CTX_set_options(reds->ctx, SSL_OP_NO_COMPRESSION);
-#else
- long ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION | SSL_OP_NO_TLSv1;
- SSL_CTX_set_options(reds->ctx, ssl_options);
-#endif
+ return_code = reds_set_min_tls_version(reds);
+ if (return_code != 0) {
+ spice_warning("Failed to set minimum TLS version");
+ return -1;
+ }
/* Load our keys and certificates*/
return_code = SSL_CTX_use_certificate_chain_file(reds->ctx, reds->config->ssl_parameters.certs_file);
@@ -3828,15 +3861,19 @@ SPICE_GNUC_VISIBLE int spice_server_set_ticket(SpiceServer *reds,
return 0;
}
-static int spice_server_set_tls_options(SpiceServer *s,
- const char *ca_cert_file, const char *certs_file,
- const char *private_key_file, const char *key_passwd,
- const char *dh_key_file, const char *ciphersuite)
+SPICE_GNUC_VISIBLE int spice_server_set_tls_options(SpiceServer *s, SpiceTLSProtocolVersion min_version,
+ const char *ca_cert_file, const char *certs_file,
+ const char *private_key_file, const char *key_passwd,
+ const char *dh_key_file, const char *ciphersuite)
{
if (ca_cert_file == NULL || certs_file == NULL || private_key_file == NULL) {
return -1;
}
+ if ((min_version < SPICE_TLS_PROTOCOL_TLSv1_0) || (min_version > SPICE_TLS_PROTOCOL_TLSv1_2)) {
+ return -1;
+ }
memset(&s->config->ssl_parameters, 0, sizeof(s->config->ssl_parameters));
+ s->config->ssl_parameters.min_version = SPICE_TLS_PROTOCOL_TLSv1_1;
g_strlcpy(s->config->ssl_parameters.ca_certificate_file, ca_cert_file,
sizeof(s->config->ssl_parameters.ca_certificate_file));
@@ -3857,11 +3894,12 @@ static int spice_server_set_tls_options(SpiceServer *s,
g_strlcpy(s->config->ssl_parameters.dh_key_file, dh_key_file,
sizeof(s->config->ssl_parameters.dh_key_file));
}
+ s->config->ssl_parameters.min_version = min_version;
return 0;
}
-int spice_server_set_tls(SpiceServer *s, int port,
+SPICE_GNUC_VISIBLE int spice_server_set_tls(SpiceServer *s, int port,
const char *ca_cert_file, const char *certs_file,
const char *private_key_file, const char *key_passwd,
const char *dh_key_file, const char *ciphersuite)
@@ -3870,7 +3908,7 @@ int spice_server_set_tls(SpiceServer *s, int port,
if (port <= 0 || port > 0xffff) {
return -1;
}
- res = spice_server_set_tls_options(s,
+ res = spice_server_set_tls_options(s, SPICE_TLS_PROTOCOL_TLSv1_1,
ca_cert_file, certs_file,
private_key_file, key_passwd,
dh_key_file, ciphersuite);
diff --git a/server/spice-server.h b/server/spice-server.h
index 5f572f4f..43819138 100644
--- a/server/spice-server.h
+++ b/server/spice-server.h
@@ -44,6 +44,12 @@ void spice_server_destroy(SpiceServer *s);
#define SPICE_ADDR_FLAG_IPV6_ONLY (1 << 1)
#define SPICE_ADDR_FLAG_UNIX_ONLY (1 << 2)
+typedef enum {
+ SPICE_TLS_PROTOCOL_TLSv1_0,
+ SPICE_TLS_PROTOCOL_TLSv1_1,
+ SPICE_TLS_PROTOCOL_TLSv1_2
+} SpiceTLSProtocolVersion;
+
int spice_server_set_compat_version(SpiceServer *s,
spice_compat_version_t version);
int spice_server_set_port(SpiceServer *s, int port);
@@ -59,6 +65,10 @@ int spice_server_set_tls(SpiceServer *s, int port,
const char *ca_cert_file, const char *certs_file,
const char *private_key_file, const char *key_passwd,
const char *dh_key_file, const char *ciphersuite);
+int spice_server_set_tls_options(SpiceServer *s, SpiceTLSProtocolVersion min_version,
+ const char *ca_cert_file, const char *certs_file,
+ const char *private_key_file, const char *key_passwd,
+ const char *dh_key_file, const char *ciphersuite);
int spice_server_add_client(SpiceServer *s, int socket, int skip_auth);
int spice_server_add_ssl_client(SpiceServer *s, int socket, int skip_auth);
diff --git a/server/spice-server.syms b/server/spice-server.syms
index edf04a42..90d5ee84 100644
--- a/server/spice-server.syms
+++ b/server/spice-server.syms
@@ -173,3 +173,8 @@ SPICE_SERVER_0.13.2 {
global:
spice_server_set_video_codecs;
} SPICE_SERVER_0.13.1;
+
+SPICE_SERVER_0.14.1 {
+global:
+ spice_server_set_tls_options;
+} SPICE_SERVER_0.13.2;