]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/client.c
Merge changes from CUPS 1.6svn-r9968.
[thirdparty/cups.git] / scheduler / client.c
index f6a446195780de515614224f81426db10de7ea77..c8995916a539a6a7df52d79b040823776e6f8457 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Client routines for the CUPS scheduler.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   This file contains Kerberos support code, copyright 2006 by
  *
  * Contents:
  *
- *   cupsdAcceptClient()    - Accept a new client.
- *   cupsdCloseAllClients() - Close all remote clients immediately.
- *   cupsdCloseClient()     - Close a remote client.
- *   cupsdFlushHeader()     - Flush the header fields to the client.
- *   cupsdReadClient()      - Read data from a client.
- *   cupsdSendCommand()     - Send output from a command via HTTP.
- *   cupsdSendError()       - Send an error message via HTTP.
- *   cupsdSendHeader()      - Send an HTTP request.
- *   cupsdUpdateCGI()       - Read status messages from CGI scripts and
- *                            programs.
- *   cupsdWriteClient()     - Write data to a client as needed.
- *   check_if_modified()    - Decode an "If-Modified-Since" line.
- *   compare_clients()      - Compare two client connections.
- *   data_ready()           - Check whether data is available from a client.
- *   encrypt_client()       - Enable encryption for the client...
- *   get_cdsa_certificate() - Get a SSL/TLS certificate from the System
- *                            keychain.
- *   get_file()             - Get a filename and state info.
- *   install_conf_file()    - Install a configuration file.
- *   is_cgi()               - Is the resource a CGI script/program?
- *   is_path_absolute()     - Is a path absolute and free of relative elements
- *                            (i.e. "..").
- *   make_certificate()     - Make a self-signed SSL/TLS certificate.
- *   pipe_command()         - Pipe the output of a command to the remote client.
- *   valid_host()           - Is the Host: field valid?
- *   write_file()           - Send a file via HTTP.
- *   write_pipe()           - Flag that data is available on the CGI pipe.
+ *   cupsdAcceptClient()     - Accept a new client.
+ *   cupsdCloseAllClients()  - Close all remote clients immediately.
+ *   cupsdCloseClient()      - Close a remote client.
+ *   cupsdFlushHeader()      - Flush the header fields to the client.
+ *   cupsdReadClient()       - Read data from a client.
+ *   cupsdSendCommand()      - Send output from a command via HTTP.
+ *   cupsdSendError()        - Send an error message via HTTP.
+ *   cupsdSendHeader()       - Send an HTTP request.
+ *   cupsdUpdateCGI()        - Read status messages from CGI scripts and
+ *                             programs.
+ *   cupsdWriteClient()      - Write data to a client as needed.
+ *   check_if_modified()     - Decode an "If-Modified-Since" line.
+ *   compare_clients()       - Compare two client connections.
+ *   copy_cdsa_certificate() - Copy a SSL/TLS certificate from the System
+ *                             keychain.
+ *   data_ready()            - Check whether data is available from a client.
+ *   encrypt_client()        - Enable encryption for the client...
+ *   get_file()              - Get a filename and state info.
+ *   install_conf_file()     - Install a configuration file.
+ *   is_cgi()                - Is the resource a CGI script/program?
+ *   is_path_absolute()      - Is a path absolute and free of relative elements
+ *                             (i.e. "..").
+ *   make_certificate()      - Make a self-signed SSL/TLS certificate.
+ *   pipe_command()          - Pipe the output of a command to the remote
+ *                             client.
+ *   valid_host()            - Is the Host: field valid?
+ *   write_file()            - Send a file via HTTP.
+ *   write_pipe()            - Flag that data is available on the CGI pipe.
  */
 
 /*
 #endif /* HAVE_TCPD_H */
 
 
+/*
+ * Local globals...
+ */
+
+static const char      * const http_states[] =
+                       {               /* HTTP state strings */
+                         "HTTP_WAITING",
+                         "HTTP_OPTIONS",
+                         "HTTP_GET",
+                         "HTTP_GET_SEND",
+                         "HTTP_HEAD",
+                         "HTTP_POST",
+                         "HTTP_POST_RECV",
+                         "HTTP_POST_SEND",
+                         "HTTP_PUT",
+                         "HTTP_PUT_RECV",
+                         "HTTP_DELETE",
+                         "HTTP_TRACE",
+                         "HTTP_CLOSE",
+                         "HTTP_STATUS"
+                       };
+static const char      * const ipp_states[] =
+                       {               /* IPP state strings */
+                         "IPP_IDLE",
+                         "IPP_HEADER",
+                         "IPP_ATTRIBUTE",
+                         "IPP_DATA"
+                       };
+
+
 /*
  * Local functions...
  */
@@ -65,13 +96,13 @@ static int          check_if_modified(cupsd_client_t *con,
                                          struct stat *filestats);
 static int             compare_clients(cupsd_client_t *a, cupsd_client_t *b,
                                        void *data);
+#ifdef HAVE_CDSASSL
+static CFArrayRef      copy_cdsa_certificate(cupsd_client_t *con);
+#endif /* HAVE_CDSASSL */
 static int             data_ready(cupsd_client_t *con);
 #ifdef HAVE_SSL
 static int             encrypt_client(cupsd_client_t *con);
 #endif /* HAVE_SSL */
-#ifdef HAVE_CDSASSL
-static CFArrayRef      get_cdsa_certificate(cupsd_client_t *con);
-#endif /* HAVE_CDSASSL */
 static char            *get_file(cupsd_client_t *con, struct stat *filestats,
                                  char *filename, int len);
 static http_status_t   install_conf_file(cupsd_client_t *con);
@@ -156,9 +187,10 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
     return;
   }
 
-  con->http.activity = time(NULL);
-  con->file          = -1;
-  con->http.hostaddr = &(con->clientaddr);
+  con->http.activity   = time(NULL);
+  con->file            = -1;
+  con->http.hostaddr   = &(con->clientaddr);
+  con->http.wait_value = 10000;
 
  /*
   * Accept the client and get the remote address...
@@ -179,29 +211,24 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
     return;
   }
 
-#ifdef AF_INET6
-  if (lis->address.addr.sa_family == AF_INET6)
-  {
-   /*
-    * Save the connected port number...
-    */
+ /*
+  * Save the connected port number...
+  */
 
-    con->http.hostaddr->ipv6.sin6_port = lis->address.ipv6.sin6_port;
+  _httpAddrSetPort(con->http.hostaddr, _httpAddrPort(&(lis->address)));
 
-   /*
-    * Convert IPv4 over IPv6 addresses (::ffff:n.n.n.n) to IPv4 forms we
-    * can more easily use...
-    */
+#ifdef AF_INET6
+ /*
+  * Convert IPv4 over IPv6 addresses (::ffff:n.n.n.n) to IPv4 forms we
+  * can more easily use...
+  */
 
-    if (con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0] == 0 &&
-        con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1] == 0 &&
-        ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]) == 0xffff)
-      con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2] = 0;
-  }
-  else
+  if (lis->address.addr.sa_family == AF_INET6 &&
+      con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0] == 0 &&
+      con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1] == 0 &&
+      ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]) == 0xffff)
+    con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2] = 0;
 #endif /* AF_INET6 */
-  if (lis->address.addr.sa_family == AF_INET)
-    con->http.hostaddr->ipv4.sin_port = lis->address.ipv4.sin_port;
 
  /*
   * Check the number of clients on the same address...
@@ -357,22 +384,16 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
   }
 #endif /* HAVE_TCPD_H */
 
-#ifdef AF_INET6
-  if (con->http.hostaddr->addr.sa_family == AF_INET6)
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv6)",
-                    con->http.fd, con->http.hostname,
-                   ntohs(con->http.hostaddr->ipv6.sin6_port));
-  else
-#endif /* AF_INET6 */
 #ifdef AF_LOCAL
   if (con->http.hostaddr->addr.sa_family == AF_LOCAL)
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s (Domain)",
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s (Domain)",
                     con->http.fd, con->http.hostname);
   else
 #endif /* AF_LOCAL */
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv4)",
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s:%d (IPv%d)",
                   con->http.fd, con->http.hostname,
-                 ntohs(con->http.hostaddr->ipv4.sin_port));
+                 _httpAddrPort(con->http.hostaddr),
+                 _httpAddrFamily(con->http.hostaddr) == AF_INET ? 4 : 6);
 
  /*
   * Get the local address the client connected to...
@@ -387,38 +408,23 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
     strcpy(con->servername, "localhost");
     con->serverport = LocalPort;
   }
+#ifdef AF_LOCAL
+  else if (_httpAddrFamily(&temp) == AF_LOCAL)
+  {
+    strcpy(con->servername, "localhost");
+    con->serverport = LocalPort;
+  }
+#endif /* AF_LOCAL */
   else
   {
-#ifdef AF_INET6
-    if (temp.addr.sa_family == AF_INET6)
-    {
-      if (httpAddrLocalhost(&temp))
-        strlcpy(con->servername, "localhost", sizeof(con->servername));
-      else if (HostNameLookups || RemotePort)
-        httpAddrLookup(&temp, con->servername, sizeof(con->servername));
-      else
-        httpAddrString(&temp, con->servername, sizeof(con->servername));
-
-      con->serverport = ntohs(lis->address.ipv6.sin6_port);
-    }
+    if (httpAddrLocalhost(&temp))
+      strlcpy(con->servername, "localhost", sizeof(con->servername));
+    else if (HostNameLookups || RemotePort)
+      httpAddrLookup(&temp, con->servername, sizeof(con->servername));
     else
-#endif /* AF_INET6 */
-    if (temp.addr.sa_family == AF_INET)
-    {
-      if (httpAddrLocalhost(&temp))
-        strlcpy(con->servername, "localhost", sizeof(con->servername));
-      else if (HostNameLookups || RemotePort)
-        httpAddrLookup(&temp, con->servername, sizeof(con->servername));
-      else
-        httpAddrString(&temp, con->servername, sizeof(con->servername));
+      httpAddrString(&temp, con->servername, sizeof(con->servername));
 
-      con->serverport = ntohs(lis->address.ipv4.sin_port);
-    }
-    else
-    {
-      strcpy(con->servername, "localhost");
-      con->serverport = LocalPort;
-    }
+    con->serverport = _httpAddrPort(&(lis->address));
   }
 
   cupsArrayAdd(Clients, con);
