Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CUPS needs a way to control the use of cipher suites and protocol versions #4476

Closed
michaelrsweet opened this issue Sep 2, 2014 · 16 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 1.4.2
CUPS.org User: alokispaney

Summary:
This routine search for weak SSL ciphers offered by a service.
Vulnerability Insight:
These rules are applied for the evaluation of the cryptographic strength:

  • Any SSL/TLS using no cipher is considered weak.
  • All SSLv2 ciphers are considered weak due to a design flaw within the SSLv2 pr
    ,!otocol.
  • RC4 is considered to be weak.
  • Ciphers using 64 bit or less are considered to be vulnerable to brute force me
    ,!thods
    and therefore considered as weak.
  • 1024 bit RSA authentication is considered to be insecure and therefore as weak
    ,!.
  • CBC ciphers in TLS < 1.2 are considered to be vulnerable to the BEAST or Lucky
    ,! 13 attacks
    . . . continues on next page . . .
    2 RESULTS PER HOST 35
    . . . continued from previous page . . .
  • Any cipher considered to be secure for only the next 10 years is considered as
    ,! medium
  • Any other cipher is considered as strong
    Solution:
    The configuration of this services should be changed so
    that it does not support the listed weak ciphers anymore.
    Weak ciphers offered by this service:
    SSL3_RSA_RC4_128_MD5
    SSL3_RSA_RC4_128_SHA
    TLS1_RSA_RC4_128_MD5
    TLS1_RSA_RC4_128_SHA

How to fix it in cups ?

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: alokispaney

I am using Centos 6 for running cups.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Changing the title; this is not a CUPS vulnerability per-se but an issue in the underlying TLS toolkits it uses. And quite frankly a set of cipher suites that is being deprecated by the TLS WG in the IETF and something that is typically a configuration option doesn't qualify as a general security vulnerability in a particular piece of software...

Since each toolkit provides different ways to override their default cipher suites, we have not yet exposed a configuration directive to configure the cipher suites. And unlike SSLv2 which we we able to disable across the board in CUPS 1.2 or so, RC4 remains the most secure algorithm available on older releases of Windows so at this point we are not comfortable disabling it by default without having a way to turn it back on...

Will use this bug to track the upstream changes in CUPS. In the meantime, I would contact your Linux distributor for assistance on getting a fix for CUPS 1.4.x.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: alokispaney

Please do let me know what details from system you are looking for to provide your assistance. I am the server owner with root privledge.
As cups do not provide config to configure this cipher suits..how its responding to sslv2 queris from network. Do you think upgrading openssl would be a fix.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Due to POODLE, I am bumping the priority of this bug to 4.

In addition to cipher suites, we need to allow disabling/enabling protocol versions.

Apache mod_ssl uses SSLCipherSuite and SSLProtocol directives for this; not sure if we want to use these with their syntax as-is, but that is the functionality required.

http://httpd.apache.org/docs/2.2/mod/mod_ssl.html

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Upon further thought and examination of the TLS APIs we are working with, we should just bring back the SSLOptions directive that was added in CUPS 1.4 and subsequently dropped in 2.0 in the TLS update.

Previously the only values were "None" and "NoEmptyFragments", the latter only being available/used for OpenSSL. New values will be "AllowRC4" and "AllowSSL3":

SSLOptions [option ... option]

The SSLOptions directive specifies additional SSL/TLS protocol options to use for encrypted connections. The default is "None" which provides the most secure mode supported by the operating system. Security can be relaxed using the "AllowRC4" and "AllowSSL3" options which allow negotiation of RC4 cipher suites and the SSL 3.0 protocol, respectively.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

The attached patch brings back the SSLOptions direct for cupsd.conf and adds it to client.conf (but just the system-wide one in /etc/cups). "AllowRC4" re-enables RC4 cipher suites, and "AllowSSL3" re-enabled SSL 3.0 support.

@michaelrsweet
Copy link
Collaborator Author

"str4476.patch":

Index: doc/help/man-client.conf.html

