]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/conf.c
Add support for MinTLS and MaxTLS options (Issue #5119)
[thirdparty/cups.git] / scheduler / conf.c
index 8110cb475c1a639c6f991161e5adb933b2c98971..455646a1398a6be47c0c4bcd00eba52d53e5698d 100644 (file)
@@ -1,14 +1,14 @@
 /*
  * Configuration routines for the CUPS scheduler.
  *
- * Copyright 2007-2016 by Apple Inc.
+ * Copyright 2007-2017 by Apple Inc.
  * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  * These coded instructions, statements, and computer programs are the
  * property of Apple Inc. and are protected by Federal copyright
  * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
  * 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/".
+ * missing or damaged, see the license at "http://www.cups.org/".
  */
 
 /*
@@ -83,6 +83,9 @@ static const cupsd_var_t      cupsd_vars[] =
   { "DefaultPolicy",           &DefaultPolicy,         CUPSD_VARTYPE_STRING },
   { "DefaultShared",           &DefaultShared,         CUPSD_VARTYPE_BOOLEAN },
   { "DirtyCleanInterval",      &DirtyCleanInterval,    CUPSD_VARTYPE_TIME },
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+  { "DNSSDHostName",           &DNSSDHostName,         CUPSD_VARTYPE_STRING },
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
   { "ErrorPolicy",             &ErrorPolicy,           CUPSD_VARTYPE_STRING },
   { "FilterLimit",             &FilterLimit,           CUPSD_VARTYPE_INTEGER },
   { "FilterNice",              &FilterNice,            CUPSD_VARTYPE_INTEGER },
@@ -190,7 +193,7 @@ static void         mime_error_cb(void *ctx, const char *message);
 static int             parse_aaa(cupsd_location_t *loc, char *line,
                                  char *value, int linenum);
 static int             parse_fatal_errors(const char *s);
-static int             parse_groups(const char *s);
+static int             parse_groups(const char *s, int linenum);
 static int             parse_protocols(const char *s);
 static int             parse_variable(const char *filename, int linenum,
                                       const char *line, const char *value,
@@ -276,20 +279,11 @@ cupsdCheckPermissions(
                          "Unable to create directory \"%s\" - %s", filename,
                          strerror(errno));
         else
-#ifdef HAVE_ASL_H
-        {
-         asl_object_t  m;              /* Log message */
-
-         m = asl_new(ASL_TYPE_MSG);
-         asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-         asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
-         asl_release(m);
-       }
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
          sd_journal_print(LOG_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
 #else
          syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
         return (-1);
       }
@@ -326,20 +320,11 @@ cupsdCheckPermissions(
     if (create_dir >= 0)
       cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory.", filename);
     else
-#ifdef HAVE_ASL_H
-    {
-      asl_object_t     m;              /* Log message */
-
-      m = asl_new(ASL_TYPE_MSG);
-      asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-      asl_log(NULL, m, ASL_LEVEL_ERR, "\"%s\" is not a directory.", filename);
-      asl_release(m);
-    }
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
       sd_journal_print(LOG_ERR, "\"%s\" is not a directory.", filename);
 #else
       syslog(LOG_ERR, "\"%s\" is not a directory.", filename);
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
     return (-1);
   }
@@ -368,20 +353,11 @@ cupsdCheckPermissions(
                        "Unable to change ownership of \"%s\" - %s", filename,
                        strerror(errno));
       else
-#ifdef HAVE_ASL_H
-      {
-       asl_object_t    m;              /* Log message */
-
-       m = asl_new(ASL_TYPE_MSG);
-       asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-       asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
-       asl_release(m);
-      }
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
        sd_journal_print(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
 #else
        syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
       return (1);
     }
@@ -400,20 +376,11 @@ cupsdCheckPermissions(
                        "Unable to change permissions of \"%s\" - %s", filename,
                        strerror(errno));
       else