@@ -513,7 +519,8 @@ cupsdCloseClient(cupsd_client_t *con)       /* I - Client to close */
 #endif /* HAVE_LIBSSL */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdCloseClient: %d", con->http.fd);
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Closing connection.",
+                  con->http.fd);
 
  /*
   * Flush pending writes before closing...
@@ -743,18 +750,22 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
   status = HTTP_CONTINUE;
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                 "cupsdReadClient(con=%p(%d)) "
-                 "con->http.error=%d "
-                 "con->http.used=%d, "
-                 "con->http.state=%d "
-                 "con->data_encoding=HTTP_ENCODE_%s, "
-                 "con->data_remaining=" CUPS_LLFMT ", "
-                 "con->file=%d",
-                 con, con->http.fd, con->http.error, con->http.used,
-                 con->http.state,
+                 "[Client %d] cupsdReadClient "
+                 "error=%d, "
+                 "used=%d, "
+                 "state=%s, "
+                 "data_encoding=HTTP_ENCODE_%s, "
+                 "data_remaining=" CUPS_LLFMT ", "
+                 "request=%p(%s), "
+                 "file=%d",
+                 con->http.fd, con->http.error, con->http.used,
+                 http_states[con->http.state],
                  con->http.data_encoding == HTTP_ENCODE_CHUNKED ?
                      "CHUNKED" : "LENGTH",
-                 CUPS_LLCAST con->http.data_remaining, con->file);
+                 CUPS_LLCAST con->http.data_remaining,
+                 con->request,
+                 con->request ? ipp_states[con->request->state] : "",
+                 con->file);
 
 #ifdef HAVE_SSL
   if (con->auto_ssl)
@@ -773,8 +784,8 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
       */
 
       cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                      "cupsdReadClient: Saw first byte %02X, auto-negotiating "
-                     "SSL/TLS session...", buf[0] & 255);
+                      "[Client %d] Saw first byte %02X, auto-negotiating "
+                     "SSL/TLS session.", con->http.fd, buf[0] & 255);
 
       if (!encrypt_client(con))
         cupsdCloseClient(con);
@@ -795,12 +806,12 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
        {
          if (con->http.error && con->http.error != EPIPE)
            cupsdLogMessage(CUPSD_LOG_DEBUG,
-                           "cupsdReadClient: %d WAITING Closing for error %d "
+                           "[Client %d] HTTP_WAITING Closing for error %d "
                            "(%s)", con->http.fd, con->http.error,
                            strerror(con->http.error));
          else
            cupsdLogMessage(CUPSD_LOG_DEBUG,
-                           "cupsdReadClient: %d WAITING Closing on EOF",
+                           "[Client %d] HTTP_WAITING Closing on EOF",
                            con->http.fd);
 
          cupsdCloseClient(con);
@@ -859,12 +870,7 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
 
 #ifdef HAVE_GSSAPI
         con->have_gss = 0;
-
-       if (con->gss_creds)
-       {
-         OM_uint32 minor_status;
-         gss_release_cred(&minor_status, &con->gss_creds);
-       }
+       con->gss_uid  = 0;
 #endif /* HAVE_GSSAPI */
 
        /*
@@ -877,7 +883,9 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
              if (line[0])
              {
                cupsdLogMessage(CUPSD_LOG_ERROR,
-                               "Bad request line \"%s\" from %s!", line,
+                               "[Client %d] Bad request line \"%s\" from %s.",
+                               con->http.fd,
+                               _httpEncodeURI(buf, line, sizeof(buf)),
                                con->http.hostname);
                cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
                cupsdCloseClient(con);
@@ -890,7 +898,9 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
              if (sscanf(version, "HTTP/%d.%d", &major, &minor) != 2)
              {
                cupsdLogMessage(CUPSD_LOG_ERROR,
-                               "Bad request line \"%s\" from %s!", line,
+                               "[Client %d] Bad request line \"%s\" from %s.",
+                               con->http.fd,
+                               _httpEncodeURI(buf, line, sizeof(buf)),
                                con->http.hostname);
                cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
                cupsdCloseClient(con);
@@ -908,8 +918,10 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
              else
              {
                cupsdLogMessage(CUPSD_LOG_ERROR,
-                               "Unsupported request line \"%s\" from %s!",
-                               line, con->http.hostname);
+                               "[Client %d] Unsupported request line \"%s\" "
+                               "from %s.", con->http.fd,
+                               _httpEncodeURI(buf, line, sizeof(buf)),
+                               con->http.hostname);
                cupsdSendError(con, HTTP_NOT_SUPPORTED, CUPSD_AUTH_NONE);
                cupsdCloseClient(con);
                return;
@@ -946,16 +958,17 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
          */
 
          if (strcmp(scheme, "file") &&
-             strcasecmp(hostname, ServerName) &&
-             strcasecmp(hostname, "localhost") &&
+             _cups_strcasecmp(hostname, ServerName) &&
+             _cups_strcasecmp(hostname, "localhost") &&
              !isdigit(hostname[0]) && hostname[0] != '[')
          {
           /*
            * Nope, we don't do proxies...
            */
 
-           cupsdLogMessage(CUPSD_LOG_ERROR, "Bad URI \"%s\" in request!",
-                           con->uri);
+           cupsdLogMessage(CUPSD_LOG_ERROR,
+                           "[Client %d] Bad URI \"%s\" in request.",
+                           con->http.fd, con->uri);
            cupsdSendError(con, HTTP_METHOD_NOT_ALLOWED, CUPSD_AUTH_NONE);
            cupsdCloseClient(con);
            return;
@@ -989,7 +1002,9 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
          con->http.state = HTTP_HEAD;
        else
        {
-         cupsdLogMessage(CUPSD_LOG_ERROR, "Bad operation \"%s\"!", operation);
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "[Client %d] Bad operation \"%s\".", con->http.fd,
+                         operation);
          cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
          cupsdCloseClient(con);
          return;
@@ -998,7 +1013,7 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
         gettimeofday(&(con->start), NULL);
         con->operation = con->http.state;
 
-        cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %s %s HTTP/%d.%d",
+        cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] %s %s HTTP/%d.%d",
                        con->http.fd, operation, con->uri,
                        con->http.version / 100, con->http.version % 100);
 
@@ -1029,13 +1044,14 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
        {
          if (con->http.error && con->http.error != EPIPE)
            cupsdLogMessage(CUPSD_LOG_DEBUG,
-                           "cupsdReadClient: %d FIELDS Closing for error %d "
-                           "(%s)", con->http.fd, con->http.error,
+                           "[Client %d] Closing for error %d (%s) while "
+                           "reading headers.",
+                           con->http.fd, con->http.error,
                            strerror(con->http.error));
          else
            cupsdLogMessage(CUPSD_LOG_DEBUG,
-                           "cupsdReadClient: %d FIELDS Closing on EOF",
-                           con->http.fd);
+                           "[Client %d] Closing on EOF while reading headers.",
+                           con->http.fd);
 
          cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
          cupsdCloseClient(con);
@@ -1051,7 +1067,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
          */
 
          cupsdLogMessage(CUPSD_LOG_DEBUG,
-                         "cupsdReadClient: %d Closing on EOF", con->http.fd);
+                         "[Client %d] Closing on EOF", con->http.fd);
           cupsdCloseClient(con);
          return;
        }
@@ -1104,10 +1120,11 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
 
     cupsdAuthorize(con);
 
-    if (!strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Keep-Alive",
-                    10) && KeepAlive)
+    if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+                           "Keep-Alive", 10) && KeepAlive)
       con->http.keep_alive = HTTP_KEEPALIVE_ON;
-    else if (!strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "close", 5))
+    else if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+                                "close", 5))
       con->http.keep_alive = HTTP_KEEPALIVE_OFF;
 
     if (!con->http.fields[HTTP_FIELD_HOST][0] &&
@@ -1119,7 +1136,9 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
 
       if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
       {
-        cupsdLogMessage(CUPSD_LOG_ERROR, "Missing Host: field in request!");
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                        "[Client %d] Missing Host: field in request.",
+                        con->http.fd);
        cupsdCloseClient(con);
        return;
       }
@@ -1132,8 +1151,9 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
       */
 
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Request from \"%s\" using invalid Host: field \"%s\"",
-                     con->http.hostname, con->http.fields[HTTP_FIELD_HOST]);
+                      "[Client %d] Request from \"%s\" using invalid Host: "
+                      "field \"%s\"", con->http.fd, con->http.hostname,
+                      con->http.fields[HTTP_FIELD_HOST]);
 
       if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
       {
@@ -1156,7 +1176,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
        }
       }
 
-      if (!strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") &&
+      if (!_cups_strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") &&
          con->http.tls == NULL)
       {
 #ifdef HAVE_SSL
@@ -1218,7 +1238,8 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
       */
 
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Request for non-absolute resource \"%s\"!", con->uri);
+                      "[Client %d] Request for non-absolute resource \"%s\".",
+                      con->http.fd, con->uri);
 
       if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
       {
@@ -1228,15 +1249,16 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
     }
     else
     {
-      if (!strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") &&
-         con->http.tls == NULL)
+      if (!_cups_strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+                            "Upgrade") && con->http.tls == NULL)
       {
 #ifdef HAVE_SSL
        /*
         * Do encryption stuff...
        */
 
-       if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
+       if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL,
+                            CUPSD_AUTH_NONE))
        {
          cupsdCloseClient(con);
          return;
@@ -1368,14 +1390,28 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
                break;
              }
            }
+           else if (!WebInterface)
+           {
+            /*
+             * Web interface is disabled. Show an appropriate message...
+             */
+
+             if (!cupsdSendError(con, HTTP_WEBIF_DISABLED, CUPSD_AUTH_NONE))
+             {
+               cupsdCloseClient(con);
+               return;
+             }
+
+             break;
+           }
 
            if ((!strncmp(con->uri, "/admin", 6) &&
-                strncmp(con->uri, "/admin/conf/", 12) &&
-                strncmp(con->uri, "/admin/log/", 11)) ||
-               !strncmp(con->uri, "/printers", 9) ||
-               !strncmp(con->uri, "/classes", 8) ||
-               !strncmp(con->uri, "/help", 5) ||
-               !strncmp(con->uri, "/jobs", 5))
+                 strncmp(con->uri, "/admin/conf/", 12) &&
+                 strncmp(con->uri, "/admin/log/", 11)) ||
+                !strncmp(con->uri, "/printers", 9) ||
+                !strncmp(con->uri, "/classes", 8) ||
+                !strncmp(con->uri, "/help", 5) ||
+                !strncmp(con->uri, "/jobs", 5))
            {
             /*
              * Send CGI output...
@@ -1580,6 +1616,20 @@ cupsdReadClient(cupsd_client_t *con)     /* I - Client to read from */
            if (!strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE],
                        "application/ipp"))
               con->request = ippNew();