--- doc/help/man-client.conf.html (revision 12210)
+++ doc/help/man-client.conf.html (working copy)
@@ -38,6 +38,12 @@
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

Index: doc/help/man-cupsd.conf.html

--- doc/help/man-cupsd.conf.html (revision 12210)
+++ doc/help/man-cupsd.conf.html (working copy)
@@ -303,6 +303,12 @@

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

Index: cups/tls-sspi.c

--- cups/tls-sspi.c (revision 12210)
+++ cups/tls-sspi.c (working copy)
@@ -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,7 +49,15 @@

    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...
      */

@@ -897,6 +906,17 @@

/*

  • * '_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,12 +1747,44 @@
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...)
    */

+#ifdef SP_PROT_TLS1_2_SERVER
if (http->mode == _HTTP_MODE_SERVER)

  • SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1;
  • {
  • if (tls_options & _HTTP_TLS_ALLOW_SSL3)
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER | SP_PROT_SSL3_SERVER;
    
  • else
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER;
    
  • }
  • else
  • {
  • if (tls_options & _HTTP_TLS_ALLOW_SSL3)
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_SSL3_CLIENT;
    
  • else
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT;
    
  • }

+#else

  • if (http->mode == _HTTP_MODE_SERVER)
  • {
  • if (tls_options & _HTTP_TLS_ALLOW_SSL3)
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER;
    
  • else
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
    
  • }
  • else
  • {
  • if (tls_options & _HTTP_TLS_ALLOW_SSL3)
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT;
    
  • else
  •  SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
    
  • }
    +#endif /* SP_PROT_TLS1_2_SERVER */
  • /* TODO: Support _HTTP_TLS_ALLOW_RC4 option; right now we'll rely on Windows registry to enable/disable RC4... _/

/_

  • Create an SSPI credential.
    */
    Index: cups/tls-darwin.c

    --- cups/tls-darwin.c (revision 12210)
    +++ cups/tls-darwin.c (working copy)
    @@ -27,6 +27,14 @@

/*

  • * Test define - set to 1 to use SSLSetEnabledCiphers. Currently disabled (0)
  • * because of rdar://problem/18707430.
  • /
    +
    +#define USE_SET_ENABLED_CIPHERS 0
    +
    +
    +/
    • Local globals...
      */

@@ -41,6 +49,7 @@
/* 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 */

@@ -973,6 +982,17 @@

/*

  • * '_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,10 +1053,109 @@
{
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)
{
/

Index: cups/usersys.c

--- cups/usersys.c (revision 12210)
+++ cups/usersys.c (working copy)
@@ -52,7 +52,8 @@
#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 @@
    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 @@

 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 @@
#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_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);
    
  • }
    }

/*

Index: cups/tls-gnutls.c

--- cups/tls-gnutls.c (revision 12210)
+++ cups/tls-gnutls.c (working copy)
@@ -36,6 +36,7 @@
/* 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 */

/*
@@ -1002,6 +1003,17 @@

/*

  • * '_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 @@
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
Index: cups/http-private.h

--- cups/http-private.h (revision 12210)
+++ cups/http-private.h (working copy)
@@ -161,7 +161,10 @@
#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 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);

    Index: man/cupsd.conf.man.in

    --- man/cupsd.conf.man.in (revision 12210)
    +++ man/cupsd.conf.man.in (working copy)
    @@ -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 @@
    \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

    Index: man/client.conf.man.in

    --- man/client.conf.man.in (revision 12210)
    +++ man/client.conf.man.in (working copy)
    @@ -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 @@
    \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

    Index: scheduler/conf.c

    --- scheduler/conf.c (revision 12210)
    +++ scheduler/conf.c (working copy)
    @@ -596,6 +596,8 @@

    else

    cupsdSetString(&ServerKeychain, "/Library/Keychains/System.keychain");

    endif /* HAVE_GNUTLS */

    • _httpTLSSetOptions(0);
      #endif /* HAVE_SSL */

    language = cupsLangDefault();
    @@ -2929,6 +2931,49 @@
    "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")

