]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/client.c
Load cups into easysw/current.
[thirdparty/cups.git] / scheduler / client.c
index 1780b2207e059085870fde48d44f3fc7e2c003a8..23a74e50ec0466f786d4be1b7239f1d1365999a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: client.c 5367 2006-04-02 19:00:00Z mike $"
+ * "$Id: client.c 5630 2006-06-05 18:42:53Z mike $"
  *
  *   Client routines for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -42,7 +42,7 @@
  *   is_path_absolute()      - Is a path absolute and free of relative elements.
  *   make_certificate()      - Make a self-signed SSL/TLS certificate.
  *   pipe_command()          - Pipe the output of a command to the remote client.
- *   send_file()             - Send a file via HTTP.
+ *   write_file()            - Send a file via HTTP.
  */
 
 /*
 
 #ifdef HAVE_CDSASSL
 #  include <Security/Security.h>
+#  ifdef HAVE_SECBASEPRIV_H
+#    include <Security/SecBasePriv.h>
+#  else
+     extern const char *cssmErrorString(int error);
+#  endif /* HAVE_SECBASEPRIV_H */
 #endif /* HAVE_CDSASSL */
 #ifdef HAVE_GNUTLS
 #  include <gnutls/x509.h>
@@ -83,9 +88,9 @@ static void           make_certificate(void);
 #endif /* HAVE_GNUTLS */
 static int             pipe_command(cupsd_client_t *con, int infile, int *outfile,
                                     char *command, char *options, int root);
-static int             send_file(cupsd_client_t *con, http_status_t code,
-                                 char *filename, char *type,
-                                 struct stat *filestats);
+static int             write_file(cupsd_client_t *con, http_status_t code,
+                                  char *filename, char *type,
+                                  struct stat *filestats);
 
 
 /*
@@ -458,10 +463,12 @@ cupsdCloseClient(cupsd_client_t *con)     /* I - Client to close */
   SSL          *conn;                  /* Connection for encryption */
   unsigned long        error;                  /* Error code */
 #elif defined(HAVE_GNUTLS)
-  http_tls_t     *conn;                        /* TLS connection information */
-  int            error;                        /* Error code */
+  http_tls_t   *conn;                  /* TLS connection information */
+  int          error;                  /* Error code */
   gnutls_certificate_server_credentials *credentials;
                                        /* TLS credentials */
+#  elif defined(HAVE_CDSASSL)
+  http_tls_t   *conn;                  /* CDSA connection information */
 #endif /* HAVE_LIBSSL */
 
 
@@ -530,10 +537,17 @@ cupsdCloseClient(cupsd_client_t *con)     /* I - Client to close */
     free(conn);
 
 #  elif defined(HAVE_CDSASSL)
-    while (SSLClose((SSLContextRef)con->http.tls) == errSSLWouldBlock)
+    conn = (http_tls_t *)(con->http.tls);
+
+    while (SSLClose(conn->session) == errSSLWouldBlock)
       usleep(1000);
 
-    SSLDisposeContext((SSLContextRef)con->http.tls);
+    SSLDisposeContext(conn->session);
+
+    if (conn->certsArray)
+      CFRelease(conn->certsArray);
+
+    free(conn);
 #  endif /* HAVE_LIBSSL */
 
     con->http.tls = NULL;
@@ -892,8 +906,8 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
         con->start     = time(NULL);
         con->operation = con->http.state;
 
-        cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %s %s HTTP/%d.%d", con->http.fd,
-                       operation, con->uri,
+        cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %s %s HTTP/%d.%d",
+                       con->http.fd, operation, con->uri,
                        con->http.version / 100, con->http.version % 100);
 
        con->http.status = HTTP_OK;
@@ -958,6 +972,10 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
         snprintf(locale, sizeof(locale), "%s.%s",
                 con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE], DefaultCharset);
 
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                      "cupsdReadClient: %d Browser asked for language \"%s\"...",
+                      con->http.fd, locale);
+
       con->language = cupsLangGet(locale);
     }
     else
@@ -1251,7 +1269,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
                else
                  snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
 
-               if (!send_file(con, HTTP_OK, filename, line, &filestats))
+               if (!write_file(con, HTTP_OK, filename, line, &filestats))
                  return (cupsdCloseClient(con));
              }
            }
