]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Revert unintented commit. 2.4.x
authorMichael R Sweet <msweet@msweet.org>
Sat, 4 Oct 2025 21:40:27 +0000 (17:40 -0400)
committerMichael R Sweet <msweet@msweet.org>
Sat, 4 Oct 2025 21:40:27 +0000 (17:40 -0400)
cups/http-private.h
cups/http.c
cups/tls-openssl.c
scheduler/client.c
scheduler/client.h
scheduler/select.c

index 2d90350329e1a963af220c6fc077d43a2e6f2072..d9854faed72d8d49ab52be801b1430bf86fcfee7 100644 (file)
@@ -121,7 +121,6 @@ extern "C" {
  * Constants...
  */
 
-#  define _HTTP_MAX_BUFFER     32768   /* Size of read buffer */
 #  define _HTTP_MAX_SBUFFER    65536   /* Size of (de)compression buffer */
 #  define _HTTP_RESOLVE_DEFAULT        0       /* Just resolve with default options */
 #  define _HTTP_RESOLVE_STDERR 1       /* Log resolve progress to stderr */
@@ -234,8 +233,8 @@ struct _http_s                              /**** HTTP connection structure ****/
   http_encoding_t      data_encoding;  /* Chunked or not */
   int                  _data_remaining;/* Number of bytes left (deprecated) */
   int                  used;           /* Number of bytes used in buffer */
-  char                 _buffer[HTTP_MAX_BUFFER];
-                                       /* Old read buffer (deprecated) */
+  char                 buffer[HTTP_MAX_BUFFER];
+                                       /* Buffer for incoming data */
   int                  _auth_type;     /* Authentication in use (deprecated) */
   unsigned char                _md5_state[88]; /* MD5 state (deprecated) */
   char                 nonce[HTTP_MAX_VALUE];
@@ -309,8 +308,6 @@ struct _http_s                              /**** HTTP connection structure ****/
                                        /* Allocated field values */
                        *default_fields[HTTP_FIELD_MAX];
                                        /* Default field values, if any */
-  char                 buffer[_HTTP_MAX_BUFFER];
-                                       /* Read buffer */
 };
 #  endif /* !_HTTP_NO_PRIVATE */
 
