]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/tls-gnutls.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / cups / tls-gnutls.c
index 23e3a8bc2b1f00e2716895eb2dbf5368eb1ea2ae..7193d79457c199ec11bd49b9209d8e781ac353fa 100644 (file)
@@ -8,7 +8,7 @@
  * 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/".
  *
  * This file is subject to the Apple OS-Developed Software exception.
  */
@@ -435,10 +435,16 @@ httpCredentialsGetTrust(
 
 
   if (!common_name)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No common name specified."), 1);
     return (HTTP_TRUST_UNKNOWN);
+  }
 
   if ((cert = http_gnutls_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create credentials from array."), 1);
     return (HTTP_TRUST_UNKNOWN);
+  }
 
   if (cg->any_root < 0)
   {
@@ -473,15 +479,28 @@ httpCredentialsGetTrust(
         * Do not trust certificates on first use...
        */
 
+        _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1);
+
         trust = HTTP_TRUST_INVALID;
       }
-      else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds) || !httpCredentialsAreValidForName(credentials, common_name))
+      else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds))
       {
        /*
-        * Either the new credentials are not newly issued, or the common name
-       * does not match the issued certificate...
+        * The new credentials are not newly issued...
        */
 
+        _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are older than stored credentials."), 1);
+
+        trust = HTTP_TRUST_INVALID;
+      }
+      else if (!httpCredentialsAreValidForName(credentials, common_name))
+      {
+       /*
+        * The common name does not match the issued certificate...
+       */
+
+        _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are not valid for name."), 1);
+
         trust = HTTP_TRUST_INVALID;
       }
       else if (httpCredentialsGetExpiration(tcreds) < time(NULL))
@@ -499,7 +518,53 @@ httpCredentialsGetTrust(
     httpFreeCredentials(tcreds);
   }
   else if (cg->validate_certs && !httpCredentialsAreValidForName(credentials, common_name))
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No stored credentials, not valid for name."), 1);
     trust = HTTP_TRUST_INVALID;
+  }
+  else if (!cg->trust_first)
+  {
+   /*
+    * See if we have a site CA certificate we can compare...
+    */
+
+    if (!httpLoadCredentials(NULL, &tcreds, "site"))
+    {
+      if (cupsArrayCount(credentials) != (cupsArrayCount(tcreds) + 1))
+      {
+       /*
+        * Certificate isn't directly generated from the CA cert...
+       */
+
+        trust = HTTP_TRUST_INVALID;
+      }
+      else
+      {
+       /*
+        * Do a tail comparison of the two certificates...
+       */
+
+        http_credential_t      *a, *b;         /* Certificates */
+
+        for (a = (http_credential_t *)cupsArrayFirst(tcreds), b = (http_credential_t *)cupsArrayIndex(credentials, 1);
+            a && b;
+            a = (http_credential_t *)cupsArrayNext(tcreds), b = (http_credential_t *)cupsArrayNext(credentials))
+         if (a->datalen != b->datalen || memcmp(a->data, b->data, a->datalen))
+           break;
+
+        if (a || b)
+         trust = HTTP_TRUST_INVALID;
+      }
+
+      if (trust != HTTP_TRUST_OK)
+       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials do not validate against site CA certificate."), 1);
+    }
+    else
+    {
+      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1);
+      trust = HTTP_TRUST_INVALID;
+    }
+  }
 
   if (trust == HTTP_TRUST_OK && !cg->expired_certs)
   {
@@ -508,11 +573,17 @@ httpCredentialsGetTrust(
     time(&curtime);
     if (curtime < gnutls_x509_crt_get_activation_time(cert) ||
         curtime > gnutls_x509_crt_get_expiration_time(cert))
+    {
+      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials have expired."), 1);
       trust = HTTP_TRUST_EXPIRED;
+    }
   }
 
   if (trust == HTTP_TRUST_OK && !cg->any_root && cupsArrayCount(credentials) == 1)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Self-signed credentials are blocked."), 1);
     trust = HTTP_TRUST_INVALID;
+  }
 
   gnutls_x509_crt_deinit(cert);
 