@@ -1363,7 +1381,8 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
               cupsdLogMessage(CUPSD_LOG_DEBUG2,
                              "cupsdReadClient: %d command=\"%s\", "
                              "options = \"%s\"",
-                             con->http.fd, con->command, con->options);
+                             con->http.fd, con->command,
+                             con->options ? con->options : "(null)");
 
              if (con->http.version <= HTTP_1_0)
                con->http.keep_alive = HTTP_KEEPALIVE_OFF;
@@ -1868,24 +1887,27 @@ cupsdSendCommand(
 
 
   if (con->filename)
+  {
     fd = open(con->filename, O_RDONLY);
-  else
-    fd = open("/dev/null", O_RDONLY);
 
-  if (fd < 0)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "cupsdSendCommand: %d Unable to open \"%s\" for reading: %s",
-                    con->http.fd, con->filename ? con->filename : "/dev/null",
-                   strerror(errno));
-    return (0);
-  }
+    if (fd < 0)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "cupsdSendCommand: %d Unable to open \"%s\" for reading: %s",
+                      con->http.fd, con->filename ? con->filename : "/dev/null",
+                     strerror(errno));
+      return (0);
+    }
 
-  fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+    fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+  }
+  else
+    fd = -1;
 
   con->pipe_pid = pipe_command(con, fd, &(con->file), command, options, root);
 
-  close(fd);
+  if (fd >= 0)
+    close(fd);
 
   cupsdLogMessage(CUPSD_LOG_INFO, "Started \"%s\" (pid=%d)", command,
                   con->pipe_pid);
@@ -2474,6 +2496,8 @@ check_if_modified(
       while (*ptr != '\0' && *ptr != ';')
         ptr ++;
     }
+    else
+      ptr ++;
   }
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
@@ -2562,7 +2586,7 @@ encrypt_client(cupsd_client_t *con)       /* I - Client to encrypt */
   * Create the SSL object and perform the SSL handshake...
   */
 
-  conn = (http_tls_t *)malloc(sizeof(gnutls_session));
+  conn = (http_tls_t *)malloc(sizeof(http_tls_t));
 
   if (conn == NULL)
     return (0);
@@ -2616,21 +2640,19 @@ encrypt_client(cupsd_client_t *con)     /* I - Client to encrypt */
   return (1);
 
 #  elif defined(HAVE_CDSASSL)
-  OSStatus     error;                  /* Error info */
-  SSLContextRef        conn;                   /* New connection */
-  CFArrayRef   certificatesArray;      /* Array containing certificates */
-  int          allowExpired;           /* Allow expired certificates? */
-  int          allowAnyRoot;           /* Allow any root certificate? */
+  OSStatus     error;                  /* Error code */
+  http_tls_t   *conn;                  /* CDSA connection information */
+  cdsa_conn_ref_t u;                   /* Connection reference union */
 
 
-  conn         = NULL;
-  error        = SSLNewContext(true, &conn);
-  allowExpired = 1;
-  allowAnyRoot = 1;
+  if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
+    return (0);
 
-  certificatesArray = get_cdsa_server_certs();
+  error            = 0;
+  conn->session    = NULL;
+  conn->certsArray = get_cdsa_server_certs();
 
-  if (!certificatesArray)
+  if (!conn->certsArray)
   {
     cupsdLogMessage(CUPSD_LOG_ERROR,
                    "EncryptClient: Could not find signing key in keychain "
@@ -2639,32 +2661,33 @@ encrypt_client(cupsd_client_t *con)     /* I - Client to encrypt */
   }
 
   if (!error)
-    error = SSLSetIOFuncs(conn, _httpReadCDSA, _httpWriteCDSA);
+    error = SSLNewContext(true, &conn->session);
 
   if (!error)
-    error = SSLSetProtocolVersion(conn, kSSLProtocol3);
+    error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);
 
   if (!error)
-    error = SSLSetConnection(conn, (SSLConnectionRef)con->http.fd);
+    error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false);
 
   if (!error)