+            else if (!WebInterface)
+           {
+            /*
+             * Web interface is disabled. Show an appropriate message...
+             */
+
+             if (!cupsdSendError(con, HTTP_WEBIF_DISABLED, CUPSD_AUTH_NONE))
+             {
+               cupsdCloseClient(con);
+               return;
+             }
+
+             break;
+           }
            else if ((!strncmp(con->uri, "/admin", 6) &&
                      strncmp(con->uri, "/admin/conf/", 12) &&
                      strncmp(con->uri, "/admin/log/", 11)) ||
@@ -1693,7 +1743,8 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              */
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Request for subdirectory \"%s\"!", con->uri);
+                             "[Client %d] Request for subdirectory \"%s\".",
+                             con->http.fd, con->uri);
 
              if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
              {
@@ -1751,8 +1802,9 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            if (con->file < 0)
            {
              cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Unable to create request file %s: %s",
-                             con->filename, strerror(errno));
+                             "[Client %d] Unable to create request file "
+                             "\"%s\": %s", con->http.fd, con->filename,
+                             strerror(errno));
 
              if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
              {
@@ -1796,6 +1848,52 @@ cupsdReadClient(cupsd_client_t *con)     /* I - Client to read from */
                break;
              }
            }
+            else if (!strncmp(con->uri, "/printers/", 10) &&
+                    !strcmp(con->uri + strlen(con->uri) - 4, ".png"))
+           {
+            /*
+             * Send PNG file - get the real printer name since printer
+             * names are not case sensitive but filenames can be...
+             */
+
+              con->uri[strlen(con->uri) - 4] = '\0';   /* Drop ".ppd" */
+
+              if ((p = cupsdFindPrinter(con->uri + 10)) != NULL)
+               snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name);
+             else
+             {
+               if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+               {
+                 cupsdCloseClient(con);
+                 return;
+               }
+
+               break;
+             }
+           }
+           else if (!WebInterface)
+           {
+              if (!cupsdSendHeader(con, HTTP_OK, line, CUPSD_AUTH_NONE))
+             {
+               cupsdCloseClient(con);
+               return;
+             }
+
+             if (httpPrintf(HTTP(con), "\r\n") < 0)
+             {
+               cupsdCloseClient(con);
+               return;
+             }
+
+             if (cupsdFlushHeader(con) < 0)
+             {
+               cupsdCloseClient(con);
+               return;
+             }
+
+             con->http.state = HTTP_WAITING;
+             break;
+           }
 
            if ((!strncmp(con->uri, "/admin", 6) &&
                 strncmp(con->uri, "/admin/conf/", 12) &&
@@ -1842,7 +1940,8 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              */
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Request for subdirectory \"%s\"!", con->uri);
+                             "[Client %d] Request for subdirectory \"%s\".",
+                             con->http.fd, con->uri);
 
              if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
              {
@@ -1943,12 +2042,12 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
          {
            if (con->http.error && con->http.error != EPIPE)
              cupsdLogMessage(CUPSD_LOG_DEBUG,
-                             "cupsdReadClient: %d PUT_RECV Closing for error "
+                             "[Client %d] HTTP_PUT_RECV Closing for error "
                              "%d (%s)", con->http.fd, con->http.error,
                              strerror(con->http.error));
            else
              cupsdLogMessage(CUPSD_LOG_DEBUG,
-                             "cupsdReadClient: %d PUT_RECV Closing on EOF",
+                             "[Client %d] HTTP_PUT_RECV Closing on EOF",
                              con->http.fd);
 
            cupsdCloseClient(con);
@@ -1961,8 +2060,9 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
             if (write(con->file, line, bytes) < bytes)
            {
               cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdReadClient: Unable to write %d bytes to %s: %s",
-                             bytes, con->filename, strerror(errno));
+                             "[Client %d] Unable to write %d bytes to "
+                             "\"%s\": %s", con->http.fd, bytes, con->filename,
+                             strerror(errno));
 
              close(con->file);
              con->file = -1;
@@ -2037,8 +2137,8 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR)
            {
               cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdReadClient: %d IPP Read Error!",
-                             con->http.fd);
+                              "[Client %d] IPP read error: %s", con->http.fd,
+                              cupsLastErrorString());
 
              cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
              cupsdCloseClient(con);
@@ -2057,7 +2157,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
             }
            else
            {
-             cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %d.%d %s %d",
+             cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] %d.%d %s %d",
                              con->http.fd, con->request->request.op.version[0],
                              con->request->request.op.version[1],
                              ippOpString(con->request->request.op.operation_id),
@@ -2079,8 +2179,9 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            if (con->file < 0)
            {
              cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Unable to create request file %s: %s",
-                             con->filename, strerror(errno));
+                             "[Client %d] Unable to create request file "
+                             "\"%s\": %s", con->http.fd, con->filename,
+                             strerror(errno));
 
              if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
              {
@@ -2100,12 +2201,12 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
            {
              if (con->http.error && con->http.error != EPIPE)
                cupsdLogMessage(CUPSD_LOG_DEBUG,
-                               "cupsdReadClient: %d POST_SEND Closing for "
+                               "[Client %d] HTTP_POST_SEND Closing for "
                                "error %d (%s)", con->http.fd, con->http.error,
                                strerror(con->http.error));
              else
                cupsdLogMessage(CUPSD_LOG_DEBUG,
-                               "cupsdReadClient: %d POST_SEND Closing on EOF",
+                               "[Client %d] HTTP_POST_SEND Closing on EOF",
                                con->http.fd);
 
              cupsdCloseClient(con);
@@ -2118,9 +2219,9 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
               if (write(con->file, line, bytes) < bytes)
              {
                cupsdLogMessage(CUPSD_LOG_ERROR,
-                               "cupsdReadClient: Unable to write %d bytes to "
-                               "%s: %s", bytes, con->filename,
-                               strerror(errno));
+                               "[Client %d] Unable to write %d bytes to "
+                               "\"%s\": %s", con->http.fd, bytes,
+                               con->filename, strerror(errno));
 
                close(con->file);
                con->file = -1;
@@ -2140,8 +2241,8 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            else if (con->http.state != HTTP_POST_SEND)
            {
              cupsdLogMessage(CUPSD_LOG_DEBUG,
-                             "cupsdReadClient: %d Closing on unknown HTTP "
-                             "state %d", con->http.fd, con->http.state);
+                             "[Client %d] Closing on unexpected state %s.",
+                             con->http.fd, http_states[con->http.state]);
              cupsdCloseClient(con);
              return;
            }
@@ -2233,7 +2334,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
     if (!con->http.keep_alive)
     {
       cupsdLogMessage(CUPSD_LOG_DEBUG,
-                     "cupsdReadClient: %d Closing because Keep-Alive disabled",
+                     "[Client %d] Closing because Keep-Alive disabled",
                      con->http.fd);
       cupsdCloseClient(con);
     }
@@ -2267,7 +2368,7 @@ cupsdSendCommand(
     if (fd < 0)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdSendCommand: %d Unable to open \"%s\" for reading: %s",
+                      "[Client %d] Unable to open \"%s\" for reading: %s",
                       con->http.fd, con->filename ? con->filename : "/dev/null",
                      strerror(errno));
       return (0);
@@ -2283,11 +2384,11 @@ cupsdSendCommand(
   if (fd >= 0)
     close(fd);
 
-  cupsdLogMessage(CUPSD_LOG_INFO, "Started \"%s\" (pid=%d)", command,
-                  con->pipe_pid);
+  cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Started \"%s\" (pid=%d)",
+                  con->http.fd, command, con->pipe_pid);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSendCommand: %d file=%d",
-                  con->http.fd, con->file);
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] file=%d", con->http.fd,
+                  con->file);
 
   if (con->pipe_pid == 0)
     return (0);