@@ -1300,34 +1371,46 @@ _httpTLSStart(http_t *http)             /* I - Connection to server */
     if (hostname[0])
     {
      /*
-      * First look for CA certs...
+      * First look in the CUPS keystore...
       */
 
-      snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostname);
-      snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostname);
-
-      if ((access(crtfile, R_OK) || access(keyfile, R_OK)) && (hostptr = strchr(hostname, '.')) != NULL)
-      {
-       /*
-        * Try just domain name...
-       */
-
-        hostptr ++;
-       if (strchr(hostptr, '.'))
-       {
-         snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
-         snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
-       }
-      }
+      http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, hostname, "crt");
+      http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, hostname, "key");
 
       if (access(crtfile, R_OK) || access(keyfile, R_OK))
       {
        /*
-        * Then look in the CUPS keystore...
-       */
-
-       http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, hostname, "crt");
-       http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, hostname, "key");
+        * No CUPS-managed certs, look for CA certs...
+        */
+
+        char cacrtfile[1024], cakeyfile[1024]; /* CA cert files */
+
+        snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostname);
+        snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostname);
+
+        if ((access(cacrtfile, R_OK) || access(cakeyfile, R_OK)) && (hostptr = strchr(hostname, '.')) != NULL)
+        {
+         /*
+          * Try just domain name...
+          */
+
+          hostptr ++;
+          if (strchr(hostptr, '.'))
+          {
+            snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
+            snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
+          }
+        }
+
+        if (!access(cacrtfile, R_OK) && !access(cakeyfile, R_OK))
+        {
+         /*
+          * Use the CA certs...
+          */
+
+          strlcpy(crtfile, cacrtfile, sizeof(crtfile));
+          strlcpy(keyfile, cakeyfile, sizeof(keyfile));
+        }
       }
 
       have_creds = !access(crtfile, R_OK) && !access(keyfile, R_OK);
@@ -1335,34 +1418,46 @@ _httpTLSStart(http_t *http)             /* I - Connection to server */
     else if (tls_common_name)
     {
      /*
-      * First look for CA certs...
+      * First look in the CUPS keystore...
       */
 
-      snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", tls_common_name);
-      snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", tls_common_name);
-
-      if ((access(crtfile, R_OK) || access(keyfile, R_OK)) && (hostptr = strchr(tls_common_name, '.')) != NULL)
-      {
-       /*
-        * Try just domain name...
-       */
-
-        hostptr ++;
-       if (strchr(hostptr, '.'))
-       {
-         snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
-         snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
-       }
-      }
+      http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, tls_common_name, "crt");
+      http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, tls_common_name, "key");
 
       if (access(crtfile, R_OK) || access(keyfile, R_OK))
       {
        /*
-        * Then look in the CUPS keystore...
-       */
-
-       http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, tls_common_name, "crt");
-       http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, tls_common_name, "key");
+        * No CUPS-managed certs, look for CA certs...
+        */
+
+        char cacrtfile[1024], cakeyfile[1024]; /* CA cert files */
+
+        snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", tls_common_name);
+        snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", tls_common_name);
+
+        if ((access(cacrtfile, R_OK) || access(cakeyfile, R_OK)) && (hostptr = strchr(tls_common_name, '.')) != NULL)
+        {
+         /*
+          * Try just domain name...
+          */
+
+          hostptr ++;
+          if (strchr(hostptr, '.'))
+          {
+            snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
+            snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
+          }
+        }
+
+        if (!access(cacrtfile, R_OK) && !access(cakeyfile, R_OK))
+        {
+         /*
+          * Use the CA certs...
+          */
+
+          strlcpy(crtfile, cacrtfile, sizeof(crtfile));
+          strlcpy(keyfile, cakeyfile, sizeof(keyfile));
+        }
       }
 
       have_creds = !access(crtfile, R_OK) && !access(keyfile, R_OK);