index e350acee5c92dc14afbceca7ac412d7ed6fbfd7b..7a42cb3d69b0704ce4837130b4882aefcae03222 100644 (file)
@@ -53,7 +53,7 @@ static http_t         *http_create(const char *host, int port,
 static void            http_debug_hex(const char *prefix, const char *buffer,
                                       int bytes);
 #endif /* DEBUG */
-static ssize_t         http_read(http_t *http, char *buffer, size_t length, int timeout);
+static ssize_t         http_read(http_t *http, char *buffer, size_t length);
 static ssize_t         http_read_buffered(http_t *http, char *buffer, size_t length);
 static ssize_t         http_read_chunk(http_t *http, char *buffer, size_t length);
 static int             http_send(http_t *http, http_state_t request,
@@ -1206,7 +1206,7 @@ httpGets(char   *line,                    /* I - Line to read into */
         return (NULL);
       }
 
-      bytes = http_read(http, http->buffer + http->used, (size_t)(_HTTP_MAX_BUFFER - http->used), http->wait_value);
+      bytes = http_read(http, http->buffer + http->used, (size_t)(HTTP_MAX_BUFFER - http->used));
 
       DEBUG_printf(("4httpGets: read " CUPS_LLFMT " bytes.", CUPS_LLCAST bytes));
 
@@ -1726,13 +1726,24 @@ httpPeek(http_t *http,                  /* I - HTTP connection */
 
     ssize_t    buflen;                 /* Length of read for buffer */
 
+    if (!http->blocking)
+    {
+      while (!httpWait(http, http->wait_value))
+      {
+       if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
+         continue;
+
+       return (0);
+      }
+    }
+
     if ((size_t)http->data_remaining > sizeof(http->buffer))
       buflen = sizeof(http->buffer);
     else
       buflen = (ssize_t)http->data_remaining;
 
     DEBUG_printf(("2httpPeek: Reading %d bytes into buffer.", (int)buflen));
-    bytes = http_read(http, http->buffer, (size_t)buflen, http->wait_value);
+    bytes = http_read(http, http->buffer, (size_t)buflen);
 
     DEBUG_printf(("2httpPeek: Read " CUPS_LLFMT " bytes into buffer.",
                   CUPS_LLCAST bytes));
@@ -1753,9 +1764,9 @@ httpPeek(http_t *http,                    /* I - HTTP connection */
     int                zerr;                   /* Decompressor error */
     z_stream   stream;                 /* Copy of decompressor stream */
 
-    if (http->used > 0 && ((z_stream *)http->stream)->avail_in < _HTTP_MAX_BUFFER)
+    if (http->used > 0 && ((z_stream *)http->stream)->avail_in < HTTP_MAX_BUFFER)
     {
-      size_t buflen = _HTTP_MAX_BUFFER - ((z_stream *)http->stream)->avail_in;
+      size_t buflen = HTTP_MAX_BUFFER - ((z_stream *)http->stream)->avail_in;
                                        /* Number of bytes to copy */
 
       if (((z_stream *)http->stream)->avail_in > 0 &&
@@ -2013,7 +2024,7 @@ httpRead2(http_t *http,                   /* I - HTTP connection */
 
       if (bytes == 0)
       {
-        ssize_t buflen = _HTTP_MAX_BUFFER - (ssize_t)((z_stream *)http->stream)->avail_in;
+        ssize_t buflen = HTTP_MAX_BUFFER - (ssize_t)((z_stream *)http->stream)->avail_in;
                                        /* Additional bytes for buffer */
 
         if (buflen > 0)
@@ -2763,7 +2774,7 @@ int                                       /* O - 1 to continue, 0 to stop */
 _httpUpdate(http_t        *http,       /* I - HTTP connection */
             http_status_t *status)     /* O - Current HTTP status */
 {
-  char         line[_HTTP_MAX_BUFFER], /* Line from connection... */
+  char         line[32768],            /* Line from connection... */
                *value;                 /* Pointer to value on line */
   http_field_t field;                  /* Field index */
   int          major, minor;           /* HTTP version numbers */
@@ -2771,46 +2782,12 @@ _httpUpdate(http_t        *http,        /* I - HTTP connection */
 
   DEBUG_printf(("_httpUpdate(http=%p, status=%p), state=%s", (void *)http, (void *)status, httpStateString(http->state)));
 
-  /* When doing non-blocking I/O, make sure we have a whole line... */
-  if (!http->blocking)
-  {
-    ssize_t    bytes;                  /* Bytes "peeked" from connection */
-
-    /* See whether our read buffer is full... */
-    DEBUG_printf(("2_httpUpdate: used=%d", http->used));
-
-    if (http->used > 0 && !memchr(http->buffer, '\n', (size_t)http->used) && (size_t)http->used < sizeof(http->buffer))
-    {
-      /* No, try filling in more data... */
-      if ((bytes = http_read(http, http->buffer + http->used, sizeof(http->buffer) - (size_t)http->used, /*timeout*/0)) > 0)
-      {
-        DEBUG_printf(("2_httpUpdate: Read %d bytes.", (int)bytes));
-        http->used += (int)bytes;
-      }
-    }
-
-    /* Peek at the incoming data... */
-    if (!http->used || !memchr(http->buffer, '\n', (size_t)http->used))
-    {
-      /* Don't have a full line, tell the reader to try again when there is more data... */
-      DEBUG_puts("1_htttpUpdate: No newline in buffer yet.");
-      if ((size_t)http->used == sizeof(http->buffer))
-        *status = HTTP_STATUS_ERROR;
-      else
-        *status = HTTP_STATUS_CONTINUE;
-      return (0);
-    }
-
-    DEBUG_puts("2_httpUpdate: Found newline in buffer.");
-  }
-
  /*
   * Grab a single line from the connection...
   */
 
   if (!httpGets(line, sizeof(line), http))
   {
-    DEBUG_puts("1_httpUpdate: Error reading request line.");
     *status = HTTP_STATUS_ERROR;
     return (0);
   }
@@ -4163,8 +4140,7 @@ http_debug_hex(const char *prefix,        /* I - Prefix for line */
 static ssize_t                         /* O - Number of bytes read or -1 on error */
 http_read(http_t *http,                        /* I - HTTP connection */
           char   *buffer,              /* I - Buffer */
-          size_t length,               /* I - Maximum bytes to read */
-          int    timeout)              /* I - Wait timeout */
+          size_t length)               /* I - Maximum bytes to read */
 {
   ssize_t      bytes;                  /* Bytes read */
 
@@ -4173,7 +4149,7 @@ http_read(http_t *http,                   /* I - HTTP connection */
 
   if (!http->blocking || http->timeout_value > 0.0)
   {
-    while (!_httpWait(http, timeout, 1))
+    while (!httpWait(http, http->wait_value))
     {
       if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
        continue;
@@ -4276,7 +4252,7 @@ http_read_buffered(http_t *http,  /* I - HTTP connection */
     else
       bytes = (ssize_t)length;
 
-    DEBUG_printf(("8http_read_buffered: Grabbing %d bytes from input buffer.",
+    DEBUG_printf(("8http_read: Grabbing %d bytes from input buffer.",
                   (int)bytes));
 
     memcpy(buffer, http->buffer, (size_t)bytes);
@@ -4286,7 +4262,7 @@ http_read_buffered(http_t *http,  /* I - HTTP connection */
       memmove(http->buffer, http->buffer + bytes, (size_t)http->used);
   }
   else
-    bytes = http_read(http, buffer, length, http->wait_value);
+    bytes = http_read(http, buffer, length);
 
   return (bytes);
 }
@@ -4627,15 +4603,15 @@ http_set_timeout(int    fd,             /* I - File descriptor */
 static void
 http_set_wait(http_t *http)            /* I - HTTP connection */
 {
-  http->wait_value = (int)(http->timeout_value * 1000);
-
-  if (http->wait_value <= 0)
+  if (http->blocking)
   {
-    if (http->blocking)
+    http->wait_value = (int)(http->timeout_value * 1000);
+
+    if (http->wait_value <= 0)
       http->wait_value = 60000;
-    else
-      http->wait_value = 1000;
   }
+  else
+    http->wait_value = 10000;
 }
 
 
index f746f4cba498c63165636dda1ade4e3a7242fe7e..9fcbe0af3b64d5c340ed1cb9b632390426eaaf97 100644 (file)
@@ -215,14 +215,12 @@ cupsMakeServerCredentials(
   // Save them...
   if ((bio = BIO_new_file(keyfile, "wb")) == NULL)
   {
-    DEBUG_printf(("1cupsMakeServerCredentials: Unable to create private key file '%s': %s", keyfile, strerror(errno)));
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
     goto done;
   }
 
   if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL))
   {
-    DEBUG_puts("1cupsMakeServerCredentials: PEM_write_bio_PrivateKey failed.");
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to write private key."), 1);
     BIO_free(bio);
     goto done;
@@ -232,14 +230,12 @@ cupsMakeServerCredentials(
 
   if ((bio = BIO_new_file(crtfile, "wb")) == NULL)
   {
-    DEBUG_printf(("1cupsMakeServerCredentials: Unable to create certificate file '%s': %s", crtfile, strerror(errno)));
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
     goto done;
   }
 
   if (!PEM_write_bio_X509(bio, cert))
   {
-    DEBUG_puts("1cupsMakeServerCredentials: PEM_write_bio_X509 failed.");
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to write X.509 certificate."), 1);
     BIO_free(bio);
     goto done;
@@ -1086,10 +1082,10 @@ _httpTLSStart(http_t *http)             // I - Connection to server
 
       if (!cupsMakeServerCredentials(tls_keypath, cn, 0, NULL, time(NULL) + 3650 * 86400))
       {
-       DEBUG_printf(("4_httpTLSStart: cupsMakeServerCredentials failed: %s", cupsLastErrorString()));
+       DEBUG_puts("4_httpTLSStart: cupsMakeServerCredentials failed.");
        http->error  = errno = EINVAL;
        http->status = HTTP_STATUS_ERROR;
-//     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create server credentials."), 1);
+       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create server credentials."), 1);
        SSL_CTX_free(context);
         _cupsMutexUnlock(&tls_mutex);
 
@@ -1350,17 +1346,14 @@ http_bio_read(BIO  *h,                  // I - BIO data
 
   http = (http_t *)BIO_get_data(h);
 
-  if (!http->blocking || http->timeout_value > 0.0)
+  if (!http->blocking)
   {
    /*
     * Make sure we have data before we read...
     */
 
-    while (!_httpWait(http, http->wait_value, 0))
+    if (!_httpWait(http, 10000, 0))
     {
-      if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
-       continue;
-
 #ifdef WIN32
       http->error = WSAETIMEDOUT;
 #else
index f23b8e6de80130a8bdcf7391ab8ce39dd71ffd1d..f0349a6c91fd8832b4e81dad55868bff8220f4db 100644 (file)
 
 static int             check_if_modified(cupsd_client_t *con,
                                          struct stat *filestats);
-#ifdef HAVE_TLS
-static int             check_start_tls(cupsd_client_t *con);
-#endif /* HAVE_TLS */
 static int             compare_clients(cupsd_client_t *a, cupsd_client_t *b,
                                        void *data);
+#ifdef HAVE_TLS
+static int             cupsd_start_tls(cupsd_client_t *con, http_encryption_t e);
+#endif /* HAVE_TLS */
 static char            *get_file(cupsd_client_t *con, struct stat *filestats,
                                  char *filename, size_t len);
 static http_status_t   install_cupsd_conf(cupsd_client_t *con);
@@ -367,20 +367,14 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
   if (lis->encryption == HTTP_ENCRYPTION_ALWAYS)
   {
    /*
-    * HTTPS connection, force TLS negotiation...
+    * https connection; go secure...
     */
 
-    con->do_tls     = time(NULL);
-    con->encryption = HTTP_ENCRYPTION_ALWAYS;
+    if (cupsd_start_tls(con, HTTP_ENCRYPTION_ALWAYS))
+      cupsdCloseClient(con);
   }
   else
-  {
-   /*
-    * HTTP connection, but check for HTTPS negotiation on first data...
-    */
-
     con->auto_ssl = 1;
-  }
 #endif /* HAVE_TLS */
 }
 
@@ -619,46 +613,17 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
 
     con->auto_ssl = 0;
 
-    if (recv(httpGetFd(con->http), buf, 5, MSG_PEEK) == 5 && buf[0] == 0x16 && buf[1] == 3 && buf[2])
+    if (recv(httpGetFd(con->http), buf, 1, MSG_PEEK) == 1 &&
+        (!buf[0] || !strchr("DGHOPT", buf[0])))
     {
      /*
-      * Client hello record, encrypt this connection...
+      * Encrypt this connection...
       */
 
-      cupsdLogClient(con, CUPSD_LOG_DEBUG2, "Saw client hello record, auto-negotiating TLS session.");
-      con->do_tls     = time(NULL);
-      con->encryption = HTTP_ENCRYPTION_ALWAYS;
-    }
-  }
+      cupsdLogClient(con, CUPSD_LOG_DEBUG2, "Saw first byte %02X, auto-negotiating SSL/TLS session.", buf[0] & 255);
 
-  if (con->do_tls)
-  {
-   /*
-    * Try negotiating TLS...
-    */
-
-    int tls_status = check_start_tls(con);
-
-    if (tls_status < 0)
-    {
-     /*
-      * TLS negotiation failed, close the connection.
-      */
-
-      cupsdCloseClient(con);
-      return;
-    }
-    else if (tls_status == 0)
-    {
-     /*
-      * Nothing to do yet...
-      */
-
-      if ((time(NULL) - con->do_tls) > 5)
-      {
-        // Timeout, close the connection...
+      if (cupsd_start_tls(con, HTTP_ENCRYPTION_ALWAYS))
         cupsdCloseClient(con);
-      }
 
       return;
     }
@@ -822,7 +787,9 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
         * Parse incoming parameters until the status changes...
        */
 
-        status = httpUpdate(con->http);
+        while ((status = httpUpdate(con->http)) == HTTP_STATUS_CONTINUE)
+         if (!httpGetReady(con->http))
+           break;
 
        if (status != HTTP_STATUS_OK && status != HTTP_STATUS_CONTINUE)
        {
@@ -984,10 +951,11 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
          return;
        }
 
-        con->do_tls         = time(NULL);
-        con->do_tls_options = 1;
-        con->encryption     = HTTP_ENCRYPTION_REQUIRED;
-        return;
+        if (cupsd_start_tls(con, HTTP_ENCRYPTION_REQUIRED))
+        {
+         cupsdCloseClient(con);
+         return;
+       }
 #else
        if (!cupsdSendError(con, HTTP_STATUS_NOT_IMPLEMENTED, CUPSD_AUTH_NONE))
        {
@@ -1026,11 +994,32 @@ cupsdReadClient(cupsd_client_t *con)     /* I - Client to read from */
       if (!_cups_strcasecmp(httpGetField(con->http, HTTP_FIELD_CONNECTION),
                             "Upgrade") && !httpIsEncrypted(con->http))
       {
+#ifdef HAVE_TLS
+       /*
+        * Do encryption stuff...
+       */
+
+        httpClearFields(con->http);
+
+       if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL,
+                            CUPSD_AUTH_NONE))
+       {
+         cupsdCloseClient(con);
+         return;
+       }
+
+        if (cupsd_start_tls(con, HTTP_ENCRYPTION_REQUIRED))
+        {
+         cupsdCloseClient(con);
+         return;
+       }
+#else
        if (!cupsdSendError(con, HTTP_STATUS_NOT_IMPLEMENTED, CUPSD_AUTH_NONE))
        {
          cupsdCloseClient(con);
          return;
        }
+#endif /* HAVE_TLS */
       }
 
       if ((status = cupsdIsAuthorized(con, NULL)) != HTTP_STATUS_OK)
@@ -2700,69 +2689,6 @@ check_if_modified(
 }
 
 
-#ifdef HAVE_TLS
-/*
- * 'check_start_tls()' - Start encryption on a connection.
- */
-
-static int                             /* O - 0 to continue, 1 on success, -1 on error */
-check_start_tls(cupsd_client_t *con)   /* I - Client connection */
-{
-  unsigned char        chello[4096];           /* Client hello record */
-  ssize_t      chello_bytes;           /* Bytes read/peeked */
-  int          chello_len;             /* Length of record */
-
-
- /*
-  * See if we have a good and complete client hello record...
-  */
-
-  if ((chello_bytes = recv(httpGetFd(con->http), (char *)chello, sizeof(chello), MSG_PEEK)) < 5)
-    return (0);                                /* Not enough bytes (yet) */
-
-  if (chello[0] != 0x016 || chello[1] != 3 || chello[2] == 0)
-    return (-1);                       /* Not a TLS Client Hello record */
-
-  chello_len = (chello[3] << 8) | chello[4];
-
-  if ((chello_len + 5) > chello_bytes)
-    return (0);                                /* Not enough bytes yet */
-
- /*
-  * OK, we do, try negotiating...
-  */
-
-  con->do_tls = 0;
-
-  if (httpEncryption(con->http, con->encryption))
-  {
-    cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to encrypt connection: %s", cupsLastErrorString());
-    return (-1);
-  }
-
-  cupsdLogClient(con, CUPSD_LOG_DEBUG, "Connection now encrypted.");
-
-  if (con->do_tls_options)
-  {
-    // Respond to the original OPTIONS command...
-    con->do_tls_options = 0;
-
-    httpClearFields(con->http);
-    httpClearCookie(con->http);
-    httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
-
-    if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
-    {
-      cupsdCloseClient(con);
-      return (0);
-    }
-  }
-
-  return (1);
-}
-#endif /* HAVE_TLS */
-
-
 /*
  * 'compare_clients()' - Compare two client connections.
  */
@@ -2783,6 +2709,28 @@ compare_clients(cupsd_client_t *a,       /* I - First client */
 }
 
 
+#ifdef HAVE_TLS
+/*
+ * 'cupsd_start_tls()' - Start encryption on a connection.
+ */
+
+static int                             /* O - 0 on success, -1 on error */
+cupsd_start_tls(cupsd_client_t    *con,        /* I - Client connection */
+                http_encryption_t e)   /* I - Encryption mode */
+{
+  if (httpEncryption(con->http, e))
+  {
+    cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to encrypt connection: %s",
+                   cupsLastErrorString());
+    return (-1);
+  }
+
+  cupsdLogClient(con, CUPSD_LOG_DEBUG, "Connection now encrypted.");
+  return (0);
+}
+#endif /* HAVE_TLS */
+
+
 /*
  * 'get_file()' - Get a filename and state info.
  */
index 9008c4b8671a0bc3168ab804dcdc7773d411d66e..9fe4e2ea6229647637862a6fc7c0bc3d07e95f23 100644 (file)
@@ -53,9 +53,6 @@ struct cupsd_client_s
   cups_lang_t          *language;      /* Language to use */
 #ifdef HAVE_TLS
   int                  auto_ssl;       /* Automatic test for SSL/TLS */
-  time_t               do_tls;         /* Do TLS negotiation? */
-  int                  do_tls_options; /* Doing TLS upgrade via OPTIONS? */
-  http_encryption_t    encryption;     /* Type of TLS negotiation */
 #endif /* HAVE_TLS */
   http_addr_t          clientaddr;     /* Client's server address */
   char                 clientname[256];/* Client's server name for connection */
index c95c79dd59092b5208cd727f4ad971d95d618826..2e64f2a7ed23a957f09b605b86b4db23802572aa 100644 (file)
@@ -544,9 +544,6 @@ cupsdDoSelect(long timeout)         /* I - Timeout in seconds */
     }
   }
 
-  // Prevent 100% CPU by releasing control before the poll call...
-  usleep(1);
-
   if (timeout >= 0 && timeout < 86400)
     nfds = poll(cupsd_pollfds, (nfds_t)count, timeout * 1000);
   else