@@ -2315,7 +2416,7 @@ cupsdSendError(cupsd_client_t *con,       /* I - Connection */
               int            auth_type)/* I - Authentication type */
 {
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdSendError(con=%p(%d), code=%d, auth_type=%d", con,
+                  "[Client %d] cupsdSendError code=%d, auth_type=%d",
                  con->http.fd, code, auth_type);
 
 #ifdef HAVE_SSL
@@ -2326,7 +2427,7 @@ cupsdSendError(cupsd_client_t *con,       /* I - Connection */
 
   if (code == HTTP_UNAUTHORIZED &&
       DefaultEncryption == HTTP_ENCRYPT_REQUIRED &&
-      strcasecmp(con->http.hostname, "localhost") &&
+      _cups_strcasecmp(con->http.hostname, "localhost") &&
       !con->http.tls)
   {
     code = HTTP_UPGRADE_REQUIRED;
@@ -2411,6 +2512,10 @@ cupsdSendError(cupsd_client_t *con,      /* I - Connection */
               "CONTENT=\"3;URL=https://%s:%d%s\">\n",
               con->servername, con->serverport, con->uri);
     }
+    else if (code == HTTP_WEBIF_DISABLED)
+      text = _cupsLangString(con->language,
+                             _("The web interface is currently disabled. Run "
+                              "\"cupsctl WebInterface=yes\" to enable it."));
     else
       text = "";
 
@@ -2421,17 +2526,17 @@ cupsdSendError(cupsd_client_t *con,     /* I - Connection */
             "<HEAD>\n"
              "\t<META HTTP-EQUIV=\"Content-Type\" "
             "CONTENT=\"text/html; charset=utf-8\">\n"
-            "\t<TITLE>%d %s</TITLE>\n"
+            "\t<TITLE>%s - " CUPS_SVERSION "</TITLE>\n"
             "\t<LINK REL=\"STYLESHEET\" TYPE=\"text/css\" "
             "HREF=\"/cups.css\">\n"
             "%s"
             "</HEAD>\n"
              "<BODY>\n"
-            "<H1>%d %s</H1>\n"
+            "<H1>%s</H1>\n"
             "<P>%s</P>\n"
             "</BODY>\n"
             "</HTML>\n",
-            code, httpStatus(code), redirect, code, httpStatus(code), text);
+            httpStatus(code), redirect, httpStatus(code), text);
 
     if (httpPrintf(HTTP(con), "Content-Type: text/html; charset=utf-8\r\n") < 0)
       return (0);
@@ -2467,10 +2572,6 @@ cupsdSendHeader(
     int            auth_type)          /* I - Type of authentication */
 {
   char         auth_str[1024];         /* Authorization string */
-#ifdef HAVE_GSSAPI
-  static char  *gss_buf = NULL;        /* Kerberos auth data buffer */
-  static int   gss_bufsize = 0;        /* Size of Kerberos auth data buffer */
-#endif /* HAVE_GSSAPI */
 
 
  /*
@@ -2486,6 +2587,15 @@ cupsdSendHeader(
     return (httpPrintf(HTTP(con), "HTTP/%d.%d 100 Continue\r\n\r\n",
                       con->http.version / 100, con->http.version % 100) > 0);
   }
+  else if (code == HTTP_WEBIF_DISABLED)
+  {
+   /*
+    * Treat our special "web interface is disabled" status as "200 OK" for web
+    * browsers.
+    */
+
+    code = HTTP_OK;
+  }
 
   httpFlushWrite(HTTP(con));
 
@@ -2529,12 +2639,19 @@ cupsdSendHeader(
       snprintf(auth_str, sizeof(auth_str), "Digest realm=\"CUPS\", nonce=\"%s\"",
               con->http.hostname);
 #ifdef HAVE_GSSAPI
-    else if (auth_type == CUPSD_AUTH_NEGOTIATE && con->gss_output_token.length == 0)
+    else if (auth_type == CUPSD_AUTH_NEGOTIATE)
+    {
+#  ifdef AF_LOCAL
+      if (_httpAddrFamily(con->http.hostaddr) == AF_LOCAL)
+        strlcpy(auth_str, "Basic realm=\"CUPS\"", sizeof(auth_str));
+      else
+#  endif /* AF_LOCAL */
       strlcpy(auth_str, "Negotiate", sizeof(auth_str));
+    }
 #endif /* HAVE_GSSAPI */
 
     if (con->best && auth_type != CUPSD_AUTH_NEGOTIATE &&
-        !strcasecmp(con->http.hostname, "localhost"))
+        !_cups_strcasecmp(con->http.hostname, "localhost"))
     {
      /*
       * Add a "trc" (try root certification) parameter for local non-Kerberos
@@ -2557,7 +2674,7 @@ cupsdSendHeader(
           name = (char *)cupsArrayNext(con->best->names))
       {
 #ifdef HAVE_AUTHORIZATION_H
-       if (!strncasecmp(name, "@AUTHKEY(", 9))
+       if (!_cups_strncasecmp(name, "@AUTHKEY(", 9))
        {
          snprintf(auth_key, auth_size, ", authkey=\"%s\"", name + 9);
          /* end parenthesis is stripped in conf.c */
@@ -2565,12 +2682,12 @@ cupsdSendHeader(
         }
        else
 #endif /* HAVE_AUTHORIZATION_H */
-       if (!strcasecmp(name, "@SYSTEM"))
+       if (!_cups_strcasecmp(name, "@SYSTEM"))
        {
 #ifdef HAVE_AUTHORIZATION_H
          if (SystemGroupAuthKey)
            snprintf(auth_key, auth_size,
-                    ", authkey=\"%s\", trc=\"y\"",
+                    ", authkey=\"%s\"",
                     SystemGroupAuthKey);
           else
 #else
@@ -2584,7 +2701,7 @@ cupsdSendHeader(
     if (auth_str[0])
     {
       cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "cupsdSendHeader: %d WWW-Authenticate: %s", con->http.fd,
+                      "[Client %d] WWW-Authenticate: %s", con->http.fd,
                       auth_str);
 
       if (httpPrintf(HTTP(con), "WWW-Authenticate: %s\r\n", auth_str) < 0)
@@ -2592,65 +2709,6 @@ cupsdSendHeader(
     }
   }
 
-#ifdef HAVE_GSSAPI
- /*
-  * WWW-Authenticate: Negotiate can be included even for
-  * non-401 replies...
-  */
-
-  if (con->gss_output_token.length > 0 && con->gss_output_token.length <= 65536)
-  {
-    OM_uint32  minor_status;           /* Minor status code */
-    int                bufsize;                /* Size of output token buffer */
-
-
-    bufsize = con->gss_output_token.length * 4 / 3 + 2;
-
-    if (bufsize > gss_bufsize)
-    {
-      char     *buf;                   /* New buffer */
-
-
-      bufsize = (bufsize + 1023) & 1023;/* Round up */
-
-      if (gss_buf)
-        buf = realloc(gss_buf, bufsize);
-      else
-        buf = malloc(bufsize);
-
-      if (!buf)
-      {
-       cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unable to allocate %d bytes for Kerberos credentials!",
-                       bufsize);
-       return (0);
-      }
-
-      gss_buf     = buf;
-      gss_bufsize = bufsize;
-    }
-
-    httpEncode64_2(gss_buf, gss_bufsize,
-                  con->gss_output_token.value,
-                  con->gss_output_token.length);
-    gss_release_buffer(&minor_status, &con->gss_output_token);
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "cupsdSendHeader: WWW-Authenticate: Negotiate %s", gss_buf);
-
-    if (httpPrintf(HTTP(con), "WWW-Authenticate: Negotiate %s\r\n",
-                   gss_buf) < 0)
-      return (0);
-  }
-  else if (con->gss_output_token.length > 65536)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Kerberos credentials larger than 64k (%d)!",
-                   (int)con->gss_output_token.length);
-    return (0);
-  }
-#endif /* HAVE_GSSAPI */
-
   if (con->language && strcmp(con->language->language, "C"))
   {
     if (httpPrintf(HTTP(con), "Content-Language: %s\r\n",
@@ -2724,11 +2782,23 @@ cupsdWriteClient(cupsd_client_t *con)   /* I - Client connection */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdWriteClient(con=%p(%d)) response=%p(%d), file=%d "
-                 "pipe_pid=%d state=%d",
-                  con, con->http.fd, con->response,
-                 con->response ? con->response->state : -1,
-                 con->file, con->pipe_pid, con->http.state);
+                 "[Client %d] cupsdWriteClient "
+                 "error=%d, "
+                 "used=%d, "
+                 "state=%s, "
+                 "data_encoding=HTTP_ENCODE_%s, "
+                 "data_remaining=" CUPS_LLFMT ", "
+                 "response=%p(%s), "
+                 "pipe_pid=%d, "
+                 "file=%d",
+                 con->http.fd, con->http.error, con->http.used,
+                 http_states[con->http.state],
+                 con->http.data_encoding == HTTP_ENCODE_CHUNKED ?
+                     "CHUNKED" : "LENGTH",
+                 CUPS_LLCAST con->http.data_remaining,
+                 con->response,
+                 con->response ? ipp_states[con->response->state] : "",
+                 con->pipe_pid, con->file);
 
   if (con->http.state != HTTP_GET_SEND &&
       con->http.state != HTTP_POST_SEND)
@@ -2739,8 +2809,8 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
     */
 
     cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "cupsdWriteClient: %d Closing on unknown HTTP state %d",
-                   con->http.fd, con->http.state);
+                   "[Client %d] Closing on unexpected HTTP state %s.",
+                   con->http.fd, http_states[con->http.state]);
     cupsdCloseClient(con);
     return;
   }
@@ -2806,15 +2876,20 @@ cupsdWriteClient(cupsd_client_t *con)   /* I - Client connection */
            * Handle redirection and CGI status codes...
            */
 
-            if (!strncasecmp(con->header, "Location:", 9))
+            if (!_cups_strncasecmp(con->header, "Location:", 9))
            {
-             cupsdSendHeader(con, HTTP_SEE_OTHER, NULL, CUPSD_AUTH_NONE);
+             if (!cupsdSendHeader(con, HTTP_SEE_OTHER, NULL, CUPSD_AUTH_NONE))
+             {
+               cupsdCloseClient(con);
+               return;
+             }
+
              con->sent_header = 2;
 
              if (httpPrintf(HTTP(con), "Content-Length: 0\r\n") < 0)
                return;
            }
-           else if (!strncasecmp(con->header, "Status:", 7))
+           else if (!_cups_strncasecmp(con->header, "Status:", 7))
            {
              cupsdSendError(con, (http_status_t)atoi(con->header + 7),
                             CUPSD_AUTH_NONE);
@@ -2822,7 +2897,12 @@ cupsdWriteClient(cupsd_client_t *con)    /* I - Client connection */
            }
            else
            {
-             cupsdSendHeader(con, HTTP_OK, NULL, CUPSD_AUTH_NONE);
+             if (!cupsdSendHeader(con, HTTP_OK, NULL, CUPSD_AUTH_NONE))
+             {
+               cupsdCloseClient(con);
+               return;
+             }
+
              con->sent_header = 1;
 
              if (con->http.version == HTTP_1_1)
@@ -2833,7 +2913,7 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
             }
          }
 
