From 9b96266830c2e565d1f3cadb322ebbc93ac94fa4 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 12 Jul 2021 12:43:47 +0200 Subject: [PATCH] Utilize system-wide crypto policies --- common/rfb/CSecurityTLS.cxx | 66 ++++++++++++++++++++++++++++-------- common/rfb/SSecurityTLS.cxx | 66 ++++++++++++++++++++++++++++-------- common/rfb/Security.cxx | 2 +- unix/xserver/hw/vnc/Xvnc.man | 4 ++- 4 files changed, 108 insertions(+), 30 deletions(-) diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index b32725f0..d2a71564 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -205,26 +205,64 @@ void CSecurityTLS::setParam() static const char kx_anon_priority[] = ":+ANON-ECDH:+ANON-DH"; int ret; - char *prio; - const char *err; - prio = (char*)malloc(strlen(Security::GnuTLSPriority) + - strlen(kx_anon_priority) + 1); - if (prio == NULL) - throw AuthFailureException("Not enough memory for GnuTLS priority string"); + // Custom priority string specified? + if (strcmp(Security::GnuTLSPriority, "") != 0) { + char *prio; + const char *err; - strcpy(prio, Security::GnuTLSPriority); - if (anon) + prio = (char*)malloc(strlen(Security::GnuTLSPriority) + + strlen(kx_anon_priority) + 1); + if (prio == NULL) + throw AuthFailureException("Not enough memory for GnuTLS priority string"); + + strcpy(prio, Security::GnuTLSPriority); + if (anon) + strcat(prio, kx_anon_priority); + + ret = gnutls_priority_set_direct(session, prio, &err); + + free(prio); + + if (ret != GNUTLS_E_SUCCESS) { + if (ret == GNUTLS_E_INVALID_REQUEST) + vlog.error("GnuTLS priority syntax error at: %s", err); + throw AuthFailureException("gnutls_set_priority_direct failed"); + } + } else if (anon) { + const char *err; + +#if GNUTLS_VERSION_NUMBER >= 0x030603 + ret = gnutls_set_default_priority_append(session, kx_anon_priority, &err, 0); + if (ret != GNUTLS_E_SUCCESS) { + if (ret == GNUTLS_E_INVALID_REQUEST) + vlog.error("GnuTLS priority syntax error at: %s", err); + throw AuthFailureException("gnutls_set_default_priority_append failed"); + } +#else + // We don't know what the system default priority is, so we guess + // it's what upstream GnuTLS has + static const char gnutls_default_priority[] = "NORMAL"; + char *prio; + + prio = (char*)malloc(strlen(gnutls_default_priority) + + strlen(kx_anon_priority) + 1); + if (prio == NULL) + throw AuthFailureException("Not enough memory for GnuTLS priority string"); + + strcpy(prio, gnutls_default_priority); strcat(prio, kx_anon_priority); - ret = gnutls_priority_set_direct(session, prio, &err); + ret = gnutls_priority_set_direct(session, prio, &err); - free(prio); + free(prio); - if (ret != GNUTLS_E_SUCCESS) { - if (ret == GNUTLS_E_INVALID_REQUEST) - vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_priority_direct failed"); + if (ret != GNUTLS_E_SUCCESS) { + if (ret == GNUTLS_E_INVALID_REQUEST) + vlog.error("GnuTLS priority syntax error at: %s", err); + throw AuthFailureException("gnutls_set_priority_direct failed"); + } +#endif } if (anon) { diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx index d5ef47e6..2c236c71 100644 --- a/common/rfb/SSecurityTLS.cxx +++ b/common/rfb/SSecurityTLS.cxx @@ -176,26 +176,64 @@ void SSecurityTLS::setParams(gnutls_session_t session) static const char kx_anon_priority[] = ":+ANON-ECDH:+ANON-DH"; int ret; - char *prio; - const char *err; - prio = (char*)malloc(strlen(Security::GnuTLSPriority) + - strlen(kx_anon_priority) + 1); - if (prio == NULL) - throw AuthFailureException("Not enough memory for GnuTLS priority string"); + // Custom priority string specified? + if (strcmp(Security::GnuTLSPriority, "") != 0) { + char *prio; + const char *err; - strcpy(prio, Security::GnuTLSPriority); - if (anon) + prio = (char*)malloc(strlen(Security::GnuTLSPriority) + + strlen(kx_anon_priority) + 1); + if (prio == NULL) + throw AuthFailureException("Not enough memory for GnuTLS priority string"); + + strcpy(prio, Security::GnuTLSPriority); + if (anon) + strcat(prio, kx_anon_priority); + + ret = gnutls_priority_set_direct(session, prio, &err); + + free(prio); + + if (ret != GNUTLS_E_SUCCESS) { + if (ret == GNUTLS_E_INVALID_REQUEST) + vlog.error("GnuTLS priority syntax error at: %s", err); + throw AuthFailureException("gnutls_set_priority_direct failed"); + } + } else if (anon) { + const char *err; + +#if GNUTLS_VERSION_NUMBER >= 0x030603 + ret = gnutls_set_default_priority_append(session, kx_anon_priority, &err, 0); + if (ret != GNUTLS_E_SUCCESS) { + if (ret == GNUTLS_E_INVALID_REQUEST) + vlog.error("GnuTLS priority syntax error at: %s", err); + throw AuthFailureException("gnutls_set_default_priority_append failed"); + } +#else + // We don't know what the system default priority is, so we guess + // it's what upstream GnuTLS has + static const char gnutls_default_priority[] = "NORMAL"; + char *prio; + + prio = (char*)malloc(strlen(gnutls_default_priority) + + strlen(kx_anon_priority) + 1); + if (prio == NULL) + throw AuthFailureException("Not enough memory for GnuTLS priority string"); + + strcpy(prio, gnutls_default_priority); strcat(prio, kx_anon_priority); - ret = gnutls_priority_set_direct(session, prio, &err); + ret = gnutls_priority_set_direct(session, prio, &err); - free(prio); + free(prio); - if (ret != GNUTLS_E_SUCCESS) { - if (ret == GNUTLS_E_INVALID_REQUEST) - vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_priority_direct failed"); + if (ret != GNUTLS_E_SUCCESS) { + if (ret == GNUTLS_E_INVALID_REQUEST) + vlog.error("GnuTLS priority syntax error at: %s", err); + throw AuthFailureException("gnutls_set_priority_direct failed"); + } +#endif } if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS) diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx index 0666041c..59deb78d 100644 --- a/common/rfb/Security.cxx +++ b/common/rfb/Security.cxx @@ -52,7 +52,7 @@ static LogWriter vlog("Security"); #ifdef HAVE_GNUTLS StringParameter Security::GnuTLSPriority("GnuTLSPriority", "GnuTLS priority string that controls the TLS session’s handshake algorithms", - "NORMAL"); + ""); #endif Security::Security() diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man index c85c396f..56da92ea 100644 --- a/unix/xserver/hw/vnc/Xvnc.man +++ b/unix/xserver/hw/vnc/Xvnc.man @@ -220,7 +220,9 @@ also be in PEM format. .TP .B \-GnuTLSPriority \fIpriority\fP GnuTLS priority string that controls the TLS session’s handshake algorithms. -See the GnuTLS manual for possible values. Default is \fBNORMAL\fP. +See the GnuTLS manual for possible values. For GnuTLS < 3.6.3 the default +value will be \fBNORMAL\fP to use upstream default. For newer versions +of GnuTLS system-wide crypto policy will be used. . .TP .B \-UseBlacklist -- 2.39.5