-#ifdef HAVE_ASL_H
-      {
-       asl_object_t    m;              /* Log message */
-
-       m = asl_new(ASL_TYPE_MSG);
-       asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-       asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
-       asl_release(m);
-      }
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
        sd_journal_print(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
 #else
        syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
       return (1);
     }
@@ -653,7 +620,7 @@ cupsdReadConfiguration(void)
   cupsdSetString(&ServerKeychain, "/Library/Keychains/System.keychain");
 #  endif /* HAVE_GNUTLS */
 
-  _httpTLSSetOptions(0);
+  _httpTLSSetOptions(_HTTP_TLS_NONE, _HTTP_TLS_1_0, _HTTP_TLS_MAX);
 #endif /* HAVE_SSL */
 
   language = cupsLangDefault();
@@ -782,6 +749,7 @@ cupsdReadConfiguration(void)
 
 #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
   cupsdSetString(&DNSSDSubTypes, "_cups,_print");
+  cupsdClearString(&DNSSDHostName);
 #endif /* HAVE_DNSSD || HAVE_AVAHI */
 
   cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE);
@@ -839,20 +807,11 @@ cupsdReadConfiguration(void)
       if (TestConfigFile)
         printf("\"%s\" contains errors.\n", CupsFilesFile);
       else
-#ifdef HAVE_ASL_H
-      {
-       asl_object_t    m;              /* Log message */
-
-       m = asl_new(ASL_TYPE_MSG);
-       asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-       asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
-       asl_release(m);
-      }
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
        sd_journal_print(LOG_ERR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
 #else
         syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
       return (0);
     }
@@ -861,19 +820,11 @@ cupsdReadConfiguration(void)
     cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile);
   else
   {
-#ifdef HAVE_ASL_H
-    asl_object_t       m;              /* Log message */
-
-    m = asl_new(ASL_TYPE_MSG);
-    asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-    asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
-    asl_release(m);
-
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
     sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
 #else
     syslog(LOG_LPR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
     return (0);
   }
@@ -887,18 +838,11 @@ cupsdReadConfiguration(void)
 
   if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL)
   {
-#ifdef HAVE_ASL_H
-    asl_object_t       m;              /* Log message */
-
-    m = asl_new(ASL_TYPE_MSG);
-    asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-    asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
-    asl_release(m);
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
     sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
 #else
     syslog(LOG_LPR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
     return (0);
   }
@@ -912,20 +856,11 @@ cupsdReadConfiguration(void)
     if (TestConfigFile)
       printf("\"%s\" contains errors.\n", ConfigurationFile);
     else
-#ifdef HAVE_ASL_H
-    {
-      asl_object_t     m;              /* Log message */
-
-      m = asl_new(ASL_TYPE_MSG);
-      asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
-      asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
-      asl_release(m);
-    }
-#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
       sd_journal_print(LOG_ERR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
 #else
       syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
-#endif /* HAVE_ASL_H */
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
     return (0);
   }
@@ -947,6 +882,7 @@ cupsdReadConfiguration(void)
     if (!ServerAlias)
       ServerAlias = cupsArrayNew(NULL, NULL);
 
+    cupsdAddAlias(ServerAlias, ServerName);
     cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", ServerName);
   }
   else