-         if (strncasecmp(con->header, "Status:", 7))
+         if (_cups_strncasecmp(con->header, "Status:", 7))
            httpPrintf(HTTP(con), "%s\r\n", con->header);
 
          /*
@@ -2883,7 +2963,7 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
       if (httpWrite2(HTTP(con), con->header, con->header_used) < 0)
       {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
-                       "cupsdWriteClient: %d Closing for error %d (%s)",
+                       "[Client %d] Closing for error %d (%s)",
                        con->http.fd, con->http.error,
                        strerror(con->http.error));
        cupsdCloseClient(con);
@@ -2920,7 +3000,7 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
        if (httpWrite2(HTTP(con), "", 0) < 0)
        {
          cupsdLogMessage(CUPSD_LOG_DEBUG,
-                         "cupsdWriteClient: %d Closing for error %d (%s)",
+                         "[Client %d] Closing for error %d (%s)",
                          con->http.fd, con->http.error,
                          strerror(con->http.error));
          cupsdCloseClient(con);
@@ -2970,7 +3050,7 @@ cupsdWriteClient(cupsd_client_t *con)     /* I - Client connection */
     if (!con->http.keep_alive)
     {
       cupsdLogMessage(CUPSD_LOG_DEBUG,
-                     "cupsdWriteClient: %d Closing because Keep-Alive disabled",
+                     "[Client %d] Closing because Keep-Alive disabled.",
                      con->http.fd);
       cupsdCloseClient(con);
       return;
@@ -3008,9 +3088,9 @@ check_if_modified(
     return (1);
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "check_if_modified(con=%p(%d), "
+                  "[Client %d] check_if_modified "
                  "filestats=%p(" CUPS_LLFMT ", %d)) If-Modified-Since=\"%s\"",
-                  con, con->http.fd, filestats, CUPS_LLCAST filestats->st_size,
+                  con->http.fd, filestats, CUPS_LLCAST filestats->st_size,
                  (int)filestats->st_mtime, ptr);
 
   while (*ptr != '\0')
@@ -3018,7 +3098,7 @@ check_if_modified(
     while (isspace(*ptr) || *ptr == ';')
       ptr ++;
 
-    if (strncasecmp(ptr, "length=", 7) == 0)
+    if (_cups_strncasecmp(ptr, "length=", 7) == 0)
     {
       ptr += 7;
       size = strtoll(ptr, NULL, 10);
@@ -3062,55 +3142,323 @@ compare_clients(cupsd_client_t *a,     /* I - First client */
 }
 
 
+#ifdef HAVE_CDSASSL
 /*
- * 'data_ready()' - Check whether data is available from a client.
+ * 'copy_cdsa_certificate()' - Copy a SSL/TLS certificate from the System
+ *                             keychain.
  */
 
-static int                             /* O - 1 if data is ready, 0 otherwise */
-data_ready(cupsd_client_t *con)                /* I - Client */
+static CFArrayRef                              /* O - Array of certificates */
+copy_cdsa_certificate(
+    cupsd_client_t *con)                       /* I - Client connection */
 {
-  if (con->http.used > 0)
-    return (1);
-#ifdef HAVE_SSL
-  else if (con->http.tls)
-  {
-#  ifdef HAVE_LIBSSL
-    if (SSL_pending((SSL *)(con->http.tls)))
-      return (1);
-#  elif defined(HAVE_GNUTLS)
-    if (gnutls_record_check_pending(con->http.tls))
-      return (1);
-#  elif defined(HAVE_CDSASSL)
-    size_t bytes;                      /* Bytes that are available */
+  OSStatus             err;            /* Error info */
+  SecKeychainRef       keychain = NULL;/* Keychain reference */
+  SecIdentitySearchRef search = NULL;  /* Search reference */
+  SecIdentityRef       identity = NULL;/* Identity */
+  CFArrayRef           certificates = NULL;
+                                       /* Certificate array */
+#  if HAVE_SECPOLICYCREATESSL
+  SecPolicyRef         policy = NULL;  /* Policy ref */
+  CFStringRef          servername = NULL;
+                                       /* Server name */
+  CFMutableDictionaryRef query = NULL; /* Query qualifiers */
+  char                 localname[1024];/* Local hostname */
+#  elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+  SecPolicyRef         policy = NULL;  /* Policy ref */
+  SecPolicySearchRef   policy_search = NULL;
+                                       /* Policy search ref */
+  CSSM_DATA            options;        /* Policy options */
+  CSSM_APPLE_TP_SSL_OPTIONS
+                       ssl_options;    /* SSL Option for hostname */
+  char                 localname[1024];/* Local hostname */
+#  endif /* HAVE_SECPOLICYCREATESSL */
 
-    if (!SSLGetBufferedReadSize(con->http.tls, &bytes) && bytes > 0)
-      return (1);
-#  endif /* HAVE_LIBSSL */
-  }
-#endif /* HAVE_SSL */
 
-  return (0);
-}
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
+                  "copy_cdsa_certificate: Looking for certs for \"%s\"...",
+                 con->servername);
 
+  if ((err = SecKeychainOpen(ServerCertificate, &keychain)))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot open keychain \"%s\" - %s (%d)",
+                   ServerCertificate, cssmErrorString(err), (int)err);
+    goto cleanup;
+  }
 
-#ifdef HAVE_SSL
-/*
- * 'encrypt_client()' - Enable encryption for the client...
- */
+#  if HAVE_SECPOLICYCREATESSL
+  servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername,
+                                        kCFStringEncodingUTF8);
 
-static int                             /* O - 1 on success, 0 on error */
-encrypt_client(cupsd_client_t *con)    /* I - Client to encrypt */
-{
-#  ifdef HAVE_LIBSSL
-  SSL_CTX      *context;               /* Context for encryption */
-  BIO          *bio;                   /* BIO data */
-  unsigned long        error;                  /* Error code */
+  policy = SecPolicyCreateSSL(1, servername);
 
+  if (servername)
+    CFRelease(servername);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con,
-                  con->http.fd);
+  if (!policy)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
+    goto cleanup;
+  }
 
- /*
+  if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                         &kCFTypeDictionaryKeyCallBacks,
+                                         &kCFTypeDictionaryValueCallBacks)))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create query dictionary");
+    goto cleanup;
+  }
+
+  CFDictionaryAddValue(query, kSecClass, kSecClassIdentity);
+  CFDictionaryAddValue(query, kSecMatchPolicy, policy);
+  CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue);
+  CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne);
+
+  err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
+
+  if (err && DNSSDHostName)
+  {
+   /*
+    * Search for the connection server name failed; try the DNS-SD .local
+    * hostname instead...
+    */
+
+    snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                   "copy_cdsa_certificate: Looking for certs for \"%s\"...",
+                   localname);
+
+    servername = CFStringCreateWithCString(kCFAllocatorDefault, localname,
+                                          kCFStringEncodingUTF8);
+
+    CFRelease(policy);
+
+    policy = SecPolicyCreateSSL(1, servername);
+
+    if (servername)
+      CFRelease(servername);
+
+    if (!policy)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
+      goto cleanup;
+    }
+
+    CFDictionarySetValue(query, kSecMatchPolicy, policy);
+
+    err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
+  }
+
+  if (err)
+  {
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                   "Cannot find signing key in keychain \"%s\": %s (%d)",
+                   ServerCertificate, cssmErrorString(err), (int)err);
+    goto cleanup;
+  }
+
+#  elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+ /*
+  * Use a policy to search for valid certificates whose common name matches the
+  * servername...
+  */
+
+  if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL,
+                           NULL, &policy_search))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create a policy search reference");
+    goto cleanup;
+  }
+
+  if (SecPolicySearchCopyNext(policy_search, &policy))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                   "Cannot find a policy to use for searching");
+    goto cleanup;
+  }
+
+  memset(&ssl_options, 0, sizeof(ssl_options));
+  ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
+  ssl_options.ServerName = con->servername;
+  ssl_options.ServerNameLen = strlen(con->servername);
+
+  options.Data = (uint8 *)&ssl_options;
+  options.Length = sizeof(ssl_options);
+
+  if (SecPolicySetValue(policy, &options))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                   "Cannot set policy value to use for searching");
+    goto cleanup;
+  }
+
+  if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
+                                              keychain, FALSE, &search)))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                   "Cannot create identity search reference: %s (%d)",
+                   cssmErrorString(err), (int)err);
+    goto cleanup;
+  }
+
+  err = SecIdentitySearchCopyNext(search, &identity);
+
+  if (err && DNSSDHostName)
+  {
+   /*
+    * Search for the connection server name failed; try the DNS-SD .local
+    * hostname instead...
+    */
+
+    snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
+
+    ssl_options.ServerName    = localname;
+    ssl_options.ServerNameLen = strlen(localname);
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                   "copy_cdsa_certificate: Looking for certs for \"%s\"...",
+                   localname);
+
+    if (SecPolicySetValue(policy, &options))
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                     "Cannot set policy value to use for searching");
+      goto cleanup;
+    }
+
+    CFRelease(search);
+    search = NULL;
+    if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
+                                              keychain, FALSE, &search)))
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                     "Cannot create identity search reference: %s (%d)",
+                     cssmErrorString(err), (int)err);
+      goto cleanup;
+    }
+
+    err = SecIdentitySearchCopyNext(search, &identity);
+
+  }
+
+  if (err)
+  {
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                   "Cannot find signing key in keychain \"%s\": %s (%d)",
+                   ServerCertificate, cssmErrorString(err), (int)err);
+    goto cleanup;
+  }
+
+#  else
+ /*
+  * Assume there is exactly one SecIdentity in the keychain...
+  */
+
+  if ((err = SecIdentitySearchCreate(keychain, CSSM_KEYUSE_SIGN, &search)))
+  {
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                   "Cannot create identity search reference (%d)", (int)err);
+    goto cleanup;
+  }
+
+  if ((err = SecIdentitySearchCopyNext(search, &identity)))
+  {
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                   "Cannot find signing key in keychain \"%s\": %s (%d)",
+                   ServerCertificate, cssmErrorString(err), (int)err);
+    goto cleanup;
+  }
+#  endif /* HAVE_SECPOLICYCREATESSL */
+
+  if (CFGetTypeID(identity) != SecIdentityGetTypeID())
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure!");
+    goto cleanup;
+  }
+
+  if ((certificates = CFArrayCreate(NULL, (const void **)&identity,
+                                 1, &kCFTypeArrayCallBacks)) == NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array");
+    goto cleanup;
+  }
+
+  cleanup :
+
+  if (keychain)
+    CFRelease(keychain);
+  if (search)
+    CFRelease(search);
+  if (identity)
+    CFRelease(identity);
+
+#  if HAVE_SECPOLICYCREATESSL
+  if (policy)
+    CFRelease(policy);
+  if (query)
+    CFRelease(query);
+#  elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+  if (policy)
+    CFRelease(policy);
+  if (policy_search)
+    CFRelease(policy_search);
+#  endif /* HAVE_SECPOLICYCREATESSL */
+
+  return (certificates);
+}
+#endif /* HAVE_CDSASSL */
+
+
+/*
+ * 'data_ready()' - Check whether data is available from a client.
+ */
+
+static int                             /* O - 1 if data is ready, 0 otherwise */
+data_ready(cupsd_client_t *con)                /* I - Client */
+{
+  if (con->http.used > 0)
+    return (1);
+#ifdef HAVE_SSL
+  else if (con->http.tls)
+  {
+#  ifdef HAVE_LIBSSL
+    if (SSL_pending((SSL *)(con->http.tls)))
+      return (1);
+#  elif defined(HAVE_GNUTLS)
+    if (gnutls_record_check_pending(con->http.tls))
+      return (1);
+#  elif defined(HAVE_CDSASSL)
+    size_t bytes;                      /* Bytes that are available */
+
+    if (!SSLGetBufferedReadSize(con->http.tls, &bytes) && bytes > 0)
+      return (1);
+#  endif /* HAVE_LIBSSL */
+  }
+#endif /* HAVE_SSL */
+
+  return (0);
+}
+
+
+#ifdef HAVE_SSL
+/*
+ * 'encrypt_client()' - Enable encryption for the client...
+ */
+
+static int                             /* O - 1 on success, 0 on error */
+encrypt_client(cupsd_client_t *con)    /* I - Client to encrypt */
+{
+#  ifdef HAVE_LIBSSL
+  SSL_CTX      *context;               /* Context for encryption */
+  BIO          *bio;                   /* BIO data */
+  unsigned long        error;                  /* Error code */
+
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
+                  con->http.fd);
+
+ /*
   * Verify that we have a certificate...
   */
 
