From: Michael R Sweet Date: Sat, 4 Oct 2025 21:40:27 +0000 (-0400) Subject: Revert unintented commit. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2F2.4.x;p=thirdparty%2Fcups.git Revert unintented commit. --- diff --git a/cups/http-private.h b/cups/http-private.h index 2d90350329..d9854faed7 100644 --- a/cups/http-private.h +++ b/cups/http-private.h @@ -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 */ diff --git a/cups/http.c b/cups/http.c index e350acee5c..7a42cb3d69 100644 --- a/cups/http.c +++ b/cups/http.c @@ -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; } diff --git a/cups/tls-openssl.c b/cups/tls-openssl.c index f746f4cba4..9fcbe0af3b 100644 --- a/cups/tls-openssl.c +++ b/cups/tls-openssl.c @@ -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 diff --git a/scheduler/client.c b/scheduler/client.c index f23b8e6de8..f0349a6c91 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -34,11 +34,11 @@ 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. */ diff --git a/scheduler/client.h b/scheduler/client.h index 9008c4b867..9fe4e2ea62 100644 --- a/scheduler/client.h +++ b/scheduler/client.h @@ -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 */ diff --git a/scheduler/select.c b/scheduler/select.c index c95c79dd59..2e64f2a7ed 100644 --- a/scheduler/select.c +++ b/scheduler/select.c @@ -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