@@ -1022,7 +958,7 @@ cupsdReadConfiguration(void)
 
   if (NumSystemGroups == 0)
   {
-    if (!parse_groups(CUPS_DEFAULT_SYSTEM_GROUPS))
+    if (!parse_groups(CUPS_DEFAULT_SYSTEM_GROUPS, 0))
     {
      /*
       * Find the group associated with GID 0...
@@ -1071,19 +1007,6 @@ cupsdReadConfiguration(void)
     openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
 #endif /* HAVE_VSYSLOG && !HAVE_ASL_H && !HAVE_SYSTEMD_SD_JOURNAL_H */
 
- /*
-  * Make sure each of the log files exists and gets rotated as necessary...
-  */
-
-  if (strcmp(AccessLog, "syslog"))
-    cupsdCheckLogFile(&AccessFile, AccessLog);
-
-  if (strcmp(ErrorLog, "syslog"))
-    cupsdCheckLogFile(&ErrorFile, ErrorLog);
-
-  if (strcmp(PageLog, "syslog"))
-    cupsdCheckLogFile(&PageFile, PageLog);
-
  /*
   * Log the configuration file that was used...
   */
@@ -1181,10 +1104,12 @@ cupsdReadConfiguration(void)
     cupsdSetStringf(&CacheDir, "%s/%s", ServerRoot, CacheDir);
 
 #ifdef HAVE_SSL
-  if (ServerKeychain[0] != '/')
+  if (!_cups_strcasecmp(ServerKeychain, "internal"))
+    cupsdClearString(&ServerKeychain);
+  else if (ServerKeychain[0] != '/')
     cupsdSetStringf(&ServerKeychain, "%s/%s", ServerRoot, ServerKeychain);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "Using keychain \"%s\" for server name \"%s\".", ServerKeychain, ServerName);
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Using keychain \"%s\" for server name \"%s\".", ServerKeychain ? ServerKeychain : "internal", ServerName);
   if (!CreateSelfSignedCerts)
     cupsdLogMessage(CUPSD_LOG_DEBUG, "Self-signed TLS certificate generation is disabled.");
   cupsSetServerCredentials(ServerKeychain, ServerName, CreateSelfSignedCerts);
@@ -2313,7 +2238,6 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
       if (loc->level == CUPSD_AUTH_ANON)
        loc->level = CUPSD_AUTH_USER;
     }
-#ifdef HAVE_GSSAPI
     else if (!_cups_strcasecmp(value, "negotiate"))
     {
       loc->type = CUPSD_AUTH_NEGOTIATE;
@@ -2321,7 +2245,6 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
       if (loc->level == CUPSD_AUTH_ANON)
        loc->level = CUPSD_AUTH_USER;
     }
-#endif /* HAVE_GSSAPI */
     else
     {
       cupsdLogMessage(CUPSD_LOG_WARN,
@@ -2576,7 +2499,8 @@ parse_fatal_errors(const char *s) /* I - FatalErrors string */
  */
 
 static int                             /* O - 1 on success, 0 on failure */
-parse_groups(const char *s)            /* I - Space-delimited groups */
+parse_groups(const char *s,            /* I - Space-delimited groups */
+             int        linenum)        /* I - Line number in cups-files.conf */
 {
   int          status;                 /* Return status */
   char         value[1024],            /* Value string */
@@ -2632,7 +2556,14 @@ parse_groups(const char *s)              /* I - Space-delimited groups */
       NumSystemGroups ++;
     }
     else
+    {
+      if (linenum)
+        cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown SystemGroup \"%s\" on line %d of %s.", valstart, linenum, CupsFilesFile);
+      else
+        cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown default SystemGroup \"%s\".", valstart);
+
       status = 0;
+    }
 
     endgrent();
 