@@ -3162,12 +3510,13 @@ encrypt_client(cupsd_client_t *con)     /* I - Client to encrypt */
   return (1);
 
 #  elif defined(HAVE_GNUTLS)
-  int          error;                  /* Error code */
+  int          status;                 /* Error code */
   gnutls_certificate_server_credentials *credentials;
                                        /* TLS credentials */
+  const char   *priority;              /* Priority string */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con,
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
                   con->http.fd);
 
  /*
@@ -3203,20 +3552,16 @@ encrypt_client(cupsd_client_t *con)     /* I - Client to encrypt */
   gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate,
                                       ServerKey, GNUTLS_X509_FMT_PEM);
 
-  gnutls_init(&con->http.tls), GNUTLS_SERVER);
+  gnutls_init(&con->http.tls, GNUTLS_SERVER);
   gnutls_set_default_priority(con->http.tls);
-  gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials);
-  gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con));
-  gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS);
-  gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS);
-
-  error = gnutls_handshake(con->http.tls);
-
-  if (error != GNUTLS_E_SUCCESS)
+  status = gnutls_priority_set_direct(con->http.tls,
+                                      "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:"
+                                      "+VERS-SSL3.0:%COMPAT", &priority);
+  if (status != GNUTLS_E_SUCCESS)
   {
     cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Unable to encrypt connection from %s - %s",
-                    con->http.hostname, gnutls_strerror(error));
+                    "Unable to encrypt connection from %s - %s (%s)",
+                    con->http.hostname, gnutls_strerror(status), priority);
 
     gnutls_deinit(con->http.tls);
     gnutls_certificate_free_credentials(*credentials);
@@ -3225,376 +3570,130 @@ encrypt_client(cupsd_client_t *con)   /* I - Client to encrypt */
     return (0);
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
-                  con->http.hostname);
-
-  con->http.tls_credentials = credentials;
-  return (1);
-
-#  elif defined(HAVE_CDSASSL)
-  OSStatus     error;                  /* Error code */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con,
-                  con->http.fd);
-
-  error                     = 0;
-  con->http.tls_credentials = get_cdsa_certificate(con);
-
-  if (!con->http.tls_credentials)
-  {
-   /*
-    * No keychain (yet), make a self-signed certificate...
-    */
-
-    if (make_certificate(con))
-      con->http.tls_credentials = get_cdsa_certificate(con);
-  }
-
-  if (!con->http.tls_credentials)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                   "Could not find signing key in keychain \"%s\"",
-                   ServerCertificate);
-    error = errSSLBadCert; /* errSSLBadConfiguration is a better choice, but not available on 10.2.x */
-  }
-
-  if (!error)
-    error = SSLNewContext(true, &con->http.tls);
-
-  if (!error)
-    error = SSLSetIOFuncs(con->http.tls, _httpReadCDSA, _httpWriteCDSA);
-
-  if (!error)
-    error = SSLSetProtocolVersionEnabled(con->http.tls, kSSLProtocol2, false);
-
-  if (!error)
-    error = SSLSetConnection(con->http.tls, HTTP(con));
-
-  if (!error)
-    error = SSLSetAllowsExpiredCerts(con->http.tls, true);
-
-  if (!error)
-    error = SSLSetAllowsAnyRoot(con->http.tls, true);
-
-  if (!error)
-    error = SSLSetCertificate(con->http.tls, con->http.tls_credentials);
-
-  if (!error)
-  {
-   /*
-    * Perform SSL/TLS handshake
-    */
-
-    while ((error = SSLHandshake(con->http.tls)) == errSSLWouldBlock)
-      usleep(1000);
-  }
-
-  if (error)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Unable to encrypt connection from %s - %s (%d)",
-                    con->http.hostname, cssmErrorString(error), (int)error);
-
-    con->http.error  = error;
-    con->http.status = HTTP_ERROR;
-
-    if (con->http.tls)
-    {
-      SSLDisposeContext(con->http.tls);
-      con->http.tls = NULL;
-    }
-
-    if (con->http.tls_credentials)
-    {
-      CFRelease(con->http.tls_credentials);
-      con->http.tls_credentials = NULL;
-    }
-
-    return (0);
-  }
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
-                  con->http.hostname);
-
-  CFArrayRef           peerCerts;      /* Peer certificates */
-
-  if (!(error = SSLCopyPeerCertificates(con->http.tls, &peerCerts)) && peerCerts)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates!",
-                   (int)CFArrayGetCount(peerCerts));
-  }
-  else
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates!");
-
-  return (1);
-
-#  endif /* HAVE_LIBSSL */
-}
-#endif /* HAVE_SSL */
-
-
-#ifdef HAVE_CDSASSL
-/*
- * 'get_cdsa_certificate()' - Get a SSL/TLS certificate from the System keychain.
- */
-
-static CFArrayRef                              /* O - Array of certificates */
-get_cdsa_certificate(
-    cupsd_client_t *con)                       /* I - Client connection */
-{
-  OSStatus             err;            /* Error info */
-  SecKeychainRef       keychain = NULL;/* Keychain reference */
-  SecIdentitySearchRef search = NULL;  /* Search reference */
-  SecIdentityRef       identity = NULL;/* Identity */
-  CFArrayRef           certificates = NULL;
-                                       /* Certificate array */
-#  if HAVE_SECPOLICYCREATESSL
-  SecPolicyRef         policy = NULL;  /* Policy ref */
-  CFStringRef          servername = NULL;
-                                       /* Server name */
-  CFMutableDictionaryRef query = NULL; /* Query qualifiers */
-  char                 localname[1024];/* Local hostname */
-#  elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
-  SecPolicyRef         policy = NULL;  /* Policy ref */
-  SecPolicySearchRef   policy_search = NULL;
-                                       /* Policy search ref */
-  CSSM_DATA            options;        /* Policy options */
-  CSSM_APPLE_TP_SSL_OPTIONS
-                       ssl_options;    /* SSL Option for hostname */
-  char                 localname[1024];/* Local hostname */
-#  endif /* HAVE_SECPOLICYCREATESSL */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG,
-                  "get_cdsa_certificate: Looking for certs for \"%s\"...",
-                 con->servername);
-
-  if ((err = SecKeychainOpen(ServerCertificate, &keychain)))
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot open keychain \"%s\" - %s (%d)",
-                   ServerCertificate, cssmErrorString(err), (int)err);
-    goto cleanup;
-  }
-
-#  if HAVE_SECPOLICYCREATESSL
-  servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername,
-                                        kCFStringEncodingUTF8);
-
-  if ((policy = SecPolicyCreateSSL(1, servername)) == NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
-    goto cleanup;
-  }
-
-  if (servername)
-    CFRelease(servername);
-
-  if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
-                                         &kCFTypeDictionaryKeyCallBacks,
-                                         &kCFTypeDictionaryValueCallBacks)))
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create query dictionary");
-    goto cleanup;
-  }
-
-  CFDictionaryAddValue(query, kSecClass, kSecClassIdentity);
-  CFDictionaryAddValue(query, kSecMatchPolicy, policy);
-  CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue);
-  CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne);
-
-  err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
-
-  if (err && DNSSDHostName)
-  {
-   /*
-    * Search for the connection server name failed; try the DNS-SD .local
-    * hostname instead...
-    */
-
-    snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "get_cdsa_certificate: Looking for certs for \"%s\"...",
-                   localname);
-
-    servername = CFStringCreateWithCString(kCFAllocatorDefault, localname,
-                                          kCFStringEncodingUTF8);
-  
-    CFRelease(policy);
+  gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials);
+  gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con));
+  gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS);
+  gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS);
 
-    if ((policy = SecPolicyCreateSSL(1, servername)) == NULL)
+  while ((status = gnutls_handshake(con->http.tls)) != GNUTLS_E_SUCCESS)
+  {
+    if (gnutls_error_is_fatal(status))
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
-      goto cleanup;
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Unable to encrypt connection from %s - %s",
+                      con->http.hostname, gnutls_strerror(status));
+
+      gnutls_deinit(con->http.tls);
+      gnutls_certificate_free_credentials(*credentials);
+      con->http.tls = NULL;
+      free(credentials);
+      return (0);
     }
+  }
 
-    if (servername)
-      CFRelease(servername);
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
+                  con->http.hostname);
 
-    CFDictionarySetValue(query, kSecMatchPolicy, policy);
+  con->http.tls_credentials = credentials;
+  return (1);
 
-    err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
-  }
+#  elif defined(HAVE_CDSASSL)
+  OSStatus     error = 0;              /* Error code */
+  CFArrayRef   peerCerts;              /* Peer certificates */
 
-  if (err)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "Cannot find signing key in keychain \"%s\": %s (%d)",
-                   ServerCertificate, cssmErrorString(err), (int)err);
-    goto cleanup;
-  }
 
-#  elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
- /*
-  * Use a policy to search for valid certificates whose common name matches the
-  * servername...
-  */
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
+                  con->http.fd);
 
-  if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL,
-                           NULL, &policy_search))
+  con->http.tls_credentials = copy_cdsa_certificate(con);
+
+  if (!con->http.tls_credentials)
   {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create a policy search reference");
-    goto cleanup;
+   /*
+    * No keychain (yet), make a self-signed certificate...
+    */
+
+    if (make_certificate(con))
+      con->http.tls_credentials = copy_cdsa_certificate(con);
   }
 
-  if (SecPolicySearchCopyNext(policy_search, &policy))
+  if (!con->http.tls_credentials)
   {
     cupsdLogMessage(CUPSD_LOG_ERROR,
-                   "Cannot find a policy to use for searching");
-    goto cleanup;
+                   "Could not find signing key in keychain \"%s\"",
+                   ServerCertificate);
+    error = errSSLBadCert; /* errSSLBadConfiguration is a better choice, but not available on 10.2.x */
   }
 
-  memset(&ssl_options, 0, sizeof(ssl_options));
-  ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
-  ssl_options.ServerName = con->servername;
-  ssl_options.ServerNameLen = strlen(con->servername);
+  if (!error)
+    error = SSLNewContext(true, &con->http.tls);
 