-    error = SSLSetPeerDomainName(conn, ServerName, strlen(ServerName) + 1);
+  {
+   /*
+    * Use a union to resolve warnings about int/pointer size mismatches...
+    */
 
-  /* have to do these options before setting server certs */
-  if (!error && allowExpired)
-    error = SSLSetAllowsExpiredCerts(conn, true);
+    u.connection = NULL;
+    u.sock       = con->http.fd;
+    error        = SSLSetConnection(conn->session, u.connection);
+  }
 
-  if (!error && allowAnyRoot)
-    error = SSLSetAllowsAnyRoot(conn, true);
+  if (!error)
+    error = SSLSetAllowsExpiredCerts(conn->session, true);
 
   if (!error)
-    error = SSLSetCertificate(conn, certificatesArray);
+    error = SSLSetAllowsAnyRoot(conn->session, true);
 
-  if (certificatesArray)
-  {
-    CFRelease(certificatesArray);
-    certificatesArray = NULL;
-  }
+  if (!error)
+    error = SSLSetCertificate(conn->session, conn->certsArray);
 
   if (!error)
   {
@@ -2672,7 +2695,7 @@ encrypt_client(cupsd_client_t *con)       /* I - Client to encrypt */
     * Perform SSL/TLS handshake
     */
 
-    while ((error = SSLHandshake(conn)) == errSSLWouldBlock)
+    while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock)
       usleep(1000);
   }
 
@@ -2682,14 +2705,19 @@ encrypt_client(cupsd_client_t *con)     /* I - Client to encrypt */
                     "encrypt_client: Unable to encrypt connection from %s!",
                     con->http.hostname);
 
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "encrypt_client: CDSA error code is %d", (int)error);
+    cupsdLogMessage(CUPSD_LOG_ERROR, "encrypt_client: %s (%d)",
+                    cssmErrorString(error), (int)error);
 
     con->http.error  = error;
     con->http.status = HTTP_ERROR;
 
-    if (conn != NULL)
-      SSLDisposeContext(conn);
+    if (conn->session)
+      SSLDisposeContext(conn->session);
+
+    if (conn->certsArray)
+      CFRelease(conn->certsArray);
+
+    free(conn);
 
     return (0);
   }
@@ -3488,7 +3516,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
                   "pipe_command: command=\"%s\", options=\"%s\"",
-                  command, options);
+                  command, options ? options : "(null)");
 
   argv[0]      = command;
   query_string = NULL;
@@ -3682,7 +3710,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
   * Tell the CGI if we are using encryption...
   */
 
-  if (con->http.encryption == HTTP_ENCRYPT_ALWAYS)
+  if (con->http.tls)
     envp[envc ++] = "HTTPS=ON";
 
  /*
@@ -3753,19 +3781,19 @@ pipe_command(cupsd_client_t *con,       /* I - Client connection */
 
 
 /*
- * 'send_file()' - Send a file via HTTP.
+ * 'write_file()' - Send a file via HTTP.
  */
 
 static int                             /* O - 0 on failure, 1 on success */
-send_file(cupsd_client_t *con,         /* I - Client connection */
-          http_status_t  code,         /* I - HTTP status */
-         char           *filename,     /* I - Filename */
-         char           *type,         /* I - File type */
-         struct stat    *filestats)    /* O - File information */
+write_file(cupsd_client_t *con,                /* I - Client connection */
+           http_status_t  code,                /* I - HTTP status */
+          char           *filename,    /* I - Filename */
+          char           *type,        /* I - File type */
+          struct stat    *filestats)   /* O - File information */
 {
   con->file = open(filename, O_RDONLY);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "send_file: %d file=%d", con->http.fd,
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "write_file: %d file=%d", con->http.fd,
                   con->file);
 
   if (con->file < 0)
@@ -3796,7 +3824,7 @@ send_file(cupsd_client_t *con,            /* I - Client connection */
     con->http._data_remaining = INT_MAX;
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "send_file: Adding fd %d to OutputSet...", con->http.fd);
+                  "write_file: Adding fd %d to OutputSet...", con->http.fd);
 
   FD_SET(con->http.fd, OutputSet);
 
@@ -3805,5 +3833,5 @@ send_file(cupsd_client_t *con,            /* I - Client connection */
 
 
 /*
- * End of "$Id: client.c 5367 2006-04-02 19:00:00Z mike $".
+ * End of "$Id: client.c 5630 2006-06-05 18:42:53Z mike $".
  */