@@ -2957,7 +2888,7 @@ parse_variable(
        else
          snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
 
-       if (access(temp, 0))
+       if (access(temp, 0) && _cups_strcasecmp(value, "internal") && _cups_strcasecmp(line, "ServerKeychain"))
        {
          cupsdLogMessage(CUPSD_LOG_ERROR,
                          "File or directory for \"%s %s\" on line %d of %s "
@@ -3069,10 +3000,12 @@ read_cupsd_conf(cups_file_t *fp)        /* I - File to read from */
     else if (!_cups_strcasecmp(line, "SSLOptions"))
     {
      /*
-      * SSLOptions [AllowRC4] [AllowSSL3] [None]
+      * SSLOptions [AllowRC4] [AllowSSL3] [AllowDH] [DenyCBC] [DenyTLS1.0] [None]
       */
 
-      int      options = 0;            /* SSL/TLS options */
+      int      options = _HTTP_TLS_NONE,/* SSL/TLS options */
+               min_version = _HTTP_TLS_1_0,
+               max_version = _HTTP_TLS_MAX;
 
       if (value)
       {
@@ -3096,18 +3029,40 @@ read_cupsd_conf(cups_file_t *fp)        /* I - File to read from */
          * Compare...
          */
 
-          if (!_cups_strcasecmp(start, "AllowRC4"))
+         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, "AllowSSL3"))
+           min_version = _HTTP_TLS_SSL3;
+         else if (!_cups_strcasecmp(start, "AllowDH"))
+           options |= _HTTP_TLS_ALLOW_DH;
+         else if (!_cups_strcasecmp(start, "DenyCBC"))
+           options |= _HTTP_TLS_DENY_CBC;
+         else if (!_cups_strcasecmp(start, "DenyTLS1.0"))
+           min_version = _HTTP_TLS_1_1;
+         else if (!_cups_strcasecmp(start, "MaxTLS1.0"))
+           max_version = _HTTP_TLS_1_0;
+         else if (!_cups_strcasecmp(start, "MaxTLS1.1"))
+           max_version = _HTTP_TLS_1_1;
+         else if (!_cups_strcasecmp(start, "MaxTLS1.2"))
+           max_version = _HTTP_TLS_1_2;
+         else if (!_cups_strcasecmp(start, "MaxTLS1.3"))
+           max_version = _HTTP_TLS_1_3;
+         else if (!_cups_strcasecmp(start, "MinTLS1.0"))
+           min_version = _HTTP_TLS_1_0;
+         else if (!_cups_strcasecmp(start, "MinTLS1.1"))
+           min_version = _HTTP_TLS_1_1;
+         else if (!_cups_strcasecmp(start, "MinTLS1.2"))
+           min_version = _HTTP_TLS_1_2;
+         else if (!_cups_strcasecmp(start, "MinTLS1.3"))
+           min_version = _HTTP_TLS_1_3;
+         else if (!_cups_strcasecmp(start, "None"))
+           options = _HTTP_TLS_NONE;
          else if (_cups_strcasecmp(start, "NoEmptyFragments"))
            cupsdLogMessage(CUPSD_LOG_WARN, "Unknown SSL option %s at line %d.", start, linenum);
         }
       }
 
-      _httpTLSSetOptions(options);
+      _httpTLSSetOptions(options, min_version, max_version);
     }
 #endif /* HAVE_SSL */
     else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")
@@ -3255,10 +3210,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
        default_auth_type = CUPSD_AUTH_NONE;
       else if (!_cups_strcasecmp(value, "basic"))
        default_auth_type = CUPSD_AUTH_BASIC;
-#ifdef HAVE_GSSAPI
       else if (!_cups_strcasecmp(value, "negotiate"))
         default_auth_type = CUPSD_AUTH_NEGOTIATE;
-#endif /* HAVE_GSSAPI */
       else if (!_cups_strcasecmp(value, "auto"))
         default_auth_type = CUPSD_AUTH_AUTO;
       else
@@ -3400,7 +3353,7 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
        cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s %s; %s) IPP/2.1",
                        plat.sysname, plat.release, plat.machine);
       else if (!_cups_strcasecmp(value, "None"))
-       cupsdClearString(&ServerHeader);
+       cupsdSetString(&ServerHeader, "");
       else
        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d of %s.",
                         value, linenum, ConfigurationFile);
@@ -3625,11 +3578,8 @@ read_cups_files_conf(cups_file_t *fp)    /* I - File to read from */
       * SystemGroup (admin) group(s)...
       */
 
-      if (!parse_groups(value))
+      if (!parse_groups(value, linenum))
       {
-       cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unknown SystemGroup \"%s\" on line %d of %s.", value,
-                       linenum, CupsFilesFile);
         if (FatalErrors & CUPSD_FATAL_CONFIG)
           return (0);
       }