-  options.Data = (uint8 *)&ssl_options;
-  options.Length = sizeof(ssl_options);
+  if (!error)
+    error = SSLSetIOFuncs(con->http.tls, _httpReadCDSA, _httpWriteCDSA);
 
-  if (SecPolicySetValue(policy, &options))
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                   "Cannot set policy value to use for searching");
-    goto cleanup;
-  }
+  if (!error)
+    error = SSLSetConnection(con->http.tls, HTTP(con));
 
-  if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
-                                              keychain, FALSE, &search)))
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                   "Cannot create identity search reference: %s (%d)",
-                   cssmErrorString(err), (int)err);
-    goto cleanup;
-  }
+  if (!error)
+    error = SSLSetAllowsExpiredCerts(con->http.tls, true);
 
-  err = SecIdentitySearchCopyNext(search, &identity);
+  if (!error)
+    error = SSLSetAllowsAnyRoot(con->http.tls, true);
 
-  if (err && DNSSDHostName)
+  if (!error)
+    error = SSLSetCertificate(con->http.tls, con->http.tls_credentials);
+
+  if (!error)
   {
    /*
-    * Search for the connection server name failed; try the DNS-SD .local
-    * hostname instead...
+    * Perform SSL/TLS handshake
     */
 
-    snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
+    while ((error = SSLHandshake(con->http.tls)) == errSSLWouldBlock)
+      usleep(1000);
+  }
 
-    ssl_options.ServerName    = localname;
-    ssl_options.ServerNameLen = strlen(localname);
+  if (error)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "Unable to encrypt connection from %s - %s (%d)",
+                    con->http.hostname, cssmErrorString(error), (int)error);
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "get_cdsa_certificate: Looking for certs for \"%s\"...",
-                   localname);
+    con->http.error  = error;
+    con->http.status = HTTP_ERROR;
 
-    if (SecPolicySetValue(policy, &options))
+    if (con->http.tls)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Cannot set policy value to use for searching");
-      goto cleanup;
+      SSLDisposeContext(con->http.tls);
+      con->http.tls = NULL;
     }
 
-    CFRelease(search);
-    search = NULL;
-    if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
-                                              keychain, FALSE, &search)))
+    if (con->http.tls_credentials)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Cannot create identity search reference: %s (%d)",
-                     cssmErrorString(err), (int)err);
-      goto cleanup;
+      CFRelease(con->http.tls_credentials);
+      con->http.tls_credentials = NULL;
     }
 
-    err = SecIdentitySearchCopyNext(search, &identity);
-
-  }
-
-  if (err)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "Cannot find signing key in keychain \"%s\": %s (%d)",
-                   ServerCertificate, cssmErrorString(err), (int)err);
-    goto cleanup;
-  }
-
-#  else
- /*
-  * Assume there is exactly one SecIdentity in the keychain...
-  */
-
-  if ((err = SecIdentitySearchCreate(keychain, CSSM_KEYUSE_SIGN, &search)))
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "Cannot create identity search reference (%d)", (int)err);
-    goto cleanup;
-  }
-
-  if ((err = SecIdentitySearchCopyNext(search, &identity)))
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "Cannot find signing key in keychain \"%s\": %s (%d)",
-                   ServerCertificate, cssmErrorString(err), (int)err);
-    goto cleanup;
+    return (0);
   }
-#  endif /* HAVE_SECPOLICYCREATESSL */
 
-  if (CFGetTypeID(identity) != SecIdentityGetTypeID())
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure!");
-    goto cleanup;
-  }
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
+                  con->http.hostname);
 
-  if ((certificates = CFArrayCreate(NULL, (const void **)&identity,
-                                 1, &kCFTypeArrayCallBacks)) == NULL)
+  if (!SSLCopyPeerCertificates(con->http.tls, &peerCerts) && peerCerts)
   {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array");
-    goto cleanup;
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates!",
+                   (int)CFArrayGetCount(peerCerts));
+    CFRelease(peerCerts);
   }
+  else
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates!");
 
-  cleanup :
-
-  if (keychain)
-    CFRelease(keychain);
-  if (search)
-    CFRelease(search);
-  if (identity)
-    CFRelease(identity);
-
-#  if HAVE_SECPOLICYCREATESSL
-  if (policy)
-    CFRelease(policy);
-  if (query)
-    CFRelease(query);
-#  elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
-  if (policy)
-    CFRelease(policy);
-  if (policy_search)
-    CFRelease(policy_search);
-#  endif /* HAVE_SECPOLICYCREATESSL */
+  return (1);
 
-  return (certificates);
+#  endif /* HAVE_LIBSSL */
 }
-#endif /* HAVE_CDSASSL */
+#endif /* HAVE_SSL */
 
 
 /*
@@ -3780,8 +3879,8 @@ get_file(cupsd_client_t *con,             /* I  - Client connection */
   }
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "get_file(con=%p(%d), filestats=%p, filename=%p, len=%d) = "
-                 "%s", con, con->http.fd, filestats, filename, len,
+                  "[Client %d] get_file filestats=%p, filename=%p, len=%d, "
+                 "returning \"%s\".", con->http.fd, filestats, filename, len,
                  status ? "(null)" : filename);
 
   if (status)
@@ -3798,60 +3897,42 @@ get_file(cupsd_client_t *con,           /* I  - Client connection */
 static http_status_t                   /* O - Status */
 install_conf_file(cupsd_client_t *con) /* I - Connection */
 {
+  char         filename[1024];         /* Configuration filename */
+  mode_t       mode;                   /* Permissions */
   cups_file_t  *in,                    /* Input file */
                *out;                   /* Output file */
-  char         buffer[1024];           /* Copy buffer */
-  int          bytes;                  /* Number of bytes */
-  char         conffile[1024],         /* Configuration filename */
-               newfile[1024],          /* New config filename */
-               oldfile[1024];          /* Old config filename */
-  struct stat  confinfo;               /* Config file info */
-
-
- /*
-  * First construct the filenames...
-  */
+  char         buffer[16384];          /* Copy buffer */
+  ssize_t      bytes;                  /* Number of bytes */
 
-  snprintf(conffile, sizeof(conffile), "%s%s", ServerRoot, con->uri + 11);
-  snprintf(newfile, sizeof(newfile), "%s%s.N", ServerRoot, con->uri + 11);
-  snprintf(oldfile, sizeof(oldfile), "%s%s.O", ServerRoot, con->uri + 11);
-
-  cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file \"%s\"...", conffile);
 
  /*
-  * Get the owner, group, and permissions of the configuration file.
-  * If it doesn't exist, assign it to the User and Group in the
-  * cupsd.conf file with mode 0640 permissions.
+  * Open the request file...
   */
 
-  if (stat(conffile, &confinfo))
+  if ((in = cupsFileOpen(con->filename, "rb")) == NULL)
   {
-    confinfo.st_uid  = User;
-    confinfo.st_gid  = Group;
-    confinfo.st_mode = ConfigFilePerm;
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open request file \"%s\": %s",
+                    con->filename, strerror(errno));
+    return (HTTP_SERVER_ERROR);
   }
 
  /*
-  * Open the request file and new config file...
+  * Open the new config file...
   */
 
-  if ((in = cupsFileOpen(con->filename, "rb")) == NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open request file \"%s\" - %s",
-                    con->filename, strerror(errno));
-    return (HTTP_SERVER_ERROR);
-  }
+  snprintf(filename, sizeof(filename), "%s%s", ServerRoot, con->uri + 11);
+  if (!strcmp(con->uri, "/admin/conf/printers.conf"))
+    mode = ConfigFilePerm & 0600;
+  else
+    mode = ConfigFilePerm;
 
-  if ((out = cupsFileOpen(newfile, "wb")) == NULL)
+  if ((out = cupsdCreateConfFile(filename, mode)) == NULL)
   {
     cupsFileClose(in);
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open config file \"%s\" - %s",
-                    newfile, strerror(errno));
     return (HTTP_SERVER_ERROR);
   }
 
-  fchmod(cupsFileNumber(out), confinfo.st_mode);
-  fchown(cupsFileNumber(out), confinfo.st_uid, confinfo.st_gid);
+  cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file \"%s\"...", filename);
 
  /*
   * Copy from the request to the new config file...
@@ -3861,12 +3942,14 @@ install_conf_file(cupsd_client_t *con)  /* I - Connection */
     if (cupsFileWrite(out, buffer, bytes) < bytes)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to copy to config file \"%s\" - %s",
-                     newfile, strerror(errno));
+                      "Unable to copy to config file \"%s\": %s",
+                     filename, strerror(errno));
 
       cupsFileClose(in);
       cupsFileClose(out);
-      unlink(newfile);
+
+      snprintf(filename, sizeof(filename), "%s%s.N", ServerRoot, con->uri + 11);
+      cupsdRemoveFile(filename);
 
       return (HTTP_SERVER_ERROR);
     }
@@ -3876,65 +3959,17 @@ install_conf_file(cupsd_client_t *con)  /* I - Connection */
   */
 
   cupsFileClose(in);
-  if (cupsFileClose(out))
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Error file closing config file \"%s\" - %s",
-                    newfile, strerror(errno));
-
-    unlink(newfile);
 
+  if (cupsdCloseCreatedConfFile(out, filename))
     return (HTTP_SERVER_ERROR);
-  }
 
  /*
   * Remove the request file...
   */
 
-  unlink(con->filename);
+  cupsdRemoveFile(con->filename);
   cupsdClearString(&con->filename);
 
- /*
-  * Unlink the old backup, rename the current config file to the backup
-  * filename, and rename the new config file to the config file name...
-  */
-
-  if (unlink(oldfile))
-    if (errno != ENOENT)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to remove backup config file \"%s\" - %s",
-                     oldfile, strerror(errno));
-
-      unlink(newfile);
-
-      return (HTTP_SERVER_ERROR);
-    }
-
-  if (rename(conffile, oldfile))
-    if (errno != ENOENT)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to rename old config file \"%s\" - %s",
-                     conffile, strerror(errno));
-
-      unlink(newfile);
-
-      return (HTTP_SERVER_ERROR);
-    }
-
-  if (rename(newfile, conffile))
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Unable to rename new config file \"%s\" - %s",
-                    newfile, strerror(errno));
-
-    rename(oldfile, conffile);
-    unlink(newfile);
-
-    return (HTTP_SERVER_ERROR);
-  }
-
  /*
   * If the cupsd.conf file was updated, set the NeedReload flag...
   */