@michaelrsweet
Copy link
Collaborator Author

"23-20231096.patch":

/-------------------------------------------------------------------------------------------------
This patch was developed in-house.
It is submitted upstream at https://www.cups.org/str.php?L4476+P-1+S0+C0+I0+E0+Q4476
---------------------------------------------------------------------------------------------------
/
--- scheduler/client.c 2015-03-06 03:28:52.100318608 -0800
+++ scheduler/client.c 2015-03-06 03:35:41.539740276 -0800
@@ -3258,7 +3258,7 @@

context = SSL_CTX_new(SSLv23_server_method());

  • SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
  • SSL_CTX_set_options(context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); /* Always disable SSLv2 & SSLv3 to "mitigate POODLE vulnerability". */
    if (SSLOptions & CUPSD_SSL_NOEMPTY)
    SSL_CTX_set_options(context, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
    SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM);
    --- cups/http.c 2015-03-06 03:27:05.266068026 -0800
    +++ cups/http.c 2015-03-06 03:34:22.981276422 -0800
    @@ -2972,7 +2972,7 @@

ifdef HAVE_LIBSSL

context = SSL_CTX_new(SSLv23_client_method());

  • SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
  • SSL_CTX_set_options(context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); /* Always disable SSLv2 & SSLv3 to "mitigate POODLE vulnerability". */

bio = BIO_new(_httpBIOMethods());
BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

+#define _HTTP_TLS_ALLOW_RC4 1 /* Allow RC4 cipher suites _/
+#define HTTP_TLS_ALLOW_SSL3 1 / Allow SSL 3.0 */

Should they be different values?

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Indeed, fixed in TOT.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

  • gnutls_priority_set_direct(http->tls, "NORMAL:VERS-TLS-ALL:-VERS-SSL3.0", NULL);

Also I think that should read "NORMAL:+VERS-TLS-ALL:-VERS-SSL3.0" (VERS-TLS-ALL needs a + in front), or even better: "NORMAL:-VERS-SSL3.0".

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

Shouldn't the "Upgrade" HTTP field contain "SSL/3.0" if _HTTP_TLS_ALLOW_SSL3 is set in tls_options? In which case, scheduler/conf.c will need to call _httpTLSSetOptions() to tell it what SSLOptions is, and we'll need to ensure _HTTP_TLS_ALLOW_SSL3==CUPSD_SSL_ALLOW_SSL3.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

SSL was never supported for HTTP Upgrade (only TLS 1.0 and higher).

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

So in older versions it was advertised in error? e.g. this change from 2012:

@@ -3690,7 +4714,7 @@ http_send(http_t http, / I - Connection to ser
ver */
if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
{
httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");

  • httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
  • httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0");
    }
    #endif /* HAVE_SSL */

Also, a usersys.c question: shouldn't cupsSetEncryption() also call _cupsSetDefaults() if the defaults haven't yet been set? i.e. something like:

@@ -257,6 +258,9 @@ cupsSetEncryption(http_encryption_t e) /
_cups_globals_t _cg = cupsGlobals(); / Pointer to library globals */

  • if (cg->encryption == (http_encryption_t)-1)
  • _cupsSetDefaults();

cg->encryption = e;

if (cg->http)

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Tim, older versions advertising SSL were an error. And since the defaults are set independently as needed (and if there is an issue there, please file a separate, new bug for it, thanks!) we should not need to set them in cupsSetEncryption, just in cupsEncryption (which gets the current value...)

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: panchami_sanjeev

This patch solves POODLE Vulnerability by disabling SSLv3 in CUPS. This fix is specific to solaris , which is using cups 1.4.5
The fix addresses the issue by disabling SSLv3
(i). In HTTP routines where we set up SSL/TLS support on a connection
(ii). In Client routines for the CUPS Scheduler where we create the SSL context and accept the connection when enabling encryption for the client.

Patch file is attached.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant