1 diff -ur cups-1.1.18/cups/http.c cups-1.1.18.patched/cups/http.c
2 --- cups-1.1.18/cups/http.c Tue Dec 17 13:56:42 2002
3 +++ cups-1.1.18.patched/cups/http.c Mon May 12 16:41:26 2003
5 * default HTTP proxy (if any).
6 * httpCheck() - Check to see if there is a pending response from
8 + * httpWait() - Wait for data available on a connection.
9 * httpClose() - Close an HTTP connection...
10 * httpConnect() - Connect to a HTTP server.
11 * httpConnectEncrypt() - Connect to a HTTP server using encryption.
13 int /* O - 0 = no data, 1 = data available */
14 httpCheck(http_t *http) /* I - HTTP connection */
16 + return (httpWait(http, 0));
21 + * 'httpWait()' - Wait for data available on a connection.
24 +int /* O - 0 = no data, 1 = data available */
25 +httpWait(http_t *http, /* I - HTTP connection */
26 + int msec) /* I - Milliseconds to wait */
28 fd_set input; /* Input set for select() */
29 struct timeval timeout; /* Timeout */
38 + if (SSL_pending((SSL *)(http->tls)))
41 +#endif /* HAVE_LIBSSL */
44 * Then try doing a select() to poll the socket...
48 FD_SET(http->fd, &input);
51 - timeout.tv_usec = 0;
54 + timeout.tv_sec = msec / 1000;
55 + timeout.tv_usec = (msec % 1000) * 1000;
57 - return (select(http->fd + 1, &input, NULL, NULL, &timeout) > 0);
58 + return (select(http->fd + 1, &input, NULL, NULL, &timeout) > 0);
61 + return (select(http->fd + 1, &input, NULL, NULL, NULL) > 0);
66 char buffer[8192]; /* Junk buffer */
69 - while (httpRead(http, buffer, sizeof(buffer)) > 0);
70 + if (http->state != HTTP_WAITING)
72 + while (httpRead(http, buffer, sizeof(buffer)) > 0);
78 * Buffer small reads for better performance...
81 + if (!http->blocking && !httpWait(http, 1000))
84 if (http->data_remaining > sizeof(http->buffer))
85 bytes = sizeof(http->buffer);
92 + http->error = EPIPE;
98 @@ -987,10 +1022,18 @@
103 + if (!http->blocking && !httpWait(http, 1000))
106 bytes = SSL_read((SSL *)(http->tls), buffer, length);
108 #endif /* HAVE_LIBSSL */
111 + if (!http->blocking && !httpWait(http, 1000))
114 DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length));
115 bytes = recv(http->fd, buffer, length, 0);
116 DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes));
117 @@ -1009,6 +1052,11 @@
123 + http->error = EPIPE;
127 if (http->data_remaining == 0)
129 @@ -1247,13 +1295,16 @@
130 * No newline; see if there is more data to be read...
133 + if (!http->blocking && !httpWait(http, 1000))
138 bytes = SSL_read((SSL *)(http->tls), bufend,
139 HTTP_MAX_BUFFER - http->used);
141 #endif /* HAVE_LIBSSL */
142 - bytes = recv(http->fd, bufend, HTTP_MAX_BUFFER - http->used, 0);
143 + bytes = recv(http->fd, bufend, HTTP_MAX_BUFFER - http->used, 0);
147 @@ -1285,8 +1336,7 @@
151 - if (http->blocking)
152 - http->error = EPIPE;
153 + http->error = EPIPE;
157 @@ -1554,6 +1604,7 @@
158 case HTTP_POST_RECV :
161 + case HTTP_POST_SEND :
165 diff -ur cups-1.1.18/cups/http.h cups-1.1.18.patched/cups/http.h
166 --- cups-1.1.18/cups/http.h Tue Dec 17 13:56:42 2002
167 +++ cups-1.1.18.patched/cups/http.h Fri May 9 13:59:10 2003
170 extern char *httpMD5String(const md5_byte_t *, char [33]);
172 +/**** New in CUPS 1.1.19 ****/
173 +extern int httpWait(http_t *http, int msec);
178 diff -ur cups-1.1.18/cups/ipp.c cups-1.1.18.patched/cups/ipp.c
179 --- cups-1.1.18/cups/ipp.c Tue Dec 17 13:56:42 2002
180 +++ cups-1.1.18.patched/cups/ipp.c Fri May 9 14:08:44 2003
181 @@ -2036,7 +2036,14 @@
182 if (http->data_remaining == 0)
184 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
185 - httpGets(len, sizeof(len), http);
188 + * Get the trailing CR LF after the chunk...
191 + if (!httpGets(len, sizeof(len), http))
195 if (http->data_encoding != HTTP_ENCODE_CHUNKED)
197 diff -ur cups-1.1.18/scheduler/client.c cups-1.1.18.patched/scheduler/client.c
198 --- cups-1.1.18/scheduler/client.c Tue Dec 17 14:00:14 2002
199 +++ cups-1.1.18.patched/scheduler/client.c Fri May 9 14:25:52 2003
201 client_t *con; /* New client pointer */
202 unsigned address;/* Address of client */
203 struct hostent *host; /* Host entry for address */
204 + static time_t last_dos = 0;
205 + /* Time of last DoS attack */
208 LogMessage(L_DEBUG2, "AcceptClient(%p) %d NumClients = %d",
211 if (count >= MaxClientsPerHost)
213 - LogMessage(L_WARN, "Possible DoS attack - more than %d clients connecting from %s!",
214 - MaxClientsPerHost, Clients[i].http.hostname);
215 + if ((time(NULL) - last_dos) >= 60)
217 + last_dos = time(NULL);
218 + LogMessage(L_WARN, "Possible DoS attack - more than %d clients connecting from %s!",
219 + MaxClientsPerHost, Clients[i].http.hostname);
223 closesocket(con->http.fd);
225 setsockopt(con->http.fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
228 - * Add the socket to the select() input mask.
229 + * Close this file on all execs...
232 fcntl(con->http.fd, F_SETFD, fcntl(con->http.fd, F_GETFD) | FD_CLOEXEC);
233 @@ -1438,6 +1444,10 @@
237 + else if (con->http.state == HTTP_POST_RECV)
241 else if (con->http.state != HTTP_POST_SEND)
244 @@ -1784,6 +1794,14 @@
245 shutdown(con->http.fd, 0);
249 + * Update the activity time so that we timeout after 30 seconds rather
250 + * then the current Timeout setting (300 by default). This prevents
251 + * some DoS situations...
254 + con->http.activity = time(NULL) - Timeout + 30;
256 LogMessage(L_DEBUG2, "ShutdownClient: Removing fd %d from InputSet...",
259 diff -ur cups-1.1.18/test/run-stp-tests.sh cups-1.1.18.patched/test/run-stp-tests.sh
260 --- cups-1.1.18/test/run-stp-tests.sh Tue Dec 17 14:00:25 2002
261 +++ cups-1.1.18.patched/test/run-stp-tests.sh Fri May 9 14:18:48 2003
264 cat >/tmp/$user/cupsd.conf <<EOF
267 Listen 127.0.0.1:$port
269 ServerRoot /tmp/$user
270 ServerRoot /tmp/$user