]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Implement SSLOptions in cupsd.conf and client.conf to allow admins to enable
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Mon, 20 Oct 2014 16:58:48 +0000 (16:58 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Mon, 20 Oct 2014 16:58:48 +0000 (16:58 +0000)
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
cups/http-private.h
cups/tls-darwin.c
cups/tls-gnutls.c
cups/tls-sspi.c
cups/usersys.c
doc/help/man-client.conf.html
doc/help/man-cupsd.conf.html
man/client.conf.man.in
man/cupsd.conf.man.in
scheduler/conf.c

index 956ada16fdfca72f24d8057f7da316999192be2f..e5b9bc757002ca5b71986617046814a34c2b1729 100644 (file)
@@ -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 (<rdar://problem/17903871>)
        - RPMs did not build (STR #4490)
 
index d7bdc8650a8e338a525bbce1919973501be1f6f4..7ef0833cd9c92c77a1034ec24dad28a33f88e24f 100644 (file)
@@ -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);
index 8d2cbb2627b07a4154445db7ddcf3e3591413246..f87294990cb3a856eda92afd2a1e1babeec43cdf 100644 (file)
 extern char **environ;
 
 
+/*
+ * 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 @@ 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);
index 0900f4fe3180e6a728306b8d11d6d196f48e36d9..3d08abcacd08ed9c7aae2dc7d29941f0ea76a401 100644 (file)
@@ -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
index 0911c683b2f899ed6e3e1f6a5e0c9573e70be609..a9664e25035e557d3b2e5517f9c4ce3fcb6ffb43 100644 (file)
@@ -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.
  *
 #  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.
index b0568ddfc295e4729ff4f820d55f44b0366c3fa0..ab5849f40e9d75f4e0ab3b334a1af40cbe48a476 100644 (file)
@@ -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);
+    }
   }
 
  /*
index a25435927cbec4879baf9efff5a80e137d804c1c..06093fb77a8adcb73484aa7c46512c833c0430ff 100644 (file)
@@ -38,6 +38,12 @@ CUPS adds the remote hostname ("name@server.example.com") for you. The default n
 <b>Note: This directive it not supported on OS X 10.7 or later.</b>
 <dt><b>ServerName </b><i>hostname-or-ip-address</i>[<i>:port</i>]<b>/version=1.1</b>
 <dd style="margin-left: 5.0em">Specifies the address and optionally the port to use when connecting to a server running CUPS 1.3.12 and earlier.
+<dt><b>SSLOptions </b>[<i>AllowRC4</i>] [<i>AllowSSL3</i>]
+<dd style="margin-left: 5.0em"><dt><b>SSLOptions None</b>
+<dd style="margin-left: 5.0em">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 <i>AllowRC4</i> option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones.
+The <i>AllowSSL3</i> option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
 <dt><b>User </b><i>name</i>
 <dd style="margin-left: 5.0em">Specifies the default user name to use for requests.
 <dt><b>ValidateCerts Yes</b>
index c627824a712097b3db2274b0c23091398e0c9707..d6a927b6aca996e624a1ee81af51d408c65ccf82 100644 (file)
@@ -303,6 +303,12 @@ The default is "Minimal".
 <dd style="margin-left: 5.0em"><dt><b>SSLListen [</b><i>ipv6-address</i><b>]:</b><i>port</i>
 <dd style="margin-left: 5.0em"><dt><b>SSLListen *:</b><i>port</i>
 <dd style="margin-left: 5.0em">Listens on the specified address and port for encrypted connections.
+<dt><b>SSLOptions </b>[<i>AllowRC4</i>] [<i>AllowSSL3</i>]
+<dd style="margin-left: 5.0em"><dt><b>SSLOptions None</b>
+<dd style="margin-left: 5.0em">Sets encryption options.
+By default, CUPS only supports encryption using TLS v1.0 or higher using known secure cipher suites.
+The <i>AllowRC4</i> option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones.
+The <i>AllowSSL3</i> option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
 <dt><b>SSLPort </b><i>port</i>
 <dd style="margin-left: 5.0em">Listens on the specified port for encrypted connections.
 <dt><b>StrictConformance Yes</b>
index 6d1a5a14e84cfc3108d4c5a0747849b148ac2bf6..a7eadbc1e337418fc4f850cd7641a0441e2aa836 100644 (file)
@@ -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
index 307f5dfa7588bc2c18e93fdf4337ce55f1a84ac5..2d5ce6ad1244c54c5ab33a64ac8993e073b03a53 100644 (file)
@@ -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
index f1e10204b7076cb1fc4c701233f84dc134e6022f..4b8f87e1419e1196bb54939eb5d0303527861276 100644 (file)
@@ -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")