@@ -3981,17 +4016,17 @@ is_cgi(cupsd_client_t *con,             /* I - Client connection */
   * Check for known types...
   */
 
-  if (!type || strcasecmp(type->super, "application"))
+  if (!type || _cups_strcasecmp(type->super, "application"))
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                   "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
-                   "type=%s/%s) = 0", con, con->http.fd, filename, filestats,
-                   type ? type->super : "unknown",
+                   "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+                   "type=%s/%s, returning 0", con->http.fd, filename,
+                   filestats, type ? type->super : "unknown",
                    type ? type->type : "unknown");
     return (0);
   }
 
-  if (!strcasecmp(type->type, "x-httpd-cgi") &&
+  if (!_cups_strcasecmp(type->type, "x-httpd-cgi") &&
       (filestats->st_mode & 0111))
   {
    /*
@@ -4004,14 +4039,13 @@ is_cgi(cupsd_client_t *con,             /* I - Client connection */
       cupsdSetStringf(&con->options, " %s", options);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                   "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
-                   "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
-                   type ? type->super : "unknown",
-                   type ? type->type : "unknown");
+                   "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+                   "type=%s/%s, returning 1", con->http.fd, filename,
+                   filestats, type->super, type->type);
     return (1);
   }
 #ifdef HAVE_JAVA
-  else if (!strcasecmp(type->type, "x-httpd-java"))
+  else if (!_cups_strcasecmp(type->type, "x-httpd-java"))
   {
    /*
     * "application/x-httpd-java" is a Java servlet.
@@ -4025,15 +4059,14 @@ is_cgi(cupsd_client_t *con,             /* I - Client connection */
       cupsdSetStringf(&con->options, " %s", filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                   "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
-                   "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
-                   type ? type->super : "unknown",
-                   type ? type->type : "unknown");
+                   "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+                   "type=%s/%s, returning 1", con->http.fd, filename,
+                   filestats, type->super, type->type);
     return (1);
   }
 #endif /* HAVE_JAVA */
 #ifdef HAVE_PERL
-  else if (!strcasecmp(type->type, "x-httpd-perl"))
+  else if (!_cups_strcasecmp(type->type, "x-httpd-perl"))
   {
    /*
     * "application/x-httpd-perl" is a Perl page.
@@ -4047,15 +4080,14 @@ is_cgi(cupsd_client_t *con,             /* I - Client connection */
       cupsdSetStringf(&con->options, " %s", filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                   "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
-                   "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
-                   type ? type->super : "unknown",
-                   type ? type->type : "unknown");
+                   "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+                   "type=%s/%s, returning 1", con->http.fd, filename,
+                   filestats, type->super, type->type);
     return (1);
   }
 #endif /* HAVE_PERL */
 #ifdef HAVE_PHP
-  else if (!strcasecmp(type->type, "x-httpd-php"))
+  else if (!_cups_strcasecmp(type->type, "x-httpd-php"))
   {
    /*
     * "application/x-httpd-php" is a PHP page.
@@ -4069,15 +4101,14 @@ is_cgi(cupsd_client_t *con,             /* I - Client connection */
       cupsdSetStringf(&con->options, " %s", filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                   "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
-                   "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
-                   type ? type->super : "unknown",
-                   type ? type->type : "unknown");
+                   "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+                   "type=%s/%s, returning 1", con->http.fd, filename,
+                   filestats, type->super, type->type);
     return (1);
   }
 #endif /* HAVE_PHP */
 #ifdef HAVE_PYTHON
-  else if (!strcasecmp(type->type, "x-httpd-python"))
+  else if (!_cups_strcasecmp(type->type, "x-httpd-python"))
   {
    /*
     * "application/x-httpd-python" is a Python page.
@@ -4091,19 +4122,17 @@ is_cgi(cupsd_client_t *con,             /* I - Client connection */
       cupsdSetStringf(&con->options, " %s", filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                   "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
-                   "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
-                   type ? type->super : "unknown",
-                   type ? type->type : "unknown");
+                   "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+                   "type=%s/%s, returning 1", con->http.fd, filename,
+                   filestats, type->super, type->type);
     return (1);
   }
 #endif /* HAVE_PYTHON */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                 "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
-                 "type=%s/%s) = 0", con, con->http.fd, filename, filestats,
-                 type ? type->super : "unknown",
-                 type ? type->type : "unknown");
+                 "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+                 "type=%s/%s, returning 0", con->http.fd, filename,
+                 filestats, type->super, type->type);
   return (0);
 }
 
@@ -4504,7 +4533,7 @@ make_certificate(cupsd_client_t *con)     /* I - Client connection */
   }
   else
     servername = con->servername;
-       
+
  /*
   * Run the "certtool" command to generate a self-signed certificate...
   */
@@ -4659,9 +4688,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
   */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "pipe_command(con=%p(%d), infile=%d, outfile=%p, "
-                 "command=\"%s\", options=\"%s\", root=%d)",
-                  con, con->http.fd, infile, outfile, command,
+                  "[Client %d] pipe_command infile=%d, outfile=%p, "
+                 "command=\"%s\", options=\"%s\", root=%d",
+                  con->http.fd, infile, outfile, command,
                  options ? options : "(null)", root);
 
   argv[0] = command;
@@ -4838,8 +4867,18 @@ pipe_command(cupsd_client_t *con,        /* I - Client connection */
 
   sprintf(server_port, "SERVER_PORT=%d", con->serverport);
 
-  snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s",
-           con->servername);
+  if (con->http.fields[HTTP_FIELD_HOST][0])
+  {
+    char *nameptr;                     /* Pointer to ":port" */
+
+    snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s",
+            con->http.fields[HTTP_FIELD_HOST]);
+    if ((nameptr = strrchr(server_name, ':')) != NULL && !strchr(nameptr, ']'))
+      *nameptr = '\0';                 /* Strip trailing ":port" */
+  }
+  else
+    snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s",
+            con->servername);
 
   envc = cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
 
@@ -4864,15 +4903,6 @@ pipe_command(cupsd_client_t *con,        /* I - Client connection */
     snprintf(remote_user, sizeof(remote_user), "REMOTE_USER=%s", con->username);
 
     envp[envc ++] = remote_user;
-
-   /*
-    * Save Kerberos credentials, if any...
-    */
-
-#ifdef HAVE_GSSAPI
-    if (con->gss_creds)
-      ccache = cupsdCopyKrb5Creds(con);
-#endif /* HAVE_GSSAPI */
   }
 
   if (con->http.version == HTTP_1_1)
@@ -5022,13 +5052,13 @@ valid_host(cupsd_client_t *con)         /* I - Client connection */
     * addresses when accessing CUPS via the loopback interface...
     */
 
-    return (!strcasecmp(host, "localhost") ||
-            !strncasecmp(host, "localhost:", 10) ||
-           !strcasecmp(host, "localhost.") ||
-            !strncasecmp(host, "localhost.:", 11) ||
+    return (!_cups_strcasecmp(host, "localhost") ||
+            !_cups_strncasecmp(host, "localhost:", 10) ||
+           !_cups_strcasecmp(host, "localhost.") ||
+            !_cups_strncasecmp(host, "localhost.:", 11) ||
 #ifdef __linux
-           !strcasecmp(host, "localhost.localdomain") ||
-            !strncasecmp(host, "localhost.localdomain:", 22) ||
+           !_cups_strcasecmp(host, "localhost.localdomain") ||
+            !_cups_strncasecmp(host, "localhost.localdomain:", 22) ||
 #endif /* __linux */
             !strcmp(host, "127.0.0.1") ||
            !strncmp(host, "127.0.0.1:", 10) ||
@@ -5042,8 +5072,8 @@ valid_host(cupsd_client_t *con)           /* I - Client connection */
   */
 
   if ((end = strrchr(host, '.')) != NULL &&
-      (!strcasecmp(end, ".local") || !strncasecmp(end, ".local:", 7) ||
-       !strcasecmp(end, ".local.") || !strncasecmp(end, ".local.:", 8)))
+      (!_cups_strcasecmp(end, ".local") || !_cups_strncasecmp(end, ".local:", 7) ||
+       !_cups_strcasecmp(end, ".local.") || !_cups_strncasecmp(end, ".local.:", 8)))
     return (1);
 #endif /* HAVE_DNSSD */
 
@@ -5092,7 +5122,7 @@ valid_host(cupsd_client_t *con)           /* I - Client connection */
     if (!strcmp(a->name, "*"))
       return (1);
 
-    if (!strncasecmp(host, a->name, a->namelen))
+    if (!_cups_strncasecmp(host, a->name, a->namelen))
     {
      /*
       * Prefix matches; check the character at the end - it must be ":", ".",
@@ -5118,7 +5148,7 @@ valid_host(cupsd_client_t *con)           /* I - Client connection */
     if (!strcmp(a->name, "*"))
       return (1);
 
-    if (!strncasecmp(host, a->name, a->namelen))
+    if (!_cups_strncasecmp(host, a->name, a->namelen))
     {
      /*
       * Prefix matches; check the character at the end - it must be ":", ".",
@@ -5141,7 +5171,7 @@ valid_host(cupsd_client_t *con)           /* I - Client connection */
        netif;
        netif = (cupsd_netif_t *)cupsArrayNext(NetIFList))
   {
-    if (!strncasecmp(host, netif->hostname, netif->hostlen))
+    if (!_cups_strncasecmp(host, netif->hostname, netif->hostlen))
     {
      /*
       * Prefix matches; check the character at the end - it must be ":", ".",
@@ -5173,8 +5203,8 @@ write_file(cupsd_client_t *con,           /* I - Client connection */
   con->file = open(filename, O_RDONLY);
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "write_file(con=%p(%d), code=%d, filename=\"%s\" (%d), "
-                 "type=\"%s\", filestats=%p)", con, con->http.fd,
+                  "[Client %d] write_file code=%d, filename=\"%s\" (%d), "
+                 "type=\"%s\", filestats=%p", con->http.fd,
                  code, filename, con->file, type ? type : "(null)", filestats);
 
   if (con->file < 0)
@@ -5222,8 +5252,8 @@ static void
 write_pipe(cupsd_client_t *con)                /* I - Client connection */
 {
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "write_pipe(con=%p(%d)) CGI output on fd %d",
-                  con, con->http.fd, con->file);
+                  "[Client %d] write_pipe CGI output on fd %d",
+                  con->http.fd, con->file);
 
   con->file_ready = 1;