From 63aefcd517fd9dc5734620c876b5e7cb86f7ea11 Mon Sep 17 00:00:00 2001 From: msweet Date: Mon, 20 Oct 2014 16:58:48 +0000 Subject: [PATCH] Implement SSLOptions in cupsd.conf and client.conf to allow admins to enable SSL 3.0 and RC4 (STR #4476) (currently RC4 cipher restrictions are not implemented on OS X or Windows) git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12211 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-2.0.txt | 2 + cups/http-private.h | 4 ++ cups/tls-darwin.c | 125 +++++++++++++++++++++++++++++++++- cups/tls-gnutls.c | 21 ++++++ cups/tls-sspi.c | 40 ++++++++++- cups/usersys.c | 94 +++++++++++++++++++------ doc/help/man-client.conf.html | 6 ++ doc/help/man-cupsd.conf.html | 6 ++ man/client.conf.man.in | 10 ++- man/cupsd.conf.man.in | 10 ++- scheduler/conf.c | 45 ++++++++++++ 11 files changed, 334 insertions(+), 29 deletions(-) diff --git a/CHANGES-2.0.txt b/CHANGES-2.0.txt index 956ada16f..e5b9bc757 100644 --- a/CHANGES-2.0.txt +++ b/CHANGES-2.0.txt @@ -3,6 +3,8 @@ CHANGES-2.0.txt CHANGES IN CUPS V2.0.1 + - Security: SSLv3 is now disabled by default to protect against the + POODLE attack (STR #4476) - Fixed a crash in ippAttributeString () - RPMs did not build (STR #4490) diff --git a/cups/http-private.h b/cups/http-private.h index d7bdc8650..7ef0833cd 100644 --- a/cups/http-private.h +++ b/cups/http-private.h @@ -161,6 +161,9 @@ extern "C" { #define _HTTP_RESOLVE_FQDN 2 /* Resolve to a FQDN */ #define _HTTP_RESOLVE_FAXOUT 4 /* Resolve FaxOut service? */ +#define _HTTP_TLS_ALLOW_RC4 1 /* Allow RC4 cipher suites */ +#define _HTTP_TLS_ALLOW_SSL3 1 /* Allow SSL 3.0 */ + /* * Types and functions for SSL support... @@ -420,6 +423,7 @@ extern void _httpTLSInitialize(void); extern size_t _httpTLSPending(http_t *http); extern int _httpTLSRead(http_t *http, char *buf, int len); extern int _httpTLSSetCredentials(http_t *http); +extern void _httpTLSSetOptions(int options); extern int _httpTLSStart(http_t *http); extern void _httpTLSStop(http_t *http); extern int _httpTLSWrite(http_t *http, const char *buf, int len); diff --git a/cups/tls-darwin.c b/cups/tls-darwin.c index 8d2cbb262..f87294990 100644 --- a/cups/tls-darwin.c +++ b/cups/tls-darwin.c @@ -26,6 +26,14 @@ extern char **environ; +/* + * Test define - set to 1 to use SSLSetEnabledCiphers. Currently disabled (0) + * because of . + */ + +#define USE_SET_ENABLED_CIPHERS 0 + + /* * Local globals... */ @@ -41,6 +49,7 @@ static char *tls_keypath = NULL; /* Server cert keychain path */ static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER; /* Mutex for keychain/certs */ +static int tls_options = 0;/* Options for TLS connections */ #endif /* HAVE_SECKEYCHAINOPEN */ @@ -972,6 +981,17 @@ _httpTLSRead(http_t *http, /* I - HTTP connection */ } +/* + * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options. + */ + +void +_httpTLSSetOptions(int options) /* I - Options */ +{ + tls_options = options; +} + + /* * '_httpTLSStart()' - Set up SSL/TLS support on a connection. */ @@ -1033,9 +1053,108 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ { error = SSLSetSessionOption(http->tls, kSSLSessionOptionBreakOnServerAuth, true); - DEBUG_printf(("4_httpTLSStart: SSLSetSessionOption, error=%d", - (int)error)); + DEBUG_printf(("4_httpTLSStart: SSLSetSessionOption, error=%d", (int)error)); + } + + if (!error) + { + error = SSLSetProtocolVersionMin(http->tls, (tls_options & _HTTP_TLS_ALLOW_SSL3) ? kSSLProtocol3 : kTLSProtocol1); + DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin, error=%d", (int)error)); + } + +# if USE_SET_ENABLED_CIPHERS + if (!error) + { + SSLCipherSuite supported[100]; /* Supported cipher suites */ + size_t num_supported; /* Number of supported cipher suites */ + SSLCipherSuite enabled[100]; /* Cipher suites to enable */ + size_t num_enabled; /* Number of cipher suites to enable */ + + num_supported = sizeof(supported) / sizeof(supported[0]); + error = SSLGetSupportedCiphers(http->tls, supported, &num_supported); + + if (!error) + { + DEBUG_printf(("4_httpTLSStart: %d cipher suites supported.", (int)num_supported)); + + for (i = 0, num_enabled = 0; i < (int)num_supported && num_enabled < (sizeof(enabled) / sizeof(enabled[0])); i ++) + { + switch (supported[i]) + { + /* Obviously insecure cipher suites that we never want to use */ + case SSL_NULL_WITH_NULL_NULL : + case SSL_RSA_WITH_NULL_MD5 : + case SSL_RSA_WITH_NULL_SHA : + case SSL_RSA_EXPORT_WITH_RC4_40_MD5 : + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 : + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA : + case SSL_RSA_WITH_DES_CBC_SHA : + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA : + case SSL_DH_DSS_WITH_DES_CBC_SHA : + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA : + case SSL_DH_RSA_WITH_DES_CBC_SHA : + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA : + case SSL_DHE_DSS_WITH_DES_CBC_SHA : + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA : + case SSL_DHE_RSA_WITH_DES_CBC_SHA : + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 : + case SSL_DH_anon_WITH_RC4_128_MD5 : + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA : + case SSL_DH_anon_WITH_DES_CBC_SHA : + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA : + case SSL_FORTEZZA_DMS_WITH_NULL_SHA : + case TLS_DH_anon_WITH_AES_128_CBC_SHA : + case TLS_DH_anon_WITH_AES_256_CBC_SHA : + case TLS_ECDH_ECDSA_WITH_NULL_SHA : + case TLS_ECDHE_RSA_WITH_NULL_SHA : + case TLS_ECDH_anon_WITH_NULL_SHA : + case TLS_ECDH_anon_WITH_RC4_128_SHA : + case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA : + case TLS_ECDH_anon_WITH_AES_128_CBC_SHA : + case TLS_ECDH_anon_WITH_AES_256_CBC_SHA : + case TLS_RSA_WITH_NULL_SHA256 : + case TLS_DH_anon_WITH_AES_128_CBC_SHA256 : + case TLS_DH_anon_WITH_AES_256_CBC_SHA256 : + case TLS_PSK_WITH_NULL_SHA : + case TLS_DHE_PSK_WITH_NULL_SHA : + case TLS_RSA_PSK_WITH_NULL_SHA : + case TLS_DH_anon_WITH_AES_128_GCM_SHA256 : + case TLS_DH_anon_WITH_AES_256_GCM_SHA384 : + case TLS_PSK_WITH_NULL_SHA256 : + case TLS_PSK_WITH_NULL_SHA384 : + case TLS_DHE_PSK_WITH_NULL_SHA256 : + case TLS_DHE_PSK_WITH_NULL_SHA384 : + case TLS_RSA_PSK_WITH_NULL_SHA256 : + case TLS_RSA_PSK_WITH_NULL_SHA384 : + case SSL_RSA_WITH_DES_CBC_MD5 : + break; + + /* RC4 cipher suites that should only be used as a last resort */ + case SSL_RSA_WITH_RC4_128_MD5 : + case SSL_RSA_WITH_RC4_128_SHA : + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA : + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : + case TLS_ECDH_RSA_WITH_RC4_128_SHA : + case TLS_ECDHE_RSA_WITH_RC4_128_SHA : + case TLS_PSK_WITH_RC4_128_SHA : + case TLS_DHE_PSK_WITH_RC4_128_SHA : + case TLS_RSA_PSK_WITH_RC4_128_SHA : + if (tls_options & _HTTP_TLS_ALLOW_RC4) + enabled[num_enabled ++] = supported[i]; + break; + + /* Anything else we'll assume is secure */ + default : + enabled[num_enabled ++] = supported[i]; + break; + } + } + + DEBUG_printf(("4_httpTLSStart: %d cipher suites enabled.", (int)num_enabled)); + error = SSLSetEnabledCiphers(http->tls, enabled, num_enabled); + } } +#endif /* USE_SET_ENABLED_CIPHERS */ if (!error && http->mode == _HTTP_MODE_CLIENT) { @@ -1309,6 +1428,8 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ * If an error string wasn't set by the callbacks use a generic one... */ + fprintf(stderr, "FAILED with code %d\n", (int)error); + if (!message) #ifdef HAVE_CSSMERRORSTRING message = cssmErrorString(error); diff --git a/cups/tls-gnutls.c b/cups/tls-gnutls.c index 0900f4fe3..3d08abcac 100644 --- a/cups/tls-gnutls.c +++ b/cups/tls-gnutls.c @@ -36,6 +36,7 @@ static char *tls_keypath = NULL; /* Server cert keychain path */ static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER; /* Mutex for keychain/certs */ +static int tls_options = 0;/* Options for TLS connections */ /* @@ -1001,6 +1002,17 @@ _httpTLSSetCredentials(http_t *http) /* I - Connection to server */ } +/* + * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options. + */ + +void +_httpTLSSetOptions(int options) /* I - Options */ +{ + tls_options = options; +} + + /* * '_httpTLSStart()' - Set up SSL/TLS support on a connection. */ @@ -1185,6 +1197,15 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ return (-1); } + if (!tls_options) + gnutls_priority_set_direct(http->tls, "NORMAL:-ARCFOUR-128:VERS-TLS-ALL:-VERS-SSL3.0", NULL); + else if ((tls_options & _HTTP_TLS_ALLOW_SSL3) && (tls_options & _HTTP_TLS_ALLOW_RC4)) + gnutls_priority_set_direct(http->tls, "NORMAL", NULL); + else if (tls_options & _HTTP_TLS_ALLOW_SSL3) + gnutls_priority_set_direct(http->tls, "NORMAL:-ARCFOUR-128:VERS-TLS-ALL", NULL); + else + gnutls_priority_set_direct(http->tls, "NORMAL:VERS-TLS-ALL:-VERS-SSL3.0", NULL); + gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr_t)http); gnutls_transport_set_pull_function(http->tls, http_gnutls_read); #ifdef HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION diff --git a/cups/tls-sspi.c b/cups/tls-sspi.c index 0911c683b..a9664e250 100644 --- a/cups/tls-sspi.c +++ b/cups/tls-sspi.c @@ -1,7 +1,8 @@ /* * "$Id$" * - * TLS support for CUPS on Windows using SSPI. + * TLS support for CUPS on Windows using the Security Support Provider + * Interface (SSPI). * * Copyright 2010-2014 by Apple Inc. * @@ -48,6 +49,14 @@ # define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID 0x00002000 /* Expired X509 Cert. */ #endif /* !SECURITY_FLAG_IGNORE_CERT_DATE_INVALID */ + +/* + * Local globals... + */ + +static int tls_options = 0;/* Options for TLS connections */ + + /* * Local functions... */ @@ -896,6 +905,17 @@ _httpTLSRead(http_t *http, /* I - HTTP connection */ } +/* + * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options. + */ + +void +_httpTLSSetOptions(int options) /* I - Options */ +{ + tls_options = options; +} + + /* * '_httpTLSStart()' - Set up SSL/TLS support on a connection. */ @@ -1727,11 +1747,25 @@ http_sspi_find_credentials( SchannelCred.paCred = &storedContext; /* - * SSPI doesn't seem to like it if grbitEnabledProtocols is set for a client. + * Set supported protocols (can also be overriden in the registry...) */ if (http->mode == _HTTP_MODE_SERVER) - SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1; + { + if (tls_options & _HTTP_TLS_ALLOW_SSL3) + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS_1_2_SERVER | SP_PROT_TLS_1_1_SERVER | SP_PROT_TLS_1_0_SERVER | SP_PROT_SSL3_SERVER; + else + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS_1_2_SERVER | SP_PROT_TLS_1_1_SERVER | SP_PROT_TLS_1_0_SERVER; + } + else + { + if (tls_options & _HTTP_TLS_ALLOW_SSL3) + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS_1_2_CLIENT | SP_PROT_TLS_1_1_CLIENT | SP_PROT_TLS_1_0_CLIENT | SP_PROT_SSL3_CLIENT; + else + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS_1_2_CLIENT | SP_PROT_TLS_1_1_CLIENT | SP_PROT_TLS_1_0_CLIENT; + } + + /* TODO: Support _HTTP_TLS_ALLOW_RC4 option; right now we'll rely on Windows registry to enable/disable RC4... */ /* * Create an SSPI credential. diff --git a/cups/usersys.c b/cups/usersys.c index b0568ddfc..ab5849f40 100644 --- a/cups/usersys.c +++ b/cups/usersys.c @@ -52,7 +52,8 @@ static void cups_read_client_conf(cups_file_t *fp, #endif /* HAVE_GSSAPI */ const char *cups_anyroot, const char *cups_expiredcerts, - const char *cups_validatecerts); + const char *cups_validatecerts, + int ssl_options); /* @@ -863,6 +864,30 @@ _cupsSetDefaults(void) if (cg->encryption == (http_encryption_t)-1 || !cg->server[0] || !cg->user[0] || !cg->ipp_port) { + /* + * Look for CUPS_SERVERROOT/client.conf... + */ + + snprintf(filename, sizeof(filename), "%s/client.conf", + cg->cups_serverroot); + fp = cupsFileOpen(filename, "r"); + + /* + * Read the configuration file and apply any environment variables; both + * functions handle NULL cups_file_t pointers... + */ + + cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user, +#ifdef HAVE_GSSAPI + cups_gssservicename, +#endif /* HAVE_GSSAPI */ + cups_anyroot, cups_expiredcerts, cups_validatecerts, 1); + cupsFileClose(fp); + + /* + * Then user defaults, if it is safe to do so... + */ + # ifdef HAVE_GETEUID if ((geteuid() == getuid() || !getuid()) && getegid() == getgid() && (home = getenv("HOME")) != NULL) # elif !defined(WIN32) @@ -877,32 +902,19 @@ _cupsSetDefaults(void) snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home); fp = cupsFileOpen(filename, "r"); - } - else - fp = NULL; - if (!fp) - { /* - * Look for CUPS_SERVERROOT/client.conf... + * Read the configuration file and apply any environment variables; both + * functions handle NULL cups_file_t pointers... */ - snprintf(filename, sizeof(filename), "%s/client.conf", - cg->cups_serverroot); - fp = cupsFileOpen(filename, "r"); - } - - /* - * Read the configuration file and apply any environment variables; both - * functions handle NULL cups_file_t pointers... - */ - - cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user, + cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user, #ifdef HAVE_GSSAPI - cups_gssservicename, + cups_gssservicename, #endif /* HAVE_GSSAPI */ - cups_anyroot, cups_expiredcerts, cups_validatecerts); - cupsFileClose(fp); + cups_anyroot, cups_expiredcerts, cups_validatecerts, 0); + cupsFileClose(fp); + } } } @@ -924,7 +936,8 @@ cups_read_client_conf( #endif /* HAVE_GSSAPI */ const char *cups_anyroot, /* I - CUPS_ANYROOT env var */ const char *cups_expiredcerts, /* I - CUPS_EXPIREDCERTS env var */ - const char *cups_validatecerts)/* I - CUPS_VALIDATECERTS env var */ + const char *cups_validatecerts,/* I - CUPS_VALIDATECERTS env var */ + int ssl_options) /* I - Allow setting of SSLOptions? */ { int linenum; /* Current line number */ char line[1024], /* Line from file */ @@ -996,6 +1009,43 @@ cups_read_client_conf( cups_gssservicename = gss_service_name; } #endif /* HAVE_GSSAPI */ + else if (ssl_options && !_cups_strcasecmp(line, "SSLOptions") && value) + { + /* + * SSLOptions [AllowRC4] [AllowSSL3] [None] + */ + + int options = 0; /* SSL/TLS options */ + char *start, /* Start of option */ + *end; /* End of option */ + + for (start = value; *start; start = end) + { + /* + * Find end of keyword... + */ + + end = start; + while (*end && !_cups_isspace(*end)) + end ++; + + if (*end) + *end++ = '\0'; + + /* + * Compare... + */ + + if (!_cups_strcasecmp(start, "AllowRC4")) + options |= _HTTP_TLS_ALLOW_RC4; + else if (!_cups_strcasecmp(start, "AllowSSL3")) + options |= _HTTP_TLS_ALLOW_SSL3; + else if (!_cups_strcasecmp(start, "None")) + options = 0; + } + + _httpTLSSetOptions(options); + } } /* diff --git a/doc/help/man-client.conf.html b/doc/help/man-client.conf.html index a25435927..06093fb77 100644 --- a/doc/help/man-client.conf.html +++ b/doc/help/man-client.conf.html @@ -38,6 +38,12 @@ CUPS adds the remote hostname ("name@server.example.com") for you. The default n Note: This directive it not supported on OS X 10.7 or later.
ServerName hostname-or-ip-address[:port]/version=1.1
Specifies the address and optionally the port to use when connecting to a server running CUPS 1.3.12 and earlier. +
SSLOptions [AllowRC4] [AllowSSL3] +
SSLOptions None +
Sets encryption options (only in /etc/cups/client.conf). +By default, CUPS only supports encryption using TLS v1.0 or higher using known secure cipher suites. +The AllowRC4 option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones. +The AllowSSL3 option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
User name
Specifies the default user name to use for requests.
ValidateCerts Yes diff --git a/doc/help/man-cupsd.conf.html b/doc/help/man-cupsd.conf.html index c627824a7..d6a927b6a 100644 --- a/doc/help/man-cupsd.conf.html +++ b/doc/help/man-cupsd.conf.html @@ -303,6 +303,12 @@ The default is "Minimal".
SSLListen [ipv6-address]:port
SSLListen *:port
Listens on the specified address and port for encrypted connections. +
SSLOptions [AllowRC4] [AllowSSL3] +
SSLOptions None +
Sets encryption options. +By default, CUPS only supports encryption using TLS v1.0 or higher using known secure cipher suites. +The AllowRC4 option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones. +The AllowSSL3 option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
SSLPort port
Listens on the specified port for encrypted connections.
StrictConformance Yes diff --git a/man/client.conf.man.in b/man/client.conf.man.in index 6d1a5a14e..a7eadbc1e 100644 --- a/man/client.conf.man.in +++ b/man/client.conf.man.in @@ -12,7 +12,7 @@ .\" which should have been included with this file. If this file is .\" file is missing or damaged, see the license at "http://www.cups.org/". .\" -.TH client.conf 5 "CUPS" "7 May 2014" "Apple Inc." +.TH client.conf 5 "CUPS" "20 October 2014" "Apple Inc." .SH NAME client.conf \- client configuration file for cups (deprecated) .SH DESCRIPTION @@ -56,6 +56,14 @@ Specifies the address and optionally the port to use when connecting to the serv \fBServerName \fIhostname-or-ip-address\fR[\fI:port\fR]\fB/version=1.1\fR Specifies the address and optionally the port to use when connecting to a server running CUPS 1.3.12 and earlier. .TP 5 +\fBSSLOptions \fR[\fIAllowRC4\fR] [\fIAllowSSL3\fR] +.TP 5 +\fBSSLOptions None\fR +Sets encryption options (only in /etc/cups/client.conf). +By default, CUPS only supports encryption using TLS v1.0 or higher using known secure cipher suites. +The \fIAllowRC4\fR option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones. +The \fIAllowSSL3\fR option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0. +.TP 5 \fBUser \fIname\fR Specifies the default user name to use for requests. .TP 5 diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in index 307f5dfa7..2d5ce6ad1 100644 --- a/man/cupsd.conf.man.in +++ b/man/cupsd.conf.man.in @@ -12,7 +12,7 @@ .\" which should have been included with this file. If this file is .\" file is missing or damaged, see the license at "http://www.cups.org/". .\" -.TH cupsd.conf 5 "CUPS" "28 July 2014" "Apple Inc." +.TH cupsd.conf 5 "CUPS" "20 October 2014" "Apple Inc." .SH NAME cupsd.conf \- server configuration file for cups .SH DESCRIPTION @@ -415,6 +415,14 @@ Set the specified environment variable to be passed to child processes. \fBSSLListen *:\fIport\fR Listens on the specified address and port for encrypted connections. .TP 5 +\fBSSLOptions \fR[\fIAllowRC4\fR] [\fIAllowSSL3\fR] +.TP 5 +\fBSSLOptions None\fR +Sets encryption options. +By default, CUPS only supports encryption using TLS v1.0 or higher using known secure cipher suites. +The \fIAllowRC4\fR option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones. +The \fIAllowSSL3\fR option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0. +.TP 5 \fBSSLPort \fIport\fR Listens on the specified port for encrypted connections. .TP 5 diff --git a/scheduler/conf.c b/scheduler/conf.c index f1e10204b..4b8f87e14 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -596,6 +596,8 @@ cupsdReadConfiguration(void) # else cupsdSetString(&ServerKeychain, "/Library/Keychains/System.keychain"); # endif /* HAVE_GNUTLS */ + + _httpTLSSetOptions(0); #endif /* HAVE_SSL */ language = cupsLangDefault(); @@ -2929,6 +2931,49 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ "FaxRetryLimit is deprecated; use " "JobRetryLimit on line %d.", linenum); } + else if (!_cups_strcasecmp(line, "SSLOptions")) + { + /* + * SSLOptions [AllowRC4] [AllowSSL3] [None] + */ + + int options = 0; /* SSL/TLS options */ + + if (value) + { + char *start, /* Start of option */ + *end; /* End of option */ + + for (start = value; *start; start = end) + { + /* + * Find end of keyword... + */ + + end = start; + while (*end && !_cups_isspace(*end)) + end ++; + + if (*end) + *end++ = '\0'; + + /* + * Compare... + */ + + if (!_cups_strcasecmp(start, "AllowRC4")) + options |= _HTTP_TLS_ALLOW_RC4; + else if (!_cups_strcasecmp(start, "AllowSSL3")) + options |= _HTTP_TLS_ALLOW_SSL3; + else if (!_cups_strcasecmp(start, "None")) + options = 0; + else if (_cups_strcasecmp(start, "NoEmptyFragments")) + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown SSL option %s at line %d.", start, linenum); + } + } + + _httpTLSSetOptions(options); + } else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen") #ifdef HAVE_SSL || !_cups_strcasecmp(line, "SSLPort") || !_cups_strcasecmp(line, "SSLListen") -- 2.39.2