1 /*
2 * "$Id: http.c 9233 2010-08-10 06:15:55Z mike $"
3 *
4 * HTTP routines for CUPS.
5 *
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
8 *
9 * This file contains Kerberos support code, copyright 2006 by
10 * Jelmer Vernooij.
11 *
12 * These coded instructions, statements, and computer programs are the
13 * property of Apple Inc. and are protected by Federal copyright
14 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
15 * which should have been included with this file. If this file is
16 * file is missing or damaged, see the license at "http://www.cups.org/".
17 *
18 * This file is subject to the Apple OS-Developed Software exception.
19 *
20 * Contents:
21 *
22 * _httpBIOMethods() - Get the OpenSSL BIO methods for HTTP connections.
23 * httpBlocking() - Set blocking/non-blocking behavior on a connection.
24 * httpCheck() - Check to see if there is a pending response from the
25 * server.
26 * httpClearCookie() - Clear the cookie value(s).
27 * httpClearFields() - Clear HTTP request fields.
28 * httpClose() - Close an HTTP connection.
29 * httpConnect() - Connect to a HTTP server.
30 * httpConnectEncrypt() - Connect to a HTTP server using encryption.
31 * _httpCreate() - Create an unconnected HTTP connection.
32 * httpDelete() - Send a DELETE request to the server.
33 * httpEncryption() - Set the required encryption on the link.
34 * httpError() - Get the last error on a connection.
35 * httpFlush() - Flush data from a HTTP connection.
36 * httpFlushWrite() - Flush data in write buffer.
37 * httpGet() - Send a GET request to the server.
38 * httpGetAuthString() - Get the current authorization string.
39 * httpGetBlocking() - Get the blocking/non-block state of a connection.
40 * httpGetCookie() - Get any cookie data from the response.
41 * httpGetFd() - Get the file descriptor associated with a
42 * connection.
43 * httpGetField() - Get a field value from a request/response.
44 * httpGetLength() - Get the amount of data remaining from the
45 * content-length or transfer-encoding fields.
46 * httpGetLength2() - Get the amount of data remaining from the
47 * content-length or transfer-encoding fields.
48 * httpGetStatus() - Get the status of the last HTTP request.
49 * httpGetSubField() - Get a sub-field value.
50 * httpGetSubField2() - Get a sub-field value.
51 * httpGets() - Get a line of text from a HTTP connection.
52 * httpHead() - Send a HEAD request to the server.
53 * httpInitialize() - Initialize the HTTP interface library and set the
54 * default HTTP proxy (if any).
55 * httpOptions() - Send an OPTIONS request to the server.
56 * httpPost() - Send a POST request to the server.
57 * httpPrintf() - Print a formatted string to a HTTP connection.
58 * httpPut() - Send a PUT request to the server.
59 * httpRead() - Read data from a HTTP connection.
60 * httpRead2() - Read data from a HTTP connection.
61 * _httpReadCDSA() - Read function for the CDSA library.
62 * _httpReadGNUTLS() - Read function for the GNU TLS library.
63 * httpReconnect() - Reconnect to a HTTP server.
64 * httpSetAuthString() - Set the current authorization string.
65 * httpSetCookie() - Set the cookie value(s).
66 * httpSetExpect() - Set the Expect: header in a request.
67 * httpSetField() - Set the value of an HTTP header.
68 * httpSetLength() - Set the content-length and content-encoding.
69 * httpTrace() - Send an TRACE request to the server.
70 * httpUpdate() - Update the current HTTP state for incoming data.
71 * _httpWait() - Wait for data available on a connection (no flush).
72 * httpWait() - Wait for data available on a connection.
73 * httpWrite() - Write data to a HTTP connection.
74 * httpWrite2() - Write data to a HTTP connection.
75 * _httpWriteCDSA() - Write function for the CDSA library.
76 * _httpWriteGNUTLS() - Write function for the GNU TLS library.
77 * http_bio_ctrl() - Control the HTTP connection.
78 * http_bio_free() - Free OpenSSL data.
79 * http_bio_new() - Initialize an OpenSSL BIO structure.
80 * http_bio_puts() - Send a string for OpenSSL.
81 * http_bio_read() - Read data for OpenSSL.
82 * http_bio_write() - Write data for OpenSSL.
83 * http_debug_hex() - Do a hex dump of a buffer.
84 * http_field() - Return the field index for a field name.
85 * http_read_ssl() - Read from a SSL/TLS connection.
86 * http_locking_cb() - Lock/unlock a thread's mutex.
87 * http_send() - Send a request with all fields and the trailing
88 * blank line.
89 * http_setup_ssl() - Set up SSL/TLS support on a connection.
90 * http_shutdown_ssl() - Shut down SSL/TLS on a connection.
91 * http_threadid_cb() - Return the current thread ID.
92 * http_upgrade() - Force upgrade to TLS encryption.
93 * http_write() - Write a buffer to a HTTP connection.
94 * http_write_chunk() - Write a chunked buffer.
95 * http_write_ssl() - Write to a SSL/TLS connection.
96 */
97
98 /*
99 * Include necessary headers...
100 */
101
102 #include "http-private.h"
103 #include "globals.h"
104 #include "debug.h"
105 #include <stdlib.h>
106 #include <fcntl.h>
107 #include <errno.h>
108 #ifndef WIN32
109 # include <signal.h>
110 # include <sys/time.h>
111 # include <sys/resource.h>
112 #endif /* !WIN32 */
113 #ifdef HAVE_POLL
114 # include <sys/poll.h>
115 #endif /* HAVE_POLL */
116
117
118 /*
119 * Some operating systems have done away with the Fxxxx constants for
120 * the fcntl() call; this works around that "feature"...
121 */
122
123 #ifndef FNONBLK
124 # define FNONBLK O_NONBLOCK
125 #endif /* !FNONBLK */
126
127
128 /*
129 * Local functions...
130 */
131
132 #ifdef DEBUG
133 static void http_debug_hex(const char *prefix, const char *buffer,
134 int bytes);
135 #endif /* DEBUG */
136 static http_field_t http_field(const char *name);
137 static int http_send(http_t *http, http_state_t request,
138 const char *uri);
139 static int http_write(http_t *http, const char *buffer,
140 int length);
141 static int http_write_chunk(http_t *http, const char *buffer,
142 int length);
143 #ifdef HAVE_SSL
144 static int http_read_ssl(http_t *http, char *buf, int len);
145 static int http_setup_ssl(http_t *http);
146 static void http_shutdown_ssl(http_t *http);
147 static int http_upgrade(http_t *http);
148 static int http_write_ssl(http_t *http, const char *buf, int len);
149
150 # ifdef HAVE_GNUTLS
151 # ifdef HAVE_PTHREAD_H
152 GCRY_THREAD_OPTION_PTHREAD_IMPL;
153 # endif /* HAVE_PTHREAD_H */
154
155 # elif defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD_H)
156 static pthread_mutex_t *http_locks; /* OpenSSL lock mutexes */
157
158 static void http_locking_cb(int mode, int type, const char *file,
159 int line);
160 static unsigned long http_threadid_cb(void);
161 # endif /* HAVE_GNUTLS */
162 #endif /* HAVE_SSL */
163
164
165 /*
166 * Local globals...
167 */
168
169 static const char * const http_fields[] =
170 {
171 "Accept-Language",
172 "Accept-Ranges",
173 "Authorization",
174 "Connection",
175 "Content-Encoding",
176 "Content-Language",
177 "Content-Length",
178 "Content-Location",
179 "Content-MD5",
180 "Content-Range",
181 "Content-Type",
182 "Content-Version",
183 "Date",
184 "Host",
185 "If-Modified-Since",
186 "If-Unmodified-since",
187 "Keep-Alive",
188 "Last-Modified",
189 "Link",
190 "Location",
191 "Range",
192 "Referer",
193 "Retry-After",
194 "Transfer-Encoding",
195 "Upgrade",
196 "User-Agent",
197 "WWW-Authenticate"
198 };
199 #ifdef DEBUG
200 static const char * const http_states[] =
201 {
202 "HTTP_WAITING",
203 "HTTP_OPTIONS",
204 "HTTP_GET",
205 "HTTP_GET_SEND",
206 "HTTP_HEAD",
207 "HTTP_POST",
208 "HTTP_POST_RECV",
209 "HTTP_POST_SEND",
210 "HTTP_PUT",
211 "HTTP_PUT_RECV",
212 "HTTP_DELETE",
213 "HTTP_TRACE",
214 "HTTP_CLOSE",
215 "HTTP_STATUS"
216 };
217 #endif /* DEBUG */
218
219
220 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
221 /*
222 * BIO methods for OpenSSL...
223 */
224
225 static int http_bio_write(BIO *h, const char *buf, int num);
226 static int http_bio_read(BIO *h, char *buf, int size);
227 static int http_bio_puts(BIO *h, const char *str);
228 static long http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
229 static int http_bio_new(BIO *h);
230 static int http_bio_free(BIO *data);
231
232 static BIO_METHOD http_bio_methods =
233 {
234 BIO_TYPE_SOCKET,
235 "http",
236 http_bio_write,
237 http_bio_read,
238 http_bio_puts,
239 NULL, /* http_bio_gets, */
240 http_bio_ctrl,
241 http_bio_new,
242 http_bio_free,
243 NULL,
244 };
245
246
247 /*
248 * '_httpBIOMethods()' - Get the OpenSSL BIO methods for HTTP connections.
249 */
250
251 BIO_METHOD * /* O - BIO methods for OpenSSL */
_httpBIOMethods(void)252 _httpBIOMethods(void)
253 {
254 return (&http_bio_methods);
255 }
256 #endif /* HAVE_SSL && HAVE_LIBSSL */
257
258
259 /*
260 * 'httpBlocking()' - Set blocking/non-blocking behavior on a connection.
261 */
262
263 void
httpBlocking(http_t * http,int b)264 httpBlocking(http_t *http, /* I - Connection to server */
265 int b) /* I - 1 = blocking, 0 = non-blocking */
266 {
267 if (http)
268 http->blocking = b;
269 }
270
271
272 /*
273 * 'httpCheck()' - Check to see if there is a pending response from the server.
274 */
275
276 int /* O - 0 = no data, 1 = data available */
httpCheck(http_t * http)277 httpCheck(http_t *http) /* I - Connection to server */
278 {
279 return (httpWait(http, 0));
280 }
281
282
283 /*
284 * 'httpClearCookie()' - Clear the cookie value(s).
285 *
286 * @since CUPS 1.1.19/Mac OS X 10.3@
287 */
288
289 void
httpClearCookie(http_t * http)290 httpClearCookie(http_t *http) /* I - Connection to server */
291 {
292 if (!http)
293 return;
294
295 if (http->cookie)
296 {
297 free(http->cookie);
298 http->cookie = NULL;
299 }
300 }
301
302
303 /*
304 * 'httpClearFields()' - Clear HTTP request fields.
305 */
306
307 void
httpClearFields(http_t * http)308 httpClearFields(http_t *http) /* I - Connection to server */
309 {
310 if (http)
311 {
312 memset(http->fields, 0, sizeof(http->fields));
313 if (http->hostname[0] == '/')
314 httpSetField(http, HTTP_FIELD_HOST, "localhost");
315 else
316 httpSetField(http, HTTP_FIELD_HOST, http->hostname);
317
318 if (http->field_authorization)
319 {
320 free(http->field_authorization);
321 http->field_authorization = NULL;
322 }
323
324 http->expect = (http_status_t)0;
325 }
326 }
327
328
329 /*
330 * 'httpClose()' - Close an HTTP connection.
331 */
332
333 void
httpClose(http_t * http)334 httpClose(http_t *http) /* I - Connection to server */
335 {
336 #ifdef HAVE_GSSAPI
337 OM_uint32 minor_status; /* Minor status code */
338 #endif /* HAVE_GSSAPI */
339
340
341 DEBUG_printf(("httpClose(http=%p)", http));
342
343 if (!http)
344 return;
345
346 httpAddrFreeList(http->addrlist);
347
348 if (http->cookie)
349 free(http->cookie);
350
351 #ifdef HAVE_SSL
352 if (http->tls)
353 http_shutdown_ssl(http);
354 #endif /* HAVE_SSL */
355
356 #ifdef WIN32
357 closesocket(http->fd);
358 #else
359 close(http->fd);
360 #endif /* WIN32 */
361
362 #ifdef HAVE_GSSAPI
363 if (http->gssctx != GSS_C_NO_CONTEXT)
364 gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
365
366 if (http->gssname != GSS_C_NO_NAME)
367 gss_release_name(&minor_status, &http->gssname);
368 #endif /* HAVE_GSSAPI */
369
370 #ifdef HAVE_AUTHORIZATION_H
371 if (http->auth_ref)
372 AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults);
373 #endif /* HAVE_AUTHORIZATION_H */
374
375 httpClearFields(http);
376
377 if (http->authstring && http->authstring != http->_authstring)
378 free(http->authstring);
379
380 free(http);
381 }
382
383
384 /*
385 * 'httpConnect()' - Connect to a HTTP server.
386 *
387 * This function is deprecated - use @link httpConnectEncrypt@ instead.
388 *
389 * @deprecated@
390 */
391
392 http_t * /* O - New HTTP connection */
httpConnect(const char * host,int port)393 httpConnect(const char *host, /* I - Host to connect to */
394 int port) /* I - Port number */
395 {
396 return (httpConnectEncrypt(host, port, HTTP_ENCRYPT_IF_REQUESTED));
397 }
398
399
400 /*
401 * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
402 */
403
404 http_t * /* O - New HTTP connection */
httpConnectEncrypt(const char * host,int port,http_encryption_t encryption)405 httpConnectEncrypt(
406 const char *host, /* I - Host to connect to */
407 int port, /* I - Port number */
408 http_encryption_t encryption) /* I - Type of encryption to use */
409 {
410 http_t *http; /* New HTTP connection */
411
412
413 DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encryption=%d)",
414 host, port, encryption));
415
416 /*
417 * Create the HTTP structure...
418 */
419
420 if ((http = _httpCreate(host, port, encryption)) == NULL)
421 return (NULL);
422
423 /*
424 * Connect to the remote system...
425 */
426
427 if (!httpReconnect(http))
428 return (http);
429
430 /*
431 * Could not connect to any known address - bail out!
432 */
433
434 httpAddrFreeList(http->addrlist);
435
436 free(http);
437
438 return (NULL);
439 }
440
441
442 /*
443 * '_httpCreate()' - Create an unconnected HTTP connection.
444 */
445
446 http_t * /* O - HTTP connection */
_httpCreate(const char * host,int port,http_encryption_t encryption)447 _httpCreate(
448 const char *host, /* I - Hostname */
449 int port, /* I - Port number */
450 http_encryption_t encryption) /* I - Encryption to use */
451 {
452 http_t *http; /* New HTTP connection */
453 http_addrlist_t *addrlist; /* Host address data */
454 char service[255]; /* Service name */
455
456
457 DEBUG_printf(("4_httpCreate(host=\"%s\", port=%d, encryption=%d)",
458 host, port, encryption));
459
460 if (!host)
461 return (NULL);
462
463 httpInitialize();
464
465 /*
466 * Lookup the host...
467 */
468
469 sprintf(service, "%d", port);
470
471 if ((addrlist = httpAddrGetList(host, AF_UNSPEC, service)) == NULL)
472 return (NULL);
473
474 /*
475 * Allocate memory for the structure...
476 */
477
478 if ((http = calloc(sizeof(http_t), 1)) == NULL)
479 {
480 httpAddrFreeList(addrlist);
481 return (NULL);
482 }
483
484 /*
485 * Initialize the HTTP data...
486 */
487
488 http->activity = time(NULL);
489 http->addrlist = addrlist;
490 http->blocking = 1;
491 http->fd = -1;
492 #ifdef HAVE_GSSAPI
493 http->gssctx = GSS_C_NO_CONTEXT;
494 http->gssname = GSS_C_NO_NAME;
495 #endif /* HAVE_GSSAPI */
496 http->version = HTTP_1_1;
497
498 strlcpy(http->hostname, host, sizeof(http->hostname));
499
500 if (port == 443) /* Always use encryption for https */
501 http->encryption = HTTP_ENCRYPT_ALWAYS;
502 else
503 http->encryption = encryption;
504
505 /*
506 * Return the new structure...
507 */
508
509 return (http);
510 }
511
512
513 /*
514 * 'httpDelete()' - Send a DELETE request to the server.
515 */
516
517 int /* O - Status of call (0 = success) */
httpDelete(http_t * http,const char * uri)518 httpDelete(http_t *http, /* I - Connection to server */
519 const char *uri) /* I - URI to delete */
520 {
521 return (http_send(http, HTTP_DELETE, uri));
522 }
523
524
525 /*
526 * 'httpEncryption()' - Set the required encryption on the link.
527 */
528
529 int /* O - -1 on error, 0 on success */
httpEncryption(http_t * http,http_encryption_t e)530 httpEncryption(http_t *http, /* I - Connection to server */
531 http_encryption_t e) /* I - New encryption preference */
532 {
533 DEBUG_printf(("httpEncryption(http=%p, e=%d)", http, e));
534
535 #ifdef HAVE_SSL
536 if (!http)
537 return (0);
538
539 http->encryption = e;
540
541 if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||
542 (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))
543 return (httpReconnect(http));
544 else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
545 return (http_upgrade(http));
546 else
547 return (0);
548 #else
549 if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)
550 return (-1);
551 else
552 return (0);
553 #endif /* HAVE_SSL */
554 }
555
556
557 /*
558 * 'httpError()' - Get the last error on a connection.
559 */
560
561 int /* O - Error code (errno) value */
httpError(http_t * http)562 httpError(http_t *http) /* I - Connection to server */
563 {
564 if (http)
565 return (http->error);
566 else
567 return (EINVAL);
568 }
569
570
571 /*
572 * 'httpFlush()' - Flush data from a HTTP connection.
573 */
574
575 void
httpFlush(http_t * http)576 httpFlush(http_t *http) /* I - Connection to server */
577 {
578 char buffer[8192]; /* Junk buffer */
579 int blocking; /* To block or not to block */
580 http_state_t oldstate; /* Old state */
581
582
583 DEBUG_printf(("httpFlush(http=%p), state=%s", http,
584 http_states[http->state]));
585
586 /*
587 * Temporarily set non-blocking mode so we don't get stuck in httpRead()...
588 */
589
590 blocking = http->blocking;
591 http->blocking = 0;
592
593 /*
594 * Read any data we can...
595 */
596
597 oldstate = http->state;
598 while (httpRead2(http, buffer, sizeof(buffer)) > 0);
599
600 /*
601 * Restore blocking and reset the connection if we didn't get all of
602 * the remaining data...
603 */
604
605 http->blocking = blocking;
606
607 if (http->state == oldstate && http->state != HTTP_WAITING && http->fd >= 0)
608 {
609 /*
610 * Didn't get the data back, so close the current connection.
611 */
612
613 http->state = HTTP_WAITING;
614
615 #ifdef HAVE_SSL
616 if (http->tls)
617 http_shutdown_ssl(http);
618 #endif /* HAVE_SSL */
619
620 #ifdef WIN32
621 closesocket(http->fd);
622 #else
623 close(http->fd);
624 #endif /* WIN32 */
625
626 http->fd = -1;
627 }
628 }
629
630
631 /*
632 * 'httpFlushWrite()' - Flush data in write buffer.
633 *
634 * @since CUPS 1.2/Mac OS X 10.5@
635 */
636
637 int /* O - Bytes written or -1 on error */
httpFlushWrite(http_t * http)638 httpFlushWrite(http_t *http) /* I - Connection to server */
639 {
640 int bytes; /* Bytes written */
641
642
643 DEBUG_printf(("httpFlushWrite(http=%p)", http));
644
645 if (!http || !http->wused)
646 return (0);
647
648 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
649 bytes = http_write_chunk(http, http->wbuffer, http->wused);
650 else
651 bytes = http_write(http, http->wbuffer, http->wused);
652
653 http->wused = 0;
654
655 return (bytes);
656 }
657
658
659 /*
660 * 'httpGet()' - Send a GET request to the server.
661 */
662
663 int /* O - Status of call (0 = success) */
httpGet(http_t * http,const char * uri)664 httpGet(http_t *http, /* I - Connection to server */
665 const char *uri) /* I - URI to get */
666 {
667 return (http_send(http, HTTP_GET, uri));
668 }
669
670
671 /*
672 * 'httpGetAuthString()' - Get the current authorization string.
673 *
674 * The authorization string is set by cupsDoAuthentication() and
675 * httpSetAuthString(). Use httpGetAuthString() to retrieve the
676 * string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION
677 * value.
678 *
679 * @since CUPS 1.3/Mac OS X 10.5@
680 */
681
682 char * /* O - Authorization string */
httpGetAuthString(http_t * http)683 httpGetAuthString(http_t *http) /* I - Connection to server */
684 {
685 if (http)
686 return (http->authstring);
687 else
688 return (NULL);
689 }
690
691
692 /*
693 * 'httpGetBlocking()' - Get the blocking/non-block state of a connection.
694 *
695 * @since CUPS 1.2/Mac OS X 10.5@
696 */
697
698 int /* O - 1 if blocking, 0 if non-blocking */
httpGetBlocking(http_t * http)699 httpGetBlocking(http_t *http) /* I - Connection to server */
700 {
701 return (http ? http->blocking : 0);
702 }
703
704
705 /*
706 * 'httpGetCookie()' - Get any cookie data from the response.
707 *
708 * @since CUPS 1.1.19/Mac OS X 10.3@
709 */
710
711 const char * /* O - Cookie data or NULL */
httpGetCookie(http_t * http)712 httpGetCookie(http_t *http) /* I - HTTP connecion */
713 {
714 return (http ? http->cookie : NULL);
715 }
716
717
718 /*
719 * 'httpGetFd()' - Get the file descriptor associated with a connection.
720 *
721 * @since CUPS 1.2/Mac OS X 10.5@
722 */
723
724 int /* O - File descriptor or -1 if none */
httpGetFd(http_t * http)725 httpGetFd(http_t *http) /* I - Connection to server */
726 {
727 return (http ? http->fd : -1);
728 }
729
730
731 /*
732 * 'httpGetField()' - Get a field value from a request/response.
733 */
734
735 const char * /* O - Field value */
httpGetField(http_t * http,http_field_t field)736 httpGetField(http_t *http, /* I - Connection to server */
737 http_field_t field) /* I - Field to get */
738 {
739 if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
740 return (NULL);
741 else if (field == HTTP_FIELD_AUTHORIZATION &&
742 http->field_authorization)
743 {
744 /*
745 * Special case for WWW-Authenticate: as its contents can be
746 * longer than HTTP_MAX_VALUE...
747 */
748
749 return (http->field_authorization);
750 }
751 else
752 return (http->fields[field]);
753 }
754
755
756 /*
757 * 'httpGetLength()' - Get the amount of data remaining from the
758 * content-length or transfer-encoding fields.
759 *
760 * This function is deprecated and will not return lengths larger than
761 * 2^31 - 1; use httpGetLength2() instead.
762 *
763 * @deprecated@
764 */
765
766 int /* O - Content length */
httpGetLength(http_t * http)767 httpGetLength(http_t *http) /* I - Connection to server */
768 {
769 /*
770 * Get the read content length and return the 32-bit value.
771 */
772
773 if (http)
774 {
775 httpGetLength2(http);
776
777 return (http->_data_remaining);
778 }
779 else
780 return (-1);
781 }
782
783
784 /*
785 * 'httpGetLength2()' - Get the amount of data remaining from the
786 * content-length or transfer-encoding fields.
787 *
788 * This function returns the complete content length, even for
789 * content larger than 2^31 - 1.
790 *
791 * @since CUPS 1.2/Mac OS X 10.5@
792 */
793
794 off_t /* O - Content length */
httpGetLength2(http_t * http)795 httpGetLength2(http_t *http) /* I - Connection to server */
796 {
797 DEBUG_printf(("2httpGetLength2(http=%p), state=%s", http,
798 http_states[http->state]));
799
800 if (!http)
801 return (-1);
802
803 if (!strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked"))
804 {
805 DEBUG_puts("4httpGetLength2: chunked request!");
806
807 http->data_encoding = HTTP_ENCODE_CHUNKED;
808 http->data_remaining = 0;
809 }
810 else
811 {
812 http->data_encoding = HTTP_ENCODE_LENGTH;
813
814 /*
815 * The following is a hack for HTTP servers that don't send a
816 * content-length or transfer-encoding field...
817 *
818 * If there is no content-length then the connection must close
819 * after the transfer is complete...
820 */
821
822 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0])
823 {
824 /*
825 * Default content length is 0 for errors and 2^31-1 for other
826 * successful requests...
827 */
828
829 if (http->status >= HTTP_MULTIPLE_CHOICES)
830 http->data_remaining = 0;
831 else
832 http->data_remaining = 2147483647;
833 }
834 else
835 http->data_remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH],
836 NULL, 10);
837
838 DEBUG_printf(("4httpGetLength2: content_length=" CUPS_LLFMT,
839 CUPS_LLCAST http->data_remaining));
840 }
841
842 if (http->data_remaining <= INT_MAX)
843 http->_data_remaining = (int)http->data_remaining;
844 else
845 http->_data_remaining = INT_MAX;
846
847 return (http->data_remaining);
848 }
849
850
851 /*
852 * 'httpGetStatus()' - Get the status of the last HTTP request.
853 *
854 * @since CUPS 1.2/Mac OS X 10.5@
855 */
856
857 http_status_t /* O - HTTP status */
httpGetStatus(http_t * http)858 httpGetStatus(http_t *http) /* I - Connection to server */
859 {
860 return (http ? http->status : HTTP_ERROR);
861 }
862
863
864 /*
865 * 'httpGetSubField()' - Get a sub-field value.
866 *
867 * @deprecated@
868 */
869
870 char * /* O - Value or NULL */
httpGetSubField(http_t * http,http_field_t field,const char * name,char * value)871 httpGetSubField(http_t *http, /* I - Connection to server */
872 http_field_t field, /* I - Field index */
873 const char *name, /* I - Name of sub-field */
874 char *value) /* O - Value string */
875 {
876 return (httpGetSubField2(http, field, name, value, HTTP_MAX_VALUE));
877 }
878
879
880 /*
881 * 'httpGetSubField2()' - Get a sub-field value.
882 *
883 * @since CUPS 1.2/Mac OS X 10.5@
884 */
885
886 char * /* O - Value or NULL */
httpGetSubField2(http_t * http,http_field_t field,const char * name,char * value,int valuelen)887 httpGetSubField2(http_t *http, /* I - Connection to server */
888 http_field_t field, /* I - Field index */
889 const char *name, /* I - Name of sub-field */
890 char *value, /* O - Value string */
891 int valuelen) /* I - Size of value buffer */
892 {
893 const char *fptr; /* Pointer into field */
894 char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */
895 *ptr, /* Pointer into string buffer */
896 *end; /* End of value buffer */
897
898 DEBUG_printf(("2httpGetSubField2(http=%p, field=%d, name=\"%s\", value=%p, "
899 "valuelen=%d)", http, field, name, value, valuelen));
900
901 if (!http || !name || !value || valuelen < 2 ||
902 field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
903 return (NULL);
904
905 end = value + valuelen - 1;
906
907 for (fptr = http->fields[field]; *fptr;)
908 {
909 /*
910 * Skip leading whitespace...
911 */
912
913 while (_cups_isspace(*fptr))
914 fptr ++;
915
916 if (*fptr == ',')
917 {
918 fptr ++;
919 continue;
920 }
921
922 /*
923 * Get the sub-field name...
924 */
925
926 for (ptr = temp;
927 *fptr && *fptr != '=' && !_cups_isspace(*fptr) &&
928 ptr < (temp + sizeof(temp) - 1);
929 *ptr++ = *fptr++);
930
931 *ptr = '\0';
932
933 DEBUG_printf(("4httpGetSubField2: name=\"%s\"", temp));
934
935 /*
936 * Skip trailing chars up to the '='...
937 */
938
939 while (_cups_isspace(*fptr))
940 fptr ++;
941
942 if (!*fptr)
943 break;
944
945 if (*fptr != '=')
946 continue;
947
948 /*
949 * Skip = and leading whitespace...
950 */
951
952 fptr ++;
953
954 while (_cups_isspace(*fptr))
955 fptr ++;
956
957 if (*fptr == '\"')
958 {
959 /*
960 * Read quoted string...
961 */
962
963 for (ptr = value, fptr ++;
964 *fptr && *fptr != '\"' && ptr < end;
965 *ptr++ = *fptr++);
966
967 *ptr = '\0';
968
969 while (*fptr && *fptr != '\"')
970 fptr ++;
971
972 if (*fptr)
973 fptr ++;
974 }
975 else
976 {
977 /*
978 * Read unquoted string...
979 */
980
981 for (ptr = value;
982 *fptr && !_cups_isspace(*fptr) && *fptr != ',' && ptr < end;
983 *ptr++ = *fptr++);
984
985 *ptr = '\0';
986
987 while (*fptr && !_cups_isspace(*fptr) && *fptr != ',')
988 fptr ++;
989 }
990
991 DEBUG_printf(("4httpGetSubField2: value=\"%s\"", value));
992
993 /*
994 * See if this is the one...
995 */
996
997 if (!strcmp(name, temp))
998 {
999 DEBUG_printf(("3httpGetSubField2: Returning \"%s\"", value));
1000 return (value);
1001 }
1002 }
1003
1004 value[0] = '\0';
1005
1006 DEBUG_puts("3httpGetSubField2: Returning NULL");
1007
1008 return (NULL);
1009 }
1010
1011
1012 /*
1013 * 'httpGets()' - Get a line of text from a HTTP connection.
1014 */
1015
1016 char * /* O - Line or NULL */
httpGets(char * line,int length,http_t * http)1017 httpGets(char *line, /* I - Line to read into */
1018 int length, /* I - Max length of buffer */
1019 http_t *http) /* I - Connection to server */
1020 {
1021 char *lineptr, /* Pointer into line */
1022 *lineend, /* End of line */
1023 *bufptr, /* Pointer into input buffer */
1024 *bufend; /* Pointer to end of buffer */
1025 int bytes, /* Number of bytes read */
1026 eol; /* End-of-line? */
1027
1028
1029 DEBUG_printf(("2httpGets(line=%p, length=%d, http=%p)", line, length, http));
1030
1031 if (http == NULL || line == NULL)
1032 return (NULL);
1033
1034 /*
1035 * Read a line from the buffer...
1036 */
1037
1038 http->error = 0;
1039 lineptr = line;
1040 lineend = line + length - 1;
1041 eol = 0;
1042
1043 while (lineptr < lineend)
1044 {
1045 /*
1046 * Pre-load the buffer as needed...
1047 */
1048
1049 #ifdef WIN32
1050 WSASetLastError(0);
1051 #else
1052 errno = 0;
1053 #endif /* WIN32 */
1054
1055 while (http->used == 0)
1056 {
1057 /*
1058 * No newline; see if there is more data to be read...
1059 */
1060
1061 if (!http->blocking && !_httpWait(http, 10000, 1))
1062 {
1063 DEBUG_puts("3httpGets: Timed out!");
1064 #ifdef WIN32
1065 http->error = WSAETIMEDOUT;
1066 #else
1067 http->error = ETIMEDOUT;
1068 #endif /* WIN32 */
1069 return (NULL);
1070 }
1071
1072 #ifdef HAVE_SSL
1073 if (http->tls)
1074 bytes = http_read_ssl(http, http->buffer + http->used,
1075 HTTP_MAX_BUFFER - http->used);
1076 else
1077 #endif /* HAVE_SSL */
1078 bytes = recv(http->fd, http->buffer + http->used,
1079 HTTP_MAX_BUFFER - http->used, 0);
1080
1081 DEBUG_printf(("4httpGets: read %d bytes...", bytes));
1082
1083 if (bytes < 0)
1084 {
1085 /*
1086 * Nope, can't get a line this time...
1087 */
1088
1089 #ifdef WIN32
1090 if (WSAGetLastError() != http->error)
1091 {
1092 http->error = WSAGetLastError();
1093 continue;
1094 }
1095
1096 DEBUG_printf(("3httpGets: recv() error %d!", WSAGetLastError()));
1097 #else
1098 DEBUG_printf(("3httpGets: recv() error %d!", errno));
1099
1100 if (errno == EINTR || errno == EAGAIN)
1101 continue;
1102 else if (errno != http->error)
1103 {
1104 http->error = errno;
1105 continue;
1106 }
1107 #endif /* WIN32 */
1108
1109 return (NULL);
1110 }
1111 else if (bytes == 0)
1112 {
1113 http->error = EPIPE;
1114
1115 return (NULL);
1116 }
1117
1118 /*
1119 * Yup, update the amount used...
1120 */
1121
1122 http->used += bytes;
1123 }
1124
1125 /*
1126 * Now copy as much of the current line as possible...
1127 */
1128
1129 for (bufptr = http->buffer, bufend = http->buffer + http->used;
1130 lineptr < lineend && bufptr < bufend;)
1131 {
1132 if (*bufptr == 0x0a)
1133 {
1134 eol = 1;
1135 bufptr ++;
1136 break;
1137 }
1138 else if (*bufptr == 0x0d)
1139 bufptr ++;
1140 else
1141 *lineptr++ = *bufptr++;
1142 }
1143
1144 http->used -= (int)(bufptr - http->buffer);
1145 if (http->used > 0)
1146 memmove(http->buffer, bufptr, http->used);
1147
1148 if (eol)
1149 {
1150 /*
1151 * End of line...
1152 */
1153
1154 http->activity = time(NULL);
1155
1156 *lineptr = '\0';
1157
1158 DEBUG_printf(("3httpGets: Returning \"%s\"", line));
1159
1160 return (line);
1161 }
1162 }
1163
1164 DEBUG_puts("3httpGets: No new line available!");
1165
1166 return (NULL);
1167 }
1168
1169
1170 /*
1171 * 'httpHead()' - Send a HEAD request to the server.
1172 */
1173
1174 int /* O - Status of call (0 = success) */
httpHead(http_t * http,const char * uri)1175 httpHead(http_t *http, /* I - Connection to server */
1176 const char *uri) /* I - URI for head */
1177 {
1178 DEBUG_printf(("httpHead(http=%p, uri=\"%s\")", http, uri));
1179 return (http_send(http, HTTP_HEAD, uri));
1180 }
1181
1182
1183 /*
1184 * 'httpInitialize()' - Initialize the HTTP interface library and set the
1185 * default HTTP proxy (if any).
1186 */
1187
1188 void
httpInitialize(void)1189 httpInitialize(void)
1190 {
1191 static int initialized = 0; /* Have we been called before? */
1192 #ifdef WIN32
1193 WSADATA winsockdata; /* WinSock data */
1194 #endif /* WIN32 */
1195 #ifdef HAVE_LIBSSL
1196 int i; /* Looping var */
1197 unsigned char data[1024]; /* Seed data */
1198 #endif /* HAVE_LIBSSL */
1199
1200
1201 if (initialized)
1202 return;
1203
1204 #ifdef WIN32
1205 WSAStartup(MAKEWORD(2,2), &winsockdata);
1206
1207 #elif !defined(SO_NOSIGPIPE)
1208 /*
1209 * Ignore SIGPIPE signals...
1210 */
1211
1212 # ifdef HAVE_SIGSET
1213 sigset(SIGPIPE, SIG_IGN);
1214
1215 # elif defined(HAVE_SIGACTION)
1216 struct sigaction action; /* POSIX sigaction data */
1217
1218
1219 memset(&action, 0, sizeof(action));
1220 action.sa_handler = SIG_IGN;
1221 sigaction(SIGPIPE, &action, NULL);
1222
1223 # else
1224 signal(SIGPIPE, SIG_IGN);
1225 # endif /* !SO_NOSIGPIPE */
1226 #endif /* WIN32 */
1227
1228 #ifdef HAVE_GNUTLS
1229 /*
1230 * Make sure we handle threading properly...
1231 */
1232
1233 # ifdef HAVE_PTHREAD_H
1234 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
1235 # endif /* HAVE_PTHREAD_H */
1236
1237 /*
1238 * Initialize GNU TLS...
1239 */
1240
1241 gnutls_global_init();
1242
1243 #elif defined(HAVE_LIBSSL)
1244 /*
1245 * Initialize OpenSSL...
1246 */
1247
1248 SSL_load_error_strings();
1249 SSL_library_init();
1250
1251 /*
1252 * Set the threading callbacks...
1253 */
1254
1255 # ifdef HAVE_PTHREAD_H
1256 http_locks = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t));
1257
1258 for (i = 0; i < CRYPTO_num_locks(); i ++)
1259 pthread_mutex_init(http_locks + i, NULL);
1260
1261 CRYPTO_set_id_callback(http_threadid_cb);
1262 CRYPTO_set_locking_callback(http_locking_cb);
1263 # endif /* HAVE_PTHREAD_H */
1264
1265 /*
1266 * Using the current time is a dubious random seed, but on some systems
1267 * it is the best we can do (on others, this seed isn't even used...)
1268 */
1269
1270 CUPS_SRAND(time(NULL));
1271
1272 for (i = 0; i < sizeof(data); i ++)
1273 data[i] = CUPS_RAND();
1274
1275 RAND_seed(data, sizeof(data));
1276 #endif /* HAVE_GNUTLS */
1277
1278 initialized = 1;
1279 }
1280
1281
1282 /*
1283 * 'httpOptions()' - Send an OPTIONS request to the server.
1284 */
1285
1286 int /* O - Status of call (0 = success) */
httpOptions(http_t * http,const char * uri)1287 httpOptions(http_t *http, /* I - Connection to server */
1288 const char *uri) /* I - URI for options */
1289 {
1290 return (http_send(http, HTTP_OPTIONS, uri));
1291 }
1292
1293
1294 /*
1295 * 'httpPost()' - Send a POST request to the server.
1296 */
1297
1298 int /* O - Status of call (0 = success) */
httpPost(http_t * http,const char * uri)1299 httpPost(http_t *http, /* I - Connection to server */
1300 const char *uri) /* I - URI for post */
1301 {
1302 return (http_send(http, HTTP_POST, uri));
1303 }
1304
1305
1306 /*
1307 * 'httpPrintf()' - Print a formatted string to a HTTP connection.
1308 *
1309 * @private@
1310 */
1311
1312 int /* O - Number of bytes written */
httpPrintf(http_t * http,const char * format,...)1313 httpPrintf(http_t *http, /* I - Connection to server */
1314 const char *format, /* I - printf-style format string */
1315 ...) /* I - Additional args as needed */
1316 {
1317 int bytes; /* Number of bytes to write */
1318 char buf[16384]; /* Buffer for formatted string */
1319 va_list ap; /* Variable argument pointer */
1320
1321
1322 DEBUG_printf(("2httpPrintf(http=%p, format=\"%s\", ...)", http, format));
1323
1324 va_start(ap, format);
1325 bytes = vsnprintf(buf, sizeof(buf), format, ap);
1326 va_end(ap);
1327
1328 DEBUG_printf(("3httpPrintf: %s", buf));
1329
1330 if (http->data_encoding == HTTP_ENCODE_FIELDS)
1331 return (httpWrite2(http, buf, bytes));
1332 else
1333 {
1334 if (http->wused)
1335 {
1336 DEBUG_puts("4httpPrintf: flushing existing data...");
1337
1338 if (httpFlushWrite(http) < 0)
1339 return (-1);
1340 }
1341
1342 return (http_write(http, buf, bytes));
1343 }
1344 }
1345
1346
1347 /*
1348 * 'httpPut()' - Send a PUT request to the server.
1349 */
1350
1351 int /* O - Status of call (0 = success) */
httpPut(http_t * http,const char * uri)1352 httpPut(http_t *http, /* I - Connection to server */
1353 const char *uri) /* I - URI to put */
1354 {
1355 DEBUG_printf(("httpPut(http=%p, uri=\"%s\")", http, uri));
1356 return (http_send(http, HTTP_PUT, uri));
1357 }
1358
1359
1360 /*
1361 * 'httpRead()' - Read data from a HTTP connection.
1362 *
1363 * This function is deprecated. Use the httpRead2() function which can
1364 * read more than 2GB of data.
1365 *
1366 * @deprecated@
1367 */
1368
1369 int /* O - Number of bytes read */
httpRead(http_t * http,char * buffer,int length)1370 httpRead(http_t *http, /* I - Connection to server */
1371 char *buffer, /* I - Buffer for data */
1372 int length) /* I - Maximum number of bytes */
1373 {
1374 return ((int)httpRead2(http, buffer, length));
1375 }
1376
1377
1378 /*
1379 * 'httpRead2()' - Read data from a HTTP connection.
1380 *
1381 * @since CUPS 1.2/Mac OS X 10.5@
1382 */
1383
1384 ssize_t /* O - Number of bytes read */
httpRead2(http_t * http,char * buffer,size_t length)1385 httpRead2(http_t *http, /* I - Connection to server */
1386 char *buffer, /* I - Buffer for data */
1387 size_t length) /* I - Maximum number of bytes */
1388 {
1389 ssize_t bytes; /* Bytes read */
1390 char len[32]; /* Length string */
1391
1392
1393 DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
1394 http, buffer, CUPS_LLCAST length));
1395
1396 if (http == NULL || buffer == NULL)
1397 return (-1);
1398
1399 http->activity = time(NULL);
1400 http->error = 0;
1401
1402 if (length <= 0)
1403 return (0);
1404
1405 if (http->data_encoding == HTTP_ENCODE_CHUNKED &&
1406 http->data_remaining <= 0)
1407 {
1408 DEBUG_puts("2httpRead2: Getting chunk length...");
1409
1410 if (httpGets(len, sizeof(len), http) == NULL)
1411 {
1412 DEBUG_puts("1httpRead2: Could not get length!");
1413 return (0);
1414 }
1415
1416 http->data_remaining = strtoll(len, NULL, 16);
1417 if (http->data_remaining < 0)
1418 {
1419 DEBUG_puts("1httpRead2: Negative chunk length!");
1420 return (0);
1421 }
1422 }
1423
1424 DEBUG_printf(("2httpRead2: data_remaining=" CUPS_LLFMT,
1425 CUPS_LLCAST http->data_remaining));
1426
1427 if (http->data_remaining <= 0)
1428 {
1429 /*
1430 * A zero-length chunk ends a transfer; unless we are reading POST
1431 * data, go idle...
1432 */
1433
1434 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1435 httpGets(len, sizeof(len), http);
1436
1437 if (http->state == HTTP_POST_RECV)
1438 http->state ++;
1439 else
1440 http->state = HTTP_WAITING;
1441
1442 /*
1443 * Prevent future reads for this request...
1444 */
1445
1446 http->data_encoding = HTTP_ENCODE_LENGTH;
1447
1448 return (0);
1449 }
1450 else if (length > (size_t)http->data_remaining)
1451 length = (size_t)http->data_remaining;
1452
1453 if (http->used == 0 && length <= 256)
1454 {
1455 /*
1456 * Buffer small reads for better performance...
1457 */
1458
1459 if (!http->blocking && !httpWait(http, 10000))
1460 return (0);
1461
1462 if (http->data_remaining > sizeof(http->buffer))
1463 bytes = sizeof(http->buffer);
1464 else
1465 bytes = http->data_remaining;
1466
1467 #ifdef HAVE_SSL
1468 if (http->tls)
1469 bytes = http_read_ssl(http, http->buffer, bytes);
1470 else
1471 #endif /* HAVE_SSL */
1472 {
1473 DEBUG_printf(("2httpRead2: reading %d bytes from socket into buffer...",
1474 (int)bytes));
1475
1476 bytes = recv(http->fd, http->buffer, bytes, 0);
1477
1478 DEBUG_printf(("2httpRead2: read %d bytes from socket into buffer...",
1479 (int)bytes));
1480 }
1481
1482 if (bytes > 0)
1483 http->used = bytes;
1484 else if (bytes < 0)
1485 {
1486 #ifdef WIN32
1487 http->error = WSAGetLastError();
1488 return (-1);
1489 #else
1490 if (errno != EINTR && errno != EAGAIN)
1491 {
1492 http->error = errno;
1493 return (-1);
1494 }
1495 #endif /* WIN32 */
1496 }
1497 else
1498 {
1499 http->error = EPIPE;
1500 return (0);
1501 }
1502 }
1503
1504 if (http->used > 0)
1505 {
1506 if (length > (size_t)http->used)
1507 length = (size_t)http->used;
1508
1509 bytes = (ssize_t)length;
1510
1511 DEBUG_printf(("2httpRead2: grabbing %d bytes from input buffer...",
1512 (int)bytes));
1513
1514 memcpy(buffer, http->buffer, length);
1515 http->used -= (int)length;
1516
1517 if (http->used > 0)
1518 memmove(http->buffer, http->buffer + length, http->used);
1519 }
1520 #ifdef HAVE_SSL
1521 else if (http->tls)
1522 {
1523 if (!http->blocking && !httpWait(http, 10000))
1524 return (0);
1525
1526 bytes = (ssize_t)http_read_ssl(http, buffer, (int)length);
1527 }
1528 #endif /* HAVE_SSL */
1529 else
1530 {
1531 if (!http->blocking && !httpWait(http, 10000))
1532 return (0);
1533
1534 DEBUG_printf(("2httpRead2: reading " CUPS_LLFMT " bytes from socket...",
1535 CUPS_LLCAST length));
1536
1537 #ifdef WIN32
1538 bytes = (ssize_t)recv(http->fd, buffer, (int)length, 0);
1539 #else
1540 while ((bytes = recv(http->fd, buffer, length, 0)) < 0)
1541 if (errno != EINTR && errno != EAGAIN)
1542 break;
1543 #endif /* WIN32 */
1544
1545 DEBUG_printf(("2httpRead2: read " CUPS_LLFMT " bytes from socket...",
1546 CUPS_LLCAST bytes));
1547 }
1548
1549 if (bytes > 0)
1550 {
1551 http->data_remaining -= bytes;
1552
1553 if (http->data_remaining <= INT_MAX)
1554 http->_data_remaining = (int)http->data_remaining;
1555 else
1556 http->_data_remaining = INT_MAX;
1557 }
1558 else if (bytes < 0)
1559 {
1560 #ifdef WIN32
1561 http->error = WSAGetLastError();
1562 #else
1563 if (errno == EINTR || errno == EAGAIN)
1564 bytes = 0;
1565 else
1566 http->error = errno;
1567 #endif /* WIN32 */
1568 }
1569 else
1570 {
1571 http->error = EPIPE;
1572 return (0);
1573 }
1574
1575 if (http->data_remaining == 0)
1576 {
1577 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1578 httpGets(len, sizeof(len), http);
1579
1580 if (http->data_encoding != HTTP_ENCODE_CHUNKED)
1581 {
1582 if (http->state == HTTP_POST_RECV)
1583 http->state ++;
1584 else
1585 http->state = HTTP_WAITING;
1586 }
1587 }
1588
1589 #ifdef DEBUG
1590 http_debug_hex("httpRead2", buffer, (int)bytes);
1591 #endif /* DEBUG */
1592
1593 return (bytes);
1594 }
1595
1596
1597 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
1598 /*
1599 * '_httpReadCDSA()' - Read function for the CDSA library.
1600 */
1601
1602 OSStatus /* O - -1 on error, 0 on success */
_httpReadCDSA(SSLConnectionRef connection,void * data,size_t * dataLength)1603 _httpReadCDSA(
1604 SSLConnectionRef connection, /* I - SSL/TLS connection */
1605 void *data, /* I - Data buffer */
1606 size_t *dataLength) /* IO - Number of bytes */
1607 {
1608 OSStatus result; /* Return value */
1609 ssize_t bytes; /* Number of bytes read */
1610 http_t *http; /* HTTP connection */
1611
1612
1613 http = (http_t *)connection;
1614
1615 if (!http->blocking)
1616 {
1617 /*
1618 * Make sure we have data before we read...
1619 */
1620
1621 if (!_httpWait(http, 10000, 0))
1622 {
1623 http->error = ETIMEDOUT;
1624 return (-1);
1625 }
1626 }
1627
1628 do
1629 {
1630 bytes = recv(http->fd, data, *dataLength, 0);
1631 }
1632 while (bytes == -1 && (errno == EINTR || errno == EAGAIN));
1633
1634 if (bytes == *dataLength)
1635 {
1636 result = 0;
1637 }
1638 else if (bytes > 0)
1639 {
1640 *dataLength = bytes;
1641 result = errSSLWouldBlock;
1642 }
1643 else
1644 {
1645 *dataLength = 0;
1646
1647 if (bytes == 0)
1648 result = errSSLClosedGraceful;
1649 else if (errno == EAGAIN)
1650 result = errSSLWouldBlock;
1651 else
1652 result = errSSLClosedAbort;
1653 }
1654
1655 return (result);
1656 }
1657 #endif /* HAVE_SSL && HAVE_CDSASSL */
1658
1659
1660 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
1661 /*
1662 * '_httpReadGNUTLS()' - Read function for the GNU TLS library.
1663 */
1664
1665 ssize_t /* O - Number of bytes read or -1 on error */
_httpReadGNUTLS(gnutls_transport_ptr ptr,void * data,size_t length)1666 _httpReadGNUTLS(
1667 gnutls_transport_ptr ptr, /* I - Connection to server */
1668 void *data, /* I - Buffer */
1669 size_t length) /* I - Number of bytes to read */
1670 {
1671 http_t *http; /* HTTP connection */
1672
1673
1674 http = (http_t *)ptr;
1675
1676 if (!http->blocking)
1677 {
1678 /*
1679 * Make sure we have data before we read...
1680 */
1681
1682 if (!_httpWait(http, 10000, 0))
1683 {
1684 http->error = ETIMEDOUT;
1685 return (-1);
1686 }
1687 }
1688
1689 return (recv(http->fd, data, length, 0));
1690 }
1691 #endif /* HAVE_SSL && HAVE_GNUTLS */
1692
1693
1694 /*
1695 * 'httpReconnect()' - Reconnect to a HTTP server.
1696 */
1697
1698 int /* O - 0 on success, non-zero on failure */
httpReconnect(http_t * http)1699 httpReconnect(http_t *http) /* I - Connection to server */
1700 {
1701 http_addrlist_t *addr; /* Connected address */
1702 #ifdef DEBUG
1703 http_addrlist_t *current; /* Current address */
1704 char temp[256]; /* Temporary address string */
1705 #endif /* DEBUG */
1706
1707
1708 DEBUG_printf(("httpReconnect(http=%p)", http));
1709
1710 if (!http)
1711 return (-1);
1712
1713 #ifdef HAVE_SSL
1714 if (http->tls)
1715 {
1716 DEBUG_puts("2httpReconnect: Shutting down SSL/TLS...");
1717 http_shutdown_ssl(http);
1718 }
1719 #endif /* HAVE_SSL */
1720
1721 /*
1722 * Close any previously open socket...
1723 */
1724
1725 if (http->fd >= 0)
1726 {
1727 DEBUG_printf(("2httpReconnect: Closing socket %d...", http->fd));
1728
1729 #ifdef WIN32
1730 closesocket(http->fd);
1731 #else
1732 close(http->fd);
1733 #endif /* WIN32 */
1734
1735 http->fd = -1;
1736 }
1737
1738 /*
1739 * Connect to the server...
1740 */
1741
1742 #ifdef DEBUG
1743 for (current = http->addrlist; current; current = current->next)
1744 DEBUG_printf(("2httpReconnect: Address %s:%d",
1745 httpAddrString(&(current->addr), temp, sizeof(temp)),
1746 _httpAddrPort(&(current->addr))));
1747 #endif /* DEBUG */
1748
1749 if ((addr = httpAddrConnect(http->addrlist, &(http->fd))) == NULL)
1750 {
1751 /*
1752 * Unable to connect...
1753 */
1754
1755 #ifdef WIN32
1756 http->error = WSAGetLastError();
1757 #else
1758 http->error = errno;
1759 #endif /* WIN32 */
1760 http->status = HTTP_ERROR;
1761
1762 DEBUG_printf(("1httpReconnect: httpAddrConnect failed: %s",
1763 strerror(http->error)));
1764
1765 return (-1);
1766 }
1767
1768 DEBUG_printf(("2httpReconnect: New socket=%d", http->fd));
1769
1770 http->hostaddr = &(addr->addr);
1771 http->error = 0;
1772 http->status = HTTP_CONTINUE;
1773
1774 #ifdef HAVE_SSL
1775 if (http->encryption == HTTP_ENCRYPT_ALWAYS)
1776 {
1777 /*
1778 * Always do encryption via SSL.
1779 */
1780
1781 if (http_setup_ssl(http) != 0)
1782 {
1783 # ifdef WIN32
1784 closesocket(http->fd);
1785 # else
1786 close(http->fd);
1787 # endif /* WIN32 */
1788
1789 return (-1);
1790 }
1791 }
1792 else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
1793 return (http_upgrade(http));
1794 #endif /* HAVE_SSL */
1795
1796 DEBUG_printf(("1httpReconnect: Connected to %s:%d...",
1797 httpAddrString(http->hostaddr, temp, sizeof(temp)),
1798 _httpAddrPort(http->hostaddr)));
1799
1800 return (0);
1801 }
1802
1803
1804 /*
1805 * 'httpSetAuthString()' - Set the current authorization string.
1806 *
1807 * This function just stores a copy of the current authorization string in
1808 * the HTTP connection object. You must still call httpSetField() to set
1809 * HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(),
1810 * httpHead(), httpOptions(), httpPost, or httpPut().
1811 *
1812 * @since CUPS 1.3/Mac OS X 10.5@
1813 */
1814
1815 void
httpSetAuthString(http_t * http,const char * scheme,const char * data)1816 httpSetAuthString(http_t *http, /* I - Connection to server */
1817 const char *scheme, /* I - Auth scheme (NULL to clear it) */
1818 const char *data) /* I - Auth data (NULL for none) */
1819 {
1820 /*
1821 * Range check input...
1822 */
1823
1824 if (!http)
1825 return;
1826
1827 if (http->authstring && http->authstring != http->_authstring)
1828 free(http->authstring);
1829
1830 http->authstring = http->_authstring;
1831
1832 if (scheme)
1833 {
1834 /*
1835 * Set the current authorization string...
1836 */
1837
1838 int len = (int)strlen(scheme) + (data ? (int)strlen(data) + 1 : 0) + 1;
1839 char *temp;
1840
1841 if (len > (int)sizeof(http->_authstring))
1842 {
1843 if ((temp = malloc(len)) == NULL)
1844 len = sizeof(http->_authstring);
1845 else
1846 http->authstring = temp;
1847 }
1848
1849 if (data)
1850 snprintf(http->authstring, len, "%s %s", scheme, data);
1851 else
1852 strlcpy(http->authstring, scheme, len);
1853 }
1854 else
1855 {
1856 /*
1857 * Clear the current authorization string...
1858 */
1859
1860 http->_authstring[0] = '\0';
1861 }
1862 }
1863
1864
1865 /*
1866 * 'httpSetCookie()' - Set the cookie value(s).
1867 *
1868 * @since CUPS 1.1.19/Mac OS X 10.3@
1869 */
1870
1871 void
httpSetCookie(http_t * http,const char * cookie)1872 httpSetCookie(http_t *http, /* I - Connection */
1873 const char *cookie) /* I - Cookie string */
1874 {
1875 if (!http)
1876 return;
1877
1878 if (http->cookie)
1879 free(http->cookie);
1880
1881 if (cookie)
1882 http->cookie = strdup(cookie);
1883 else
1884 http->cookie = NULL;
1885 }
1886
1887
1888 /*
1889 * 'httpSetExpect()' - Set the Expect: header in a request.
1890 *
1891 * Currently only HTTP_CONTINUE is supported for the "expect" argument.
1892 *
1893 * @since CUPS 1.2/Mac OS X 10.5@
1894 */
1895
1896 void
httpSetExpect(http_t * http,http_status_t expect)1897 httpSetExpect(http_t *http, /* I - Connection to server */
1898 http_status_t expect) /* I - HTTP status to expect (HTTP_CONTINUE) */
1899 {
1900 if (http)
1901 http->expect = expect;
1902 }
1903
1904
1905 /*
1906 * 'httpSetField()' - Set the value of an HTTP header.
1907 */
1908
1909 void
httpSetField(http_t * http,http_field_t field,const char * value)1910 httpSetField(http_t *http, /* I - Connection to server */
1911 http_field_t field, /* I - Field index */
1912 const char *value) /* I - Value */
1913 {
1914 if (http == NULL ||
1915 field < HTTP_FIELD_ACCEPT_LANGUAGE ||
1916 field > HTTP_FIELD_WWW_AUTHENTICATE ||
1917 value == NULL)
1918 return;
1919
1920 strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
1921
1922 if (field == HTTP_FIELD_AUTHORIZATION)
1923 {
1924 /*
1925 * Special case for Authorization: as its contents can be
1926 * longer than HTTP_MAX_VALUE
1927 */
1928
1929 if (http->field_authorization)
1930 free(http->field_authorization);
1931
1932 http->field_authorization = strdup(value);
1933 }
1934 else if (field == HTTP_FIELD_HOST)
1935 {
1936 /*
1937 * Special-case for Host: as we don't want a trailing "." on the hostname and
1938 * need to bracket IPv6 numeric addresses.
1939 */
1940
1941 char *ptr = strchr(value, ':');
1942
1943 if (value[0] != '[' && ptr && strchr(ptr + 1, ':'))
1944 {
1945 /*
1946 * Bracket IPv6 numeric addresses...
1947 *
1948 * This is slightly inefficient (basically copying twice), but is an edge
1949 * case and not worth optimizing...
1950 */
1951
1952 snprintf(http->fields[HTTP_FIELD_HOST],
1953 sizeof(http->fields[HTTP_FIELD_HOST]), "[%s]", value);
1954 }
1955 else
1956 {
1957 /*
1958 * Check for a trailing dot on the hostname...
1959 */
1960
1961 ptr = http->fields[HTTP_FIELD_HOST];
1962
1963 if (*ptr)
1964 {
1965 ptr += strlen(ptr) - 1;
1966
1967 if (*ptr == '.')
1968 *ptr = '\0';
1969 }
1970 }
1971 }
1972 }
1973
1974
1975 /*
1976 * 'httpSetLength()' - Set the content-length and content-encoding.
1977 *
1978 * @since CUPS 1.2/Mac OS X 10.5@
1979 */
1980
1981 void
httpSetLength(http_t * http,size_t length)1982 httpSetLength(http_t *http, /* I - Connection to server */
1983 size_t length) /* I - Length (0 for chunked) */
1984 {
1985 if (!http)
1986 return;
1987
1988 if (!length)
1989 {
1990 strcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked");
1991 http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0';
1992 }
1993 else
1994 {
1995 http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0';
1996 snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE,
1997 CUPS_LLFMT, CUPS_LLCAST length);
1998 }
1999 }
2000
2001
2002 /*
2003 * 'httpTrace()' - Send an TRACE request to the server.
2004 */
2005
2006 int /* O - Status of call (0 = success) */
httpTrace(http_t * http,const char * uri)2007 httpTrace(http_t *http, /* I - Connection to server */
2008 const char *uri) /* I - URI for trace */
2009 {
2010 return (http_send(http, HTTP_TRACE, uri));
2011 }
2012
2013
2014 /*
2015 * 'httpUpdate()' - Update the current HTTP state for incoming data.
2016 */
2017
2018 http_status_t /* O - HTTP status */
httpUpdate(http_t * http)2019 httpUpdate(http_t *http) /* I - Connection to server */
2020 {
2021 char line[32768], /* Line from connection... */
2022 *value; /* Pointer to value on line */
2023 http_field_t field; /* Field index */
2024 int major, minor, /* HTTP version numbers */
2025 status; /* Request status */
2026
2027
2028 DEBUG_printf(("httpUpdate(http=%p), state=%s", http,
2029 http_states[http->state]));
2030
2031 /*
2032 * Flush pending data, if any...
2033 */
2034
2035 if (http->wused)
2036 {
2037 DEBUG_puts("2httpUpdate: flushing buffer...");
2038
2039 if (httpFlushWrite(http) < 0)
2040 return (HTTP_ERROR);
2041 }
2042
2043 /*
2044 * If we haven't issued any commands, then there is nothing to "update"...
2045 */
2046
2047 if (http->state == HTTP_WAITING)
2048 return (HTTP_CONTINUE);
2049
2050 /*
2051 * Grab all of the lines we can from the connection...
2052 */
2053
2054 while (httpGets(line, sizeof(line), http) != NULL)
2055 {
2056 DEBUG_printf(("2httpUpdate: Got \"%s\"", line));
2057
2058 if (line[0] == '\0')
2059 {
2060 /*
2061 * Blank line means the start of the data section (if any). Return
2062 * the result code, too...
2063 *
2064 * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
2065 * Instead, we just return HTTP_CONTINUE to the caller and keep on
2066 * tryin'...
2067 */
2068
2069 if (http->status == HTTP_CONTINUE)
2070 return (http->status);
2071
2072 if (http->status < HTTP_BAD_REQUEST)
2073 http->digest_tries = 0;
2074
2075 #ifdef HAVE_SSL
2076 if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
2077 {
2078 if (http_setup_ssl(http) != 0)
2079 {
2080 # ifdef WIN32
2081 closesocket(http->fd);
2082 # else
2083 close(http->fd);
2084 # endif /* WIN32 */
2085
2086 return (HTTP_ERROR);
2087 }
2088
2089 return (HTTP_CONTINUE);
2090 }
2091 #endif /* HAVE_SSL */
2092
2093 httpGetLength2(http);
2094
2095 switch (http->state)
2096 {
2097 case HTTP_GET :
2098 case HTTP_POST :
2099 case HTTP_POST_RECV :
2100 case HTTP_PUT :
2101 http->state ++;
2102 case HTTP_POST_SEND :
2103 case HTTP_HEAD :
2104 break;
2105
2106 default :
2107 http->state = HTTP_WAITING;
2108 break;
2109 }
2110
2111 return (http->status);
2112 }
2113 else if (!strncmp(line, "HTTP/", 5))
2114 {
2115 /*
2116 * Got the beginning of a response...
2117 */
2118
2119 if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3)
2120 return (HTTP_ERROR);
2121
2122 http->version = (http_version_t)(major * 100 + minor);
2123 http->status = (http_status_t)status;
2124 }
2125 else if ((value = strchr(line, ':')) != NULL)
2126 {
2127 /*
2128 * Got a value...
2129 */
2130
2131 *value++ = '\0';
2132 while (_cups_isspace(*value))
2133 value ++;
2134
2135 /*
2136 * Be tolerants of servers that send unknown attribute fields...
2137 */
2138
2139 if (!strcasecmp(line, "expect"))
2140 {
2141 /*
2142 * "Expect: 100-continue" or similar...
2143 */
2144
2145 http->expect = (http_status_t)atoi(value);
2146 }
2147 else if (!strcasecmp(line, "cookie"))
2148 {
2149 /*
2150 * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
2151 */
2152
2153 httpSetCookie(http, value);
2154 }
2155 else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN)
2156 {
2157 DEBUG_printf(("1httpUpdate: unknown field %s seen!", line));
2158 continue;
2159 }
2160 else
2161 httpSetField(http, field, value);
2162 }
2163 else
2164 {
2165 DEBUG_printf(("1httpUpdate: Bad response line \"%s\"!", line));
2166 http->status = HTTP_ERROR;
2167 return (HTTP_ERROR);
2168 }
2169 }
2170
2171 /*
2172 * See if there was an error...
2173 */
2174
2175 if (http->error == EPIPE && http->status > HTTP_CONTINUE)
2176 {
2177 DEBUG_printf(("1httpUpdate: Returning status %d...", http->status));
2178 return (http->status);
2179 }
2180
2181 if (http->error)
2182 {
2183 DEBUG_printf(("1httpUpdate: socket error %d - %s", http->error,
2184 strerror(http->error)));
2185 http->status = HTTP_ERROR;
2186 return (HTTP_ERROR);
2187 }
2188
2189 /*
2190 * If we haven't already returned, then there is nothing new...
2191 */
2192
2193 return (HTTP_CONTINUE);
2194 }
2195
2196
2197 /*
2198 * '_httpWait()' - Wait for data available on a connection (no flush).
2199 */
2200
2201 int /* O - 1 if data is available, 0 otherwise */
_httpWait(http_t * http,int msec,int usessl)2202 _httpWait(http_t *http, /* I - Connection to server */
2203 int msec, /* I - Milliseconds to wait */
2204 int usessl) /* I - Use SSL context? */
2205 {
2206 #ifdef HAVE_POLL
2207 struct pollfd pfd; /* Polled file descriptor */
2208 #else
2209 fd_set input_set; /* select() input set */
2210 struct timeval timeout; /* Timeout */
2211 #endif /* HAVE_POLL */
2212 int nfds; /* Result from select()/poll() */
2213
2214
2215 DEBUG_printf(("4_httpWait(http=%p, msec=%d, usessl=%d)", http, msec, usessl));
2216
2217 if (http->fd < 0)
2218 return (0);
2219
2220 /*
2221 * Check the SSL/TLS buffers for data first...
2222 */
2223
2224 #ifdef HAVE_SSL
2225 if (http->tls && usessl)
2226 {
2227 # ifdef HAVE_LIBSSL
2228 if (SSL_pending((SSL *)(http->tls)))
2229 return (1);
2230 # elif defined(HAVE_GNUTLS)
2231 if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
2232 return (1);
2233 # elif defined(HAVE_CDSASSL)
2234 size_t bytes; /* Bytes that are available */
2235
2236 if (!SSLGetBufferedReadSize(((http_tls_t *)(http->tls))->session, &bytes) &&
2237 bytes > 0)
2238 return (1);
2239 # endif /* HAVE_LIBSSL */
2240 }
2241 #endif /* HAVE_SSL */
2242
2243 /*
2244 * Then try doing a select() or poll() to poll the socket...
2245 */
2246
2247 #ifdef HAVE_POLL
2248 pfd.fd = http->fd;
2249 pfd.events = POLLIN;
2250
2251 while ((nfds = poll(&pfd, 1, msec)) < 0 &&
2252 (errno == EINTR || errno == EAGAIN));
2253
2254 #else
2255 do
2256 {
2257 FD_ZERO(&input_set);
2258 FD_SET(http->fd, &input_set);
2259
2260 DEBUG_printf(("6_httpWait: msec=%d, http->fd=%d", msec, http->fd));
2261
2262 if (msec >= 0)
2263 {
2264 timeout.tv_sec = msec / 1000;
2265 timeout.tv_usec = (msec % 1000) * 1000;
2266
2267 nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout);
2268 }
2269 else
2270 nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL);
2271
2272 DEBUG_printf(("6_httpWait: select() returned %d...", nfds));
2273 }
2274 # ifdef WIN32
2275 while (nfds < 0 && WSAGetLastError() == WSAEINTR);
2276 # else
2277 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
2278 # endif /* WIN32 */
2279 #endif /* HAVE_POLL */
2280
2281 DEBUG_printf(("5_httpWait: returning with nfds=%d...", nfds));
2282
2283 return (nfds > 0);
2284 }
2285
2286
2287 /*
2288 * 'httpWait()' - Wait for data available on a connection.
2289 *
2290 * @since CUPS 1.1.19/Mac OS X 10.3@
2291 */
2292
2293 int /* O - 1 if data is available, 0 otherwise */
httpWait(http_t * http,int msec)2294 httpWait(http_t *http, /* I - Connection to server */
2295 int msec) /* I - Milliseconds to wait */
2296 {
2297 /*
2298 * First see if there is data in the buffer...
2299 */
2300
2301 if (http == NULL)
2302 return (0);
2303
2304 if (http->used)
2305 return (1);
2306
2307 /*
2308 * Flush pending data, if any...
2309 */
2310
2311 if (http->wused)
2312 {
2313 if (httpFlushWrite(http) < 0)
2314 return (0);
2315 }
2316
2317 /*
2318 * If not, check the SSL/TLS buffers and do a select() on the connection...
2319 */
2320
2321 return (_httpWait(http, msec, 1));
2322 }
2323
2324
2325 /*
2326 * 'httpWrite()' - Write data to a HTTP connection.
2327 *
2328 * This function is deprecated. Use the httpWrite2() function which can
2329 * write more than 2GB of data.
2330 *
2331 * @deprecated@
2332 */
2333
2334 int /* O - Number of bytes written */
httpWrite(http_t * http,const char * buffer,int length)2335 httpWrite(http_t *http, /* I - Connection to server */
2336 const char *buffer, /* I - Buffer for data */
2337 int length) /* I - Number of bytes to write */
2338 {
2339 return ((int)httpWrite2(http, buffer, length));
2340 }
2341
2342
2343 /*
2344 * 'httpWrite2()' - Write data to a HTTP connection.
2345 *
2346 * @since CUPS 1.2/Mac OS X 10.5@
2347 */
2348
2349 ssize_t /* O - Number of bytes written */
httpWrite2(http_t * http,const char * buffer,size_t length)2350 httpWrite2(http_t *http, /* I - Connection to server */
2351 const char *buffer, /* I - Buffer for data */
2352 size_t length) /* I - Number of bytes to write */
2353 {
2354 ssize_t bytes; /* Bytes written */
2355
2356
2357 DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
2358 buffer, CUPS_LLCAST length));
2359
2360 /*
2361 * Range check input...
2362 */
2363
2364 if (http == NULL || buffer == NULL)
2365 return (-1);
2366
2367 /*
2368 * Mark activity on the connection...
2369 */
2370
2371 http->activity = time(NULL);
2372
2373 /*
2374 * Buffer small writes for better performance...
2375 */
2376
2377 if (length > 0)
2378 {
2379 if (http->wused && (length + http->wused) > sizeof(http->wbuffer))
2380 {
2381 DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length="
2382 CUPS_LLFMT ")", http->wused, CUPS_LLCAST length));
2383
2384 httpFlushWrite(http);
2385 }
2386
2387 if ((length + http->wused) <= sizeof(http->wbuffer) &&
2388 length < sizeof(http->wbuffer))
2389 {
2390 /*
2391 * Write to buffer...
2392 */
2393
2394 DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...",
2395 CUPS_LLCAST length));
2396
2397 memcpy(http->wbuffer + http->wused, buffer, length);
2398 http->wused += (int)length;
2399 bytes = (ssize_t)length;
2400 }
2401 else
2402 {
2403 /*
2404 * Otherwise write the data directly...
2405 */
2406
2407 DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...",
2408 CUPS_LLCAST length));
2409
2410 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
2411 bytes = (ssize_t)http_write_chunk(http, buffer, (int)length);
2412 else
2413 bytes = (ssize_t)http_write(http, buffer, (int)length);
2414
2415 DEBUG_printf(("2httpWrite2: Wrote " CUPS_LLFMT " bytes...",
2416 CUPS_LLCAST bytes));
2417 }
2418
2419 if (http->data_encoding == HTTP_ENCODE_LENGTH)
2420 http->data_remaining -= bytes;
2421 }
2422 else
2423 bytes = 0;
2424
2425 /*
2426 * Handle end-of-request processing...
2427 */
2428
2429 if ((http->data_encoding == HTTP_ENCODE_CHUNKED && length == 0) ||
2430 (http->data_encoding == HTTP_ENCODE_LENGTH && http->data_remaining == 0))
2431 {
2432 /*
2433 * Finished with the transfer; unless we are sending POST or PUT
2434 * data, go idle...
2435 */
2436
2437 DEBUG_puts("2httpWrite: changing states...");
2438
2439 if (http->wused)
2440 httpFlushWrite(http);
2441
2442 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
2443 {
2444 /*
2445 * Send a 0-length chunk at the end of the request...
2446 */
2447
2448 http_write(http, "0\r\n\r\n", 5);
2449
2450 /*
2451 * Reset the data state...
2452 */
2453
2454 http->data_encoding = HTTP_ENCODE_LENGTH;
2455 http->data_remaining = 0;
2456 }
2457
2458 if (http->state == HTTP_POST_RECV)
2459 http->state ++;
2460 else if (http->state == HTTP_PUT_RECV)
2461 http->state = HTTP_STATUS;
2462 else
2463 http->state = HTTP_WAITING;
2464 }
2465
2466 return (bytes);
2467 }
2468
2469
2470 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
2471 /*
2472 * '_httpWriteCDSA()' - Write function for the CDSA library.
2473 */
2474
2475 OSStatus /* O - -1 on error, 0 on success */
_httpWriteCDSA(SSLConnectionRef connection,const void * data,size_t * dataLength)2476 _httpWriteCDSA(
2477 SSLConnectionRef connection, /* I - SSL/TLS connection */
2478 const void *data, /* I - Data buffer */
2479 size_t *dataLength) /* IO - Number of bytes */
2480 {
2481 OSStatus result; /* Return value */
2482 ssize_t bytes; /* Number of bytes read */
2483 http_t *http; /* HTTP connection */
2484
2485
2486 http = (http_t *)connection;
2487
2488 do
2489 {
2490 bytes = write(http->fd, data, *dataLength);
2491 }
2492 while (bytes == -1 && (errno == EINTR || errno == EAGAIN));
2493
2494 if (bytes == *dataLength)
2495 {
2496 result = 0;
2497 }
2498 else if (bytes >= 0)
2499 {
2500 *dataLength = bytes;
2501 result = errSSLWouldBlock;
2502 }
2503 else
2504 {
2505 *dataLength = 0;
2506
2507 if (errno == EAGAIN)
2508 result = errSSLWouldBlock;
2509 else
2510 result = errSSLClosedAbort;
2511 }
2512
2513 return (result);
2514 }
2515 #endif /* HAVE_SSL && HAVE_CDSASSL */
2516
2517
2518 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
2519 /*
2520 * '_httpWriteGNUTLS()' - Write function for the GNU TLS library.
2521 */
2522
2523 ssize_t /* O - Number of bytes written or -1 on error */
_httpWriteGNUTLS(gnutls_transport_ptr ptr,const void * data,size_t length)2524 _httpWriteGNUTLS(
2525 gnutls_transport_ptr ptr, /* I - Connection to server */
2526 const void *data, /* I - Data buffer */
2527 size_t length) /* I - Number of bytes to write */
2528 {
2529 return (send(((http_t *)ptr)->fd, data, length, 0));
2530 }
2531 #endif /* HAVE_SSL && HAVE_GNUTLS */
2532
2533
2534 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
2535 /*
2536 * 'http_bio_ctrl()' - Control the HTTP connection.
2537 */
2538
2539 static long /* O - Result/data */
http_bio_ctrl(BIO * h,int cmd,long arg1,void * arg2)2540 http_bio_ctrl(BIO *h, /* I - BIO data */
2541 int cmd, /* I - Control command */
2542 long arg1, /* I - First argument */
2543 void *arg2) /* I - Second argument */
2544 {
2545 switch (cmd)
2546 {
2547 default :
2548 return (0);
2549
2550 case BIO_CTRL_RESET :
2551 h->ptr = NULL;
2552 return (0);
2553
2554 case BIO_C_SET_FILE_PTR :
2555 h->ptr = arg2;
2556 h->init = 1;
2557 return (1);
2558
2559 case BIO_C_GET_FILE_PTR :
2560 if (arg2)
2561 {
2562 *((void **)arg2) = h->ptr;
2563 return (1);
2564 }
2565 else
2566 return (0);
2567
2568 case BIO_CTRL_DUP :
2569 case BIO_CTRL_FLUSH :
2570 return (1);
2571 }
2572 }
2573
2574
2575 /*
2576 * 'http_bio_free()' - Free OpenSSL data.
2577 */
2578
2579 static int /* O - 1 on success, 0 on failure */
http_bio_free(BIO * h)2580 http_bio_free(BIO *h) /* I - BIO data */
2581 {
2582 if (!h)
2583 return (0);
2584
2585 if (h->shutdown)
2586 {
2587 h->init = 0;
2588 h->flags = 0;
2589 }
2590
2591 return (1);
2592 }
2593
2594
2595 /*
2596 * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
2597 */
2598
2599 static int /* O - 1 on success, 0 on failure */
http_bio_new(BIO * h)2600 http_bio_new(BIO *h) /* I - BIO data */
2601 {
2602 if (!h)
2603 return (0);
2604
2605 h->init = 0;
2606 h->num = 0;
2607 h->ptr = NULL;
2608 h->flags = 0;
2609
2610 return (1);
2611 }
2612
2613
2614 /*
2615 * 'http_bio_puts()' - Send a string for OpenSSL.
2616 */
2617
2618 static int /* O - Bytes written */
http_bio_puts(BIO * h,const char * str)2619 http_bio_puts(BIO *h, /* I - BIO data */
2620 const char *str) /* I - String to write */
2621 {
2622 #ifdef WIN32
2623 return (send(((http_t *)h->ptr)->fd, str, (int)strlen(str), 0));
2624 #else
2625 return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0));
2626 #endif /* WIN32 */
2627 }
2628
2629
2630 /*
2631 * 'http_bio_read()' - Read data for OpenSSL.
2632 */
2633
2634 static int /* O - Bytes read */
http_bio_read(BIO * h,char * buf,int size)2635 http_bio_read(BIO *h, /* I - BIO data */
2636 char *buf, /* I - Buffer */
2637 int size) /* I - Number of bytes to read */
2638 {
2639 http_t *http; /* HTTP connection */
2640
2641
2642 http = (http_t *)h->ptr;
2643
2644 if (!http->blocking)
2645 {
2646 /*
2647 * Make sure we have data before we read...
2648 */
2649
2650 if (!_httpWait(http, 10000, 0))
2651 {
2652 #ifdef WIN32
2653 http->error = WSAETIMEDOUT;
2654 #else
2655 http->error = ETIMEDOUT;
2656 #endif /* WIN32 */
2657
2658 return (-1);
2659 }
2660 }
2661
2662 return (recv(http->fd, buf, size, 0));
2663 }
2664
2665
2666 /*
2667 * 'http_bio_write()' - Write data for OpenSSL.
2668 */
2669
2670 static int /* O - Bytes written */
http_bio_write(BIO * h,const char * buf,int num)2671 http_bio_write(BIO *h, /* I - BIO data */
2672 const char *buf, /* I - Buffer to write */
2673 int num) /* I - Number of bytes to write */
2674 {
2675 return (send(((http_t *)h->ptr)->fd, buf, num, 0));
2676 }
2677 #endif /* HAVE_SSL && HAVE_LIBSSL */
2678
2679
2680 #ifdef DEBUG
2681 /*
2682 * 'http_debug_hex()' - Do a hex dump of a buffer.
2683 */
2684
2685 static void
http_debug_hex(const char * prefix,const char * buffer,int bytes)2686 http_debug_hex(const char *prefix, /* I - Prefix for line */
2687 const char *buffer, /* I - Buffer to dump */
2688 int bytes) /* I - Bytes to dump */
2689 {
2690 int i, j, /* Looping vars */
2691 ch; /* Current character */
2692 char line[255], /* Line buffer */
2693 *start, /* Start of line after prefix */
2694 *ptr; /* Pointer into line */
2695
2696
2697 if (_cups_debug_fd < 0 || _cups_debug_level < 6)
2698 return;
2699
2700 DEBUG_printf(("6%s: %d bytes:\n", prefix, bytes));
2701
2702 snprintf(line, sizeof(line), "6%s: ", prefix);
2703 start = line + strlen(line);
2704
2705 for (i = 0; i < bytes; i += 16)
2706 {
2707 for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2)
2708 sprintf(ptr, "%02X", buffer[i + j] & 255);
2709
2710 while (j < 16)
2711 {
2712 strcpy(ptr, " ");
2713 ptr += 2;
2714 j ++;
2715 }
2716
2717 strcpy(ptr, " ");
2718 ptr += 2;
2719
2720 for (j = 0; j < 16 && (i + j) < bytes; j ++)
2721 {
2722 ch = buffer[i + j] & 255;
2723
2724 if (ch < ' ' || ch >= 127)
2725 ch = '.';
2726
2727 *ptr++ = ch;
2728 }
2729
2730 *ptr = '\0';
2731 DEBUG_puts(line);
2732 }
2733 }
2734 #endif /* DEBUG */
2735
2736
2737 /*
2738 * 'http_field()' - Return the field index for a field name.
2739 */
2740
2741 static http_field_t /* O - Field index */
http_field(const char * name)2742 http_field(const char *name) /* I - String name */
2743 {
2744 int i; /* Looping var */
2745
2746
2747 for (i = 0; i < HTTP_FIELD_MAX; i ++)
2748 if (strcasecmp(name, http_fields[i]) == 0)
2749 return ((http_field_t)i);
2750
2751 return (HTTP_FIELD_UNKNOWN);
2752 }
2753
2754
2755 #ifdef HAVE_SSL
2756 /*
2757 * 'http_read_ssl()' - Read from a SSL/TLS connection.
2758 */
2759
2760 static int /* O - Bytes read */
http_read_ssl(http_t * http,char * buf,int len)2761 http_read_ssl(http_t *http, /* I - Connection to server */
2762 char *buf, /* I - Buffer to store data */
2763 int len) /* I - Length of buffer */
2764 {
2765 # if defined(HAVE_LIBSSL)
2766 return (SSL_read((SSL *)(http->tls), buf, len));
2767
2768 # elif defined(HAVE_GNUTLS)
2769 ssize_t result; /* Return value */
2770
2771
2772 result = gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len);
2773
2774 if (result < 0 && !errno)
2775 {
2776 /*
2777 * Convert GNU TLS error to errno value...
2778 */
2779
2780 switch (result)
2781 {
2782 case GNUTLS_E_INTERRUPTED :
2783 errno = EINTR;
2784 break;
2785
2786 case GNUTLS_E_AGAIN :
2787 errno = EAGAIN;
2788 break;
2789
2790 default :
2791 errno = EPIPE;
2792 break;
2793 }
2794
2795 result = -1;
2796 }
2797
2798 return ((int)result);
2799
2800 # elif defined(HAVE_CDSASSL)
2801 int result; /* Return value */
2802 OSStatus error; /* Error info */
2803 size_t processed; /* Number of bytes processed */
2804
2805
2806 error = SSLRead(((http_tls_t *)http->tls)->session, buf, len, &processed);
2807
2808 switch (error)
2809 {
2810 case 0 :
2811 result = (int)processed;
2812 break;
2813 case errSSLClosedGraceful :
2814 result = 0;
2815 break;
2816 case errSSLWouldBlock :
2817 if (processed)
2818 result = (int)processed;
2819 else
2820 {
2821 result = -1;
2822 errno = EINTR;
2823 }
2824 break;
2825 default :
2826 errno = EPIPE;
2827 result = -1;
2828 break;
2829 }
2830
2831 return (result);
2832 # endif /* HAVE_LIBSSL */
2833 }
2834 #endif /* HAVE_SSL */
2835
2836
2837 #if defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD_H)
2838 /*
2839 * 'http_locking_cb()' - Lock/unlock a thread's mutex.
2840 */
2841
2842 static void
http_locking_cb(int mode,int type,const char * file,int line)2843 http_locking_cb(int mode, /* I - Lock mode */
2844 int type, /* I - Lock type */
2845 const char *file, /* I - Source file */
2846 int line) /* I - Line number */
2847 {
2848 if (mode & CRYPTO_LOCK)
2849 pthread_mutex_lock(http_locks + type);
2850 else
2851 pthread_mutex_unlock(http_locks + type);
2852 }
2853 #endif /* HAVE_LIBSSL && HAVE_PTHREAD_H */
2854
2855
2856 /*
2857 * 'http_send()' - Send a request with all fields and the trailing blank line.
2858 */
2859
2860 static int /* O - 0 on success, non-zero on error */
http_send(http_t * http,http_state_t request,const char * uri)2861 http_send(http_t *http, /* I - Connection to server */
2862 http_state_t request, /* I - Request code */
2863 const char *uri) /* I - URI */
2864 {
2865 int i; /* Looping var */
2866 char buf[1024]; /* Encoded URI buffer */
2867 static const char * const codes[] =
2868 { /* Request code strings */
2869 NULL,
2870 "OPTIONS",
2871 "GET",
2872 NULL,
2873 "HEAD",
2874 "POST",
2875 NULL,
2876 NULL,
2877 "PUT",
2878 NULL,
2879 "DELETE",
2880 "TRACE",
2881 "CLOSE"
2882 };
2883
2884
2885 DEBUG_printf(("7http_send(http=%p, request=HTTP_%s, uri=\"%s\")",
2886 http, codes[request], uri));
2887
2888 if (http == NULL || uri == NULL)
2889 return (-1);
2890
2891 /*
2892 * Set the User-Agent field if it isn't already...
2893 */
2894
2895 if (!http->fields[HTTP_FIELD_USER_AGENT][0])
2896 httpSetField(http, HTTP_FIELD_USER_AGENT, CUPS_MINIMAL);
2897
2898 /*
2899 * Encode the URI as needed...
2900 */
2901
2902 _httpEncodeURI(buf, uri, sizeof(buf));
2903
2904 /*
2905 * See if we had an error the last time around; if so, reconnect...
2906 */
2907
2908 if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
2909 if (httpReconnect(http))
2910 return (-1);
2911
2912 /*
2913 * Flush any written data that is pending...
2914 */
2915
2916 if (http->wused)
2917 {
2918 if (httpFlushWrite(http) < 0)
2919 if (httpReconnect(http))
2920 return (-1);
2921 }
2922
2923 /*
2924 * Send the request header...
2925 */
2926
2927 http->state = request;
2928 http->data_encoding = HTTP_ENCODE_FIELDS;
2929
2930 if (request == HTTP_POST || request == HTTP_PUT)
2931 http->state ++;
2932
2933 http->status = HTTP_CONTINUE;
2934
2935 #ifdef HAVE_SSL
2936 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
2937 {
2938 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
2939 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
2940 }
2941 #endif /* HAVE_SSL */
2942
2943 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
2944 {
2945 http->status = HTTP_ERROR;
2946 return (-1);
2947 }
2948
2949 for (i = 0; i < HTTP_FIELD_MAX; i ++)
2950 if (http->fields[i][0] != '\0')
2951 {
2952 DEBUG_printf(("9http_send: %s: %s", http_fields[i],
2953 httpGetField(http, i)));
2954
2955 if (httpPrintf(http, "%s: %s\r\n", http_fields[i],
2956 httpGetField(http, i)) < 1)
2957 {
2958 http->status = HTTP_ERROR;
2959 return (-1);
2960 }
2961 }
2962
2963 if (http->cookie)
2964 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1)
2965 {
2966 http->status = HTTP_ERROR;
2967 return (-1);
2968 }
2969
2970 if (http->expect == HTTP_CONTINUE &&
2971 (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV))
2972 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
2973 {
2974 http->status = HTTP_ERROR;
2975 return (-1);
2976 }
2977
2978 if (httpPrintf(http, "\r\n") < 1)
2979 {
2980 http->status = HTTP_ERROR;
2981 return (-1);
2982 }
2983
2984 if (httpFlushWrite(http) < 0)
2985 return (-1);
2986
2987 httpGetLength2(http);
2988 httpClearFields(http);
2989
2990 /*
2991 * The Kerberos and AuthRef authentication strings can only be used once...
2992 */
2993
2994 if (http->field_authorization && http->authstring &&
2995 (!strncmp(http->authstring, "Negotiate", 9) ||
2996 !strncmp(http->authstring, "AuthRef", 7)))
2997 {
2998 http->_authstring[0] = '\0';
2999
3000 if (http->authstring != http->_authstring)
3001 free(http->authstring);
3002
3003 http->authstring = http->_authstring;
3004 }
3005
3006 return (0);
3007 }
3008
3009
3010 #ifdef HAVE_SSL
3011 /*
3012 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
3013 */
3014
3015 static int /* O - Status of connection */
http_setup_ssl(http_t * http)3016 http_setup_ssl(http_t *http) /* I - Connection to server */
3017 {
3018 # ifdef HAVE_LIBSSL
3019 SSL_CTX *context; /* Context for encryption */
3020 SSL *conn; /* Connection for encryption */
3021 BIO *bio; /* BIO data */
3022 # elif defined(HAVE_GNUTLS)
3023 http_tls_t *conn; /* TLS session object */
3024 gnutls_certificate_client_credentials *credentials;
3025 /* TLS credentials */
3026 # elif defined(HAVE_CDSASSL)
3027 OSStatus error; /* Error code */
3028 http_tls_t *conn; /* CDSA connection information */
3029 # endif /* HAVE_LIBSSL */
3030
3031
3032 DEBUG_printf(("7http_setup_ssl(http=%p)", http));
3033
3034 # ifdef HAVE_LIBSSL
3035 context = SSL_CTX_new(SSLv23_client_method());
3036
3037 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
3038
3039 bio = BIO_new(_httpBIOMethods());
3040 BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
3041
3042 conn = SSL_new(context);
3043 SSL_set_bio(conn, bio, bio);
3044
3045 if (SSL_connect(conn) != 1)
3046 {
3047 # ifdef DEBUG
3048 unsigned long error; /* Error code */
3049
3050 while ((error = ERR_get_error()) != 0)
3051 DEBUG_printf(("8http_setup_ssl: %s", ERR_error_string(error, NULL)));
3052 # endif /* DEBUG */
3053
3054 SSL_CTX_free(context);
3055 SSL_free(conn);
3056
3057 # ifdef WIN32
3058 http->error = WSAGetLastError();
3059 # else
3060 http->error = errno;
3061 # endif /* WIN32 */
3062 http->status = HTTP_ERROR;
3063
3064 return (HTTP_ERROR);
3065 }
3066
3067 # elif defined(HAVE_GNUTLS)
3068 if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
3069 {
3070 http->error = errno;
3071 http->status = HTTP_ERROR;
3072
3073 return (-1);
3074 }
3075
3076 credentials = (gnutls_certificate_client_credentials *)
3077 malloc(sizeof(gnutls_certificate_client_credentials));
3078 if (credentials == NULL)
3079 {
3080 free(conn);
3081
3082 http->error = errno;
3083 http->status = HTTP_ERROR;
3084
3085 return (-1);
3086 }
3087
3088 gnutls_certificate_allocate_credentials(credentials);
3089
3090 gnutls_init(&(conn->session), GNUTLS_CLIENT);
3091 gnutls_set_default_priority(conn->session);
3092 gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
3093 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)http);
3094 gnutls_transport_set_pull_function(conn->session, _httpReadGNUTLS);
3095 gnutls_transport_set_push_function(conn->session, _httpWriteGNUTLS);
3096
3097 if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
3098 {
3099 http->error = errno;
3100 http->status = HTTP_ERROR;
3101
3102 gnutls_deinit(conn->session);
3103 gnutls_certificate_free_credentials(*credentials);
3104 free(credentials);
3105 free(conn);
3106
3107 return (-1);
3108 }
3109
3110 conn->credentials = credentials;
3111
3112 # elif defined(HAVE_CDSASSL)
3113 conn = (http_tls_t *)calloc(1, sizeof(http_tls_t));
3114
3115 if (conn == NULL)
3116 return (-1);
3117
3118 if ((error = SSLNewContext(false, &conn->session)))
3119 {
3120 http->error = error;
3121 http->status = HTTP_ERROR;
3122
3123 free(conn);
3124 return (-1);
3125 }
3126
3127 /*
3128 * Use a union to resolve warnings about int/pointer size mismatches...
3129 */
3130
3131 error = SSLSetConnection(conn->session, http);
3132
3133 if (!error)
3134 error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);
3135
3136 if (!error)
3137 error = SSLSetAllowsExpiredCerts(conn->session, true);
3138
3139 if (!error)
3140 error = SSLSetAllowsAnyRoot(conn->session, true);
3141
3142 if (!error)
3143 error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false);
3144
3145 if (!error)
3146 {
3147 while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock)
3148 usleep(1000);
3149 }
3150
3151 if (error)
3152 {
3153 http->error = error;
3154 http->status = HTTP_ERROR;
3155
3156 SSLDisposeContext(conn->session);
3157
3158 free(conn);
3159
3160 return (-1);
3161 }
3162 # endif /* HAVE_CDSASSL */
3163
3164 http->tls = conn;
3165 return (0);
3166 }
3167 #endif /* HAVE_SSL */
3168
3169
3170 #ifdef HAVE_SSL
3171 /*
3172 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
3173 */
3174
3175 static void
http_shutdown_ssl(http_t * http)3176 http_shutdown_ssl(http_t *http) /* I - Connection to server */
3177 {
3178 # ifdef HAVE_LIBSSL
3179 SSL_CTX *context; /* Context for encryption */
3180 SSL *conn; /* Connection for encryption */
3181
3182
3183 conn = (SSL *)(http->tls);
3184 context = SSL_get_SSL_CTX(conn);
3185
3186 SSL_shutdown(conn);
3187 SSL_CTX_free(context);
3188 SSL_free(conn);
3189
3190 # elif defined(HAVE_GNUTLS)
3191 http_tls_t *conn; /* Encryption session */
3192 gnutls_certificate_client_credentials *credentials;
3193 /* TLS credentials */
3194
3195
3196 conn = (http_tls_t *)(http->tls);
3197 credentials = (gnutls_certificate_client_credentials *)(conn->credentials);
3198
3199 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
3200 gnutls_deinit(conn->session);
3201 gnutls_certificate_free_credentials(*credentials);
3202 free(credentials);
3203 free(conn);
3204
3205 # elif defined(HAVE_CDSASSL)
3206 http_tls_t *conn; /* CDSA connection information */
3207
3208
3209 conn = (http_tls_t *)(http->tls);
3210
3211 while (SSLClose(conn->session) == errSSLWouldBlock)
3212 usleep(1000);
3213
3214 SSLDisposeContext(conn->session);
3215
3216 if (conn->certsArray)
3217 CFRelease(conn->certsArray);
3218
3219 free(conn);
3220 # endif /* HAVE_LIBSSL */
3221
3222 http->tls = NULL;
3223 }
3224 #endif /* HAVE_SSL */
3225
3226
3227 #if defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD_H)
3228 /*
3229 * 'http_threadid_cb()' - Return the current thread ID.
3230 */
3231
3232 static unsigned long /* O - Thread ID */
http_threadid_cb(void)3233 http_threadid_cb(void)
3234 {
3235 return ((unsigned long)pthread_self());
3236 }
3237 #endif /* HAVE_LIBSSL && HAVE_PTHREAD_H */
3238
3239
3240 #ifdef HAVE_SSL
3241 /*
3242 * 'http_upgrade()' - Force upgrade to TLS encryption.
3243 */
3244
3245 static int /* O - Status of connection */
http_upgrade(http_t * http)3246 http_upgrade(http_t *http) /* I - Connection to server */
3247 {
3248 int ret; /* Return value */
3249 http_t myhttp; /* Local copy of HTTP data */
3250
3251
3252 DEBUG_printf(("7http_upgrade(%p)", http));
3253
3254 /*
3255 * Flush the connection to make sure any previous "Upgrade" message
3256 * has been read.
3257 */
3258
3259 httpFlush(http);
3260
3261 /*
3262 * Copy the HTTP data to a local variable so we can do the OPTIONS
3263 * request without interfering with the existing request data...
3264 */
3265
3266 memcpy(&myhttp, http, sizeof(myhttp));
3267
3268 /*
3269 * Send an OPTIONS request to the server, requiring SSL or TLS
3270 * encryption on the link...
3271 */
3272
3273 http->field_authorization = NULL; /* Don't free the auth string */
3274
3275 httpClearFields(http);
3276 httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
3277 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
3278
3279 if ((ret = httpOptions(http, "*")) == 0)
3280 {
3281 /*
3282 * Wait for the secure connection...
3283 */
3284
3285 while (httpUpdate(http) == HTTP_CONTINUE);
3286 }
3287
3288 /*
3289 * Restore the HTTP request data...
3290 */
3291
3292 memcpy(http->fields, myhttp.fields, sizeof(http->fields));
3293 http->data_encoding = myhttp.data_encoding;
3294 http->data_remaining = myhttp.data_remaining;
3295 http->_data_remaining = myhttp._data_remaining;
3296 http->expect = myhttp.expect;
3297 http->field_authorization = myhttp.field_authorization;
3298 http->digest_tries = myhttp.digest_tries;
3299
3300 /*
3301 * See if we actually went secure...
3302 */
3303
3304 if (!http->tls)
3305 {
3306 /*
3307 * Server does not support HTTP upgrade...
3308 */
3309
3310 DEBUG_puts("8http_upgrade: Server does not support HTTP upgrade!");
3311
3312 # ifdef WIN32
3313 closesocket(http->fd);
3314 # else
3315 close(http->fd);
3316 # endif
3317
3318 http->fd = -1;
3319
3320 return (-1);
3321 }
3322 else
3323 return (ret);
3324 }
3325 #endif /* HAVE_SSL */
3326
3327
3328 /*
3329 * 'http_write()' - Write a buffer to a HTTP connection.
3330 */
3331
3332 static int /* O - Number of bytes written */
http_write(http_t * http,const char * buffer,int length)3333 http_write(http_t *http, /* I - Connection to server */
3334 const char *buffer, /* I - Buffer for data */
3335 int length) /* I - Number of bytes to write */
3336 {
3337 int tbytes, /* Total bytes sent */
3338 bytes; /* Bytes sent */
3339
3340
3341 http->error = 0;
3342 tbytes = 0;
3343
3344 while (length > 0)
3345 {
3346 #ifdef HAVE_SSL
3347 if (http->tls)
3348 bytes = http_write_ssl(http, buffer, length);
3349 else
3350 #endif /* HAVE_SSL */
3351 bytes = send(http->fd, buffer, length, 0);
3352
3353 if (bytes < 0)
3354 {
3355 #ifdef WIN32
3356 if (WSAGetLastError() != http->error)
3357 {
3358 http->error = WSAGetLastError();
3359 continue;
3360 }
3361 #else
3362 if (errno == EINTR || errno == EAGAIN)
3363 continue;
3364 else if (errno != http->error && errno != ECONNRESET)
3365 {
3366 http->error = errno;
3367 continue;
3368 }
3369 #endif /* WIN32 */
3370
3371 DEBUG_puts("8http_write: error writing data...");
3372
3373 return (-1);
3374 }
3375
3376 buffer += bytes;
3377 tbytes += bytes;
3378 length -= bytes;
3379 }
3380
3381 #ifdef DEBUG
3382 http_debug_hex("http_write", buffer - tbytes, tbytes);
3383 #endif /* DEBUG */
3384
3385 return (tbytes);
3386 }
3387
3388
3389 /*
3390 * 'http_write_chunk()' - Write a chunked buffer.
3391 */
3392
3393 static int /* O - Number bytes written */
http_write_chunk(http_t * http,const char * buffer,int length)3394 http_write_chunk(http_t *http, /* I - Connection to server */
3395 const char *buffer, /* I - Buffer to write */
3396 int length) /* I - Length of buffer */
3397 {
3398 char header[255]; /* Chunk header */
3399 int bytes; /* Bytes written */
3400
3401
3402 DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=%d)",
3403 http, buffer, length));
3404
3405 /*
3406 * Write the chunk header, data, and trailer.
3407 */
3408
3409 sprintf(header, "%x\r\n", length);
3410 if (http_write(http, header, (int)strlen(header)) < 0)
3411 {
3412 DEBUG_puts("8http_write_chunk: http_write of length failed!");
3413 return (-1);
3414 }
3415
3416 if ((bytes = http_write(http, buffer, length)) < 0)
3417 {
3418 DEBUG_puts("8http_write_chunk: http_write of buffer failed!");
3419 return (-1);
3420 }
3421
3422 if (http_write(http, "\r\n", 2) < 0)
3423 {
3424 DEBUG_puts("8http_write_chunk: http_write of CR LF failed!");
3425 return (-1);
3426 }
3427
3428 return (bytes);
3429 }
3430
3431
3432 #ifdef HAVE_SSL
3433 /*
3434 * 'http_write_ssl()' - Write to a SSL/TLS connection.
3435 */
3436
3437 static int /* O - Bytes written */
http_write_ssl(http_t * http,const char * buf,int len)3438 http_write_ssl(http_t *http, /* I - Connection to server */
3439 const char *buf, /* I - Buffer holding data */
3440 int len) /* I - Length of buffer */
3441 {
3442 # if defined(HAVE_LIBSSL)
3443 return (SSL_write((SSL *)(http->tls), buf, len));
3444
3445 # elif defined(HAVE_GNUTLS)
3446 ssize_t result; /* Return value */
3447
3448 result = gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len);
3449
3450 if (result < 0 && !errno)
3451 {
3452 /*
3453 * Convert GNU TLS error to errno value...
3454 */
3455
3456 switch (result)
3457 {
3458 case GNUTLS_E_INTERRUPTED :
3459 errno = EINTR;
3460 break;
3461
3462 case GNUTLS_E_AGAIN :
3463 errno = EAGAIN;
3464 break;
3465
3466 default :
3467 errno = EPIPE;
3468 break;
3469 }
3470
3471 result = -1;
3472 }
3473
3474 return ((int)result);
3475
3476 # elif defined(HAVE_CDSASSL)
3477 int result; /* Return value */
3478 OSStatus error; /* Error info */
3479 size_t processed; /* Number of bytes processed */
3480
3481
3482 error = SSLWrite(((http_tls_t *)http->tls)->session, buf, len, &processed);
3483
3484 switch (error)
3485 {
3486 case 0 :
3487 result = (int)processed;
3488 break;
3489 case errSSLClosedGraceful :
3490 result = 0;
3491 break;
3492 case errSSLWouldBlock :
3493 if (processed)
3494 result = (int)processed;
3495 else
3496 {
3497 result = -1;
3498 errno = EINTR;
3499 }
3500 break;
3501 default :
3502 errno = EPIPE;
3503 result = -1;
3504 break;
3505 }
3506
3507 return (result);
3508 # endif /* HAVE_LIBSSL */
3509 }
3510 #endif /* HAVE_SSL */
3511
3512
3513 /*
3514 * End of "$Id: http.c 9233 2010-08-10 06:15:55Z mike $".
3515 */
3516