]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/http.c
Merge changes from CUPS 1.6svn-r10112.
[thirdparty/cups.git] / cups / http.c
1 /*
2 * "$Id: http.c 7850 2008-08-20 00:07:25Z mike $"
3 *
4 * HTTP routines for CUPS.
5 *
6 * Copyright 2007-2011 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 * httpAddCredential() - Allocates and adds a single credential to an
23 * array.
24 * _httpBIOMethods() - Get the OpenSSL BIO methods for HTTP
25 * connections.
26 * httpBlocking() - Set blocking/non-blocking behavior on a
27 * connection.
28 * httpCheck() - Check to see if there is a pending response
29 * from the server.
30 * httpClearCookie() - Clear the cookie value(s).
31 * httpClearFields() - Clear HTTP request fields.
32 * httpClose() - Close an HTTP connection.
33 * httpConnect() - Connect to a HTTP server.
34 * httpConnectEncrypt() - Connect to a HTTP server using encryption.
35 * httpCopyCredentials() - Copy the credentials associated with an
36 * encrypted connection.
37 * _httpCreate() - Create an unconnected HTTP connection.
38 * _httpCreateCredentials() - Create credentials in the internal format.
39 * httpDelete() - Send a DELETE request to the server.
40 * _httpDisconnect() - Disconnect a HTTP connection.
41 * httpEncryption() - Set the required encryption on the link.
42 * httpError() - Get the last error on a connection.
43 * httpFlush() - Flush data from a HTTP connection.
44 * httpFlushWrite() - Flush data in write buffer.
45 * _httpFreeCredentials() - Free internal credentials.
46 * httpFreeCredentials() - Free an array of credentials.
47 * httpGet() - Send a GET request to the server.
48 * httpGetAuthString() - Get the current authorization string.
49 * httpGetBlocking() - Get the blocking/non-block state of a
50 * connection.
51 * httpGetCookie() - Get any cookie data from the response.
52 * httpGetFd() - Get the file descriptor associated with a
53 * connection.
54 * httpGetField() - Get a field value from a request/response.
55 * httpGetLength() - Get the amount of data remaining from the
56 * content-length or transfer-encoding fields.
57 * httpGetLength2() - Get the amount of data remaining from the
58 * content-length or transfer-encoding fields.
59 * httpGets() - Get a line of text from a HTTP connection.
60 * httpGetState() - Get the current state of the HTTP request.
61 * httpGetStatus() - Get the status of the last HTTP request.
62 * httpGetSubField() - Get a sub-field value.
63 * httpGetSubField2() - Get a sub-field value.
64 * httpGetVersion() - Get the HTTP version at the other end.
65 * httpHead() - Send a HEAD request to the server.
66 * httpInitialize() - Initialize the HTTP interface library and set
67 * the default HTTP proxy (if any).
68 * httpOptions() - Send an OPTIONS request to the server.
69 * _httpPeek() - Peek at data from a HTTP connection.
70 * httpPost() - Send a POST request to the server.
71 * httpPrintf() - Print a formatted string to a HTTP connection.
72 * httpPut() - Send a PUT request to the server.
73 * httpRead() - Read data from a HTTP connection.
74 * httpRead2() - Read data from a HTTP connection.
75 * _httpReadCDSA() - Read function for the CDSA library.
76 * _httpReadGNUTLS() - Read function for the GNU TLS library.
77 * httpReconnect() - Reconnect to a HTTP server.
78 * httpSetAuthString() - Set the current authorization string.
79 * httpSetCredentials() - Set the credentials associated with an
80 * encrypted connection.
81 * httpSetCookie() - Set the cookie value(s).
82 * httpSetExpect() - Set the Expect: header in a request.
83 * httpSetField() - Set the value of an HTTP header.
84 * httpSetLength() - Set the content-length and content-encoding.
85 * httpSetTimeout() - Set read/write timeouts and an optional
86 * callback.
87 * httpTrace() - Send an TRACE request to the server.
88 * _httpUpdate() - Update the current HTTP status for incoming
89 * data.
90 * httpUpdate() - Update the current HTTP state for incoming
91 * data.
92 * _httpWait() - Wait for data available on a connection (no
93 * flush).
94 * httpWait() - Wait for data available on a connection.
95 * httpWrite() - Write data to a HTTP connection.
96 * httpWrite2() - Write data to a HTTP connection.
97 * _httpWriteCDSA() - Write function for the CDSA library.
98 * _httpWriteGNUTLS() - Write function for the GNU TLS library.
99 * http_bio_ctrl() - Control the HTTP connection.
100 * http_bio_free() - Free OpenSSL data.
101 * http_bio_new() - Initialize an OpenSSL BIO structure.
102 * http_bio_puts() - Send a string for OpenSSL.
103 * http_bio_read() - Read data for OpenSSL.
104 * http_bio_write() - Write data for OpenSSL.
105 * http_debug_hex() - Do a hex dump of a buffer.
106 * http_field() - Return the field index for a field name.
107 * http_read_ssl() - Read from a SSL/TLS connection.
108 * http_send() - Send a request with all fields and the trailing
109 * blank line.
110 * http_set_credentials() - Set the SSL/TLS credentials.
111 * http_set_timeout() - Set the socket timeout values.
112 * http_set_wait() - Set the default wait value for reads.
113 * http_setup_ssl() - Set up SSL/TLS support on a connection.
114 * http_shutdown_ssl() - Shut down SSL/TLS on a connection.
115 * http_upgrade() - Force upgrade to TLS encryption.
116 * http_write() - Write a buffer to a HTTP connection.
117 * http_write_chunk() - Write a chunked buffer.
118 * http_write_ssl() - Write to a SSL/TLS connection.
119 */
120
121 /*
122 * Include necessary headers...
123 */
124
125 #include "cups-private.h"
126 #include <fcntl.h>
127 #include <math.h>
128 #ifdef WIN32
129 # include <tchar.h>
130 #else
131 # include <signal.h>
132 # include <sys/time.h>
133 # include <sys/resource.h>
134 #endif /* WIN32 */
135 #ifdef HAVE_POLL
136 # include <sys/poll.h>
137 #endif /* HAVE_POLL */
138
139
140 /*
141 * Some operating systems have done away with the Fxxxx constants for
142 * the fcntl() call; this works around that "feature"...
143 */
144
145 #ifndef FNONBLK
146 # define FNONBLK O_NONBLOCK
147 #endif /* !FNONBLK */
148
149
150 /*
151 * Local functions...
152 */
153
154 #ifdef DEBUG
155 static void http_debug_hex(const char *prefix, const char *buffer,
156 int bytes);
157 #endif /* DEBUG */
158 static http_field_t http_field(const char *name);
159 static int http_send(http_t *http, http_state_t request,
160 const char *uri);
161 static int http_write(http_t *http, const char *buffer,
162 int length);
163 static int http_write_chunk(http_t *http, const char *buffer,
164 int length);
165 #ifdef HAVE_SSL
166 static int http_read_ssl(http_t *http, char *buf, int len);
167 # if defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
168 static int http_set_credentials(http_t *http);
169 # endif /* HAVE_CDSASSL ** HAVE_SECCERTIFICATECOPYDATA */
170 #endif /* HAVE_SSL */
171 static void http_set_timeout(int fd, double timeout);
172 static void http_set_wait(http_t *http);
173 #ifdef HAVE_SSL
174 static int http_setup_ssl(http_t *http);
175 static void http_shutdown_ssl(http_t *http);
176 static int http_upgrade(http_t *http);
177 static int http_write_ssl(http_t *http, const char *buf, int len);
178 #endif /* HAVE_SSL */
179
180
181 /*
182 * Local globals...
183 */
184
185 static const char * const http_fields[] =
186 {
187 "Accept-Language",
188 "Accept-Ranges",
189 "Authorization",
190 "Connection",
191 "Content-Encoding",
192 "Content-Language",
193 "Content-Length",
194 "Content-Location",
195 "Content-MD5",
196 "Content-Range",
197 "Content-Type",
198 "Content-Version",
199 "Date",
200 "Host",
201 "If-Modified-Since",
202 "If-Unmodified-since",
203 "Keep-Alive",
204 "Last-Modified",
205 "Link",
206 "Location",
207 "Range",
208 "Referer",
209 "Retry-After",
210 "Transfer-Encoding",
211 "Upgrade",
212 "User-Agent",
213 "WWW-Authenticate"
214 };
215 #ifdef DEBUG
216 static const char * const http_states[] =
217 {
218 "HTTP_WAITING",
219 "HTTP_OPTIONS",
220 "HTTP_GET",
221 "HTTP_GET_SEND",
222 "HTTP_HEAD",
223 "HTTP_POST",
224 "HTTP_POST_RECV",
225 "HTTP_POST_SEND",
226 "HTTP_PUT",
227 "HTTP_PUT_RECV",
228 "HTTP_DELETE",
229 "HTTP_TRACE",
230 "HTTP_CLOSE",
231 "HTTP_STATUS"
232 };
233 #endif /* DEBUG */
234
235
236 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
237 /*
238 * BIO methods for OpenSSL...
239 */
240
241 static int http_bio_write(BIO *h, const char *buf, int num);
242 static int http_bio_read(BIO *h, char *buf, int size);
243 static int http_bio_puts(BIO *h, const char *str);
244 static long http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
245 static int http_bio_new(BIO *h);
246 static int http_bio_free(BIO *data);
247
248 static BIO_METHOD http_bio_methods =
249 {
250 BIO_TYPE_SOCKET,
251 "http",
252 http_bio_write,
253 http_bio_read,
254 http_bio_puts,
255 NULL, /* http_bio_gets, */
256 http_bio_ctrl,
257 http_bio_new,
258 http_bio_free,
259 NULL,
260 };
261 #endif /* HAVE_SSL && HAVE_LIBSSL */
262
263
264 /*
265 * 'httpAddCredential()' - Allocates and adds a single credential to an array.
266 *
267 * Use @code cupsArrayNew(NULL, NULL)@ to create a credentials array.
268 *
269 * @since CUPS 1.5/Mac OS X 10.7@
270 */
271
272 int /* O - 0 on success, -1 on error */
273 httpAddCredential(
274 cups_array_t *credentials, /* I - Credentials array */
275 const void *data, /* I - PEM-encoded X.509 data */
276 size_t datalen) /* I - Length of data */
277 {
278 http_credential_t *credential; /* Credential data */
279
280
281 if ((credential = malloc(sizeof(http_credential_t))) != NULL)
282 {
283 credential->datalen = datalen;
284
285 if ((credential->data = malloc(datalen)) != NULL)
286 {
287 memcpy(credential->data, data, datalen);
288 cupsArrayAdd(credentials, credential);
289 return (0);
290 }
291
292 free(credential);
293 }
294
295 return (-1);
296 }
297
298
299 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
300 /*
301 * '_httpBIOMethods()' - Get the OpenSSL BIO methods for HTTP connections.
302 */
303
304 BIO_METHOD * /* O - BIO methods for OpenSSL */
305 _httpBIOMethods(void)
306 {
307 return (&http_bio_methods);
308 }
309 #endif /* HAVE_SSL && HAVE_LIBSSL */
310
311
312 /*
313 * 'httpBlocking()' - Set blocking/non-blocking behavior on a connection.
314 */
315
316 void
317 httpBlocking(http_t *http, /* I - Connection to server */
318 int b) /* I - 1 = blocking, 0 = non-blocking */
319 {
320 if (http)
321 {
322 http->blocking = b;
323 http_set_wait(http);
324 }
325 }
326
327
328 /*
329 * 'httpCheck()' - Check to see if there is a pending response from the server.
330 */
331
332 int /* O - 0 = no data, 1 = data available */
333 httpCheck(http_t *http) /* I - Connection to server */
334 {
335 return (httpWait(http, 0));
336 }
337
338
339 /*
340 * 'httpClearCookie()' - Clear the cookie value(s).
341 *
342 * @since CUPS 1.1.19/Mac OS X 10.3@
343 */
344
345 void
346 httpClearCookie(http_t *http) /* I - Connection to server */
347 {
348 if (!http)
349 return;
350
351 if (http->cookie)
352 {
353 free(http->cookie);
354 http->cookie = NULL;
355 }
356 }
357
358
359 /*
360 * 'httpClearFields()' - Clear HTTP request fields.
361 */
362
363 void
364 httpClearFields(http_t *http) /* I - Connection to server */
365 {
366 if (http)
367 {
368 memset(http->fields, 0, sizeof(http->fields));
369 if (http->hostname[0] == '/')
370 httpSetField(http, HTTP_FIELD_HOST, "localhost");
371 else
372 httpSetField(http, HTTP_FIELD_HOST, http->hostname);
373
374 if (http->field_authorization)
375 {
376 free(http->field_authorization);
377 http->field_authorization = NULL;
378 }
379
380 http->expect = (http_status_t)0;
381 }
382 }
383
384
385 /*
386 * 'httpClose()' - Close an HTTP connection.
387 */
388
389 void
390 httpClose(http_t *http) /* I - Connection to server */
391 {
392 #ifdef HAVE_GSSAPI
393 OM_uint32 minor_status; /* Minor status code */
394 #endif /* HAVE_GSSAPI */
395
396
397 DEBUG_printf(("httpClose(http=%p)", http));
398
399 /*
400 * Range check input...
401 */
402
403 if (!http)
404 return;
405
406 /*
407 * Close any open connection...
408 */
409
410 _httpDisconnect(http);
411
412 /*
413 * Free memory used...
414 */
415
416 httpAddrFreeList(http->addrlist);
417
418 if (http->cookie)
419 free(http->cookie);
420
421 #ifdef HAVE_GSSAPI
422 if (http->gssctx != GSS_C_NO_CONTEXT)
423 gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
424
425 if (http->gssname != GSS_C_NO_NAME)
426 gss_release_name(&minor_status, &http->gssname);
427 #endif /* HAVE_GSSAPI */
428
429 #ifdef HAVE_AUTHORIZATION_H
430 if (http->auth_ref)
431 AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults);
432 #endif /* HAVE_AUTHORIZATION_H */
433
434 httpClearFields(http);
435
436 if (http->authstring && http->authstring != http->_authstring)
437 free(http->authstring);
438
439 free(http);
440 }
441
442
443 /*
444 * 'httpConnect()' - Connect to a HTTP server.
445 *
446 * This function is deprecated - use @link httpConnectEncrypt@ instead.
447 *
448 * @deprecated@
449 */
450
451 http_t * /* O - New HTTP connection */
452 httpConnect(const char *host, /* I - Host to connect to */
453 int port) /* I - Port number */
454 {
455 return (httpConnectEncrypt(host, port, HTTP_ENCRYPT_IF_REQUESTED));
456 }
457
458
459 /*
460 * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
461 */
462
463 http_t * /* O - New HTTP connection */
464 httpConnectEncrypt(
465 const char *host, /* I - Host to connect to */
466 int port, /* I - Port number */
467 http_encryption_t encryption) /* I - Type of encryption to use */
468 {
469 http_t *http; /* New HTTP connection */
470
471
472 DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encryption=%d)",
473 host, port, encryption));
474
475 /*
476 * Create the HTTP structure...
477 */
478
479 if ((http = _httpCreate(host, port, NULL, encryption, AF_UNSPEC)) == NULL)
480 return (NULL);
481
482 /*
483 * Connect to the remote system...
484 */
485
486 if (!httpReconnect(http))
487 return (http);
488
489 /*
490 * Could not connect to any known address - bail out!
491 */
492
493 httpAddrFreeList(http->addrlist);
494
495 free(http);
496
497 return (NULL);
498 }
499
500
501 /*
502 * 'httpCopyCredentials()' - Copy the credentials associated with an encrypted
503 * connection.
504 *
505 * @since CUPS 1.5/Mac OS X 10.7@
506 */
507
508 int /* O - Status of call (0 = success) */
509 httpCopyCredentials(
510 http_t *http, /* I - Connection to server */
511 cups_array_t **credentials) /* O - Array of credentials */
512 {
513 # ifdef HAVE_LIBSSL
514 # elif defined(HAVE_GNUTLS)
515 # elif defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
516 OSStatus error; /* Error code */
517 CFIndex count; /* Number of credentials */
518 CFArrayRef peerCerts; /* Peer certificates */
519 SecCertificateRef secCert; /* Certificate reference */
520 CFDataRef data; /* Certificate data */
521 int i; /* Looping var */
522 # elif defined(HAVE_SSPISSL)
523 # endif /* HAVE_LIBSSL */
524
525
526 if (credentials)
527 *credentials = NULL;
528
529 if (!http || !http->tls || !credentials)
530 return (-1);
531
532 # ifdef HAVE_LIBSSL
533 return (-1);
534
535 # elif defined(HAVE_GNUTLS)
536 return (-1);
537
538 # elif defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
539 if (!(error = SSLCopyPeerCertificates(http->tls, &peerCerts)) && peerCerts)
540 {
541 if ((*credentials = cupsArrayNew(NULL, NULL)) != NULL)
542 {
543 for (i = 0, count = CFArrayGetCount(peerCerts); i < count; i++)
544 {
545 secCert = (SecCertificateRef)CFArrayGetValueAtIndex(peerCerts, i);
546 if ((data = SecCertificateCopyData(secCert)))
547 {
548 httpAddCredential(*credentials, CFDataGetBytePtr(data),
549 CFDataGetLength(data));
550 CFRelease(data);
551 }
552 }
553 }
554
555 CFRelease(peerCerts);
556 }
557
558 return (error);
559
560 # elif defined(HAVE_SSPISSL)
561 return (-1);
562
563 # else
564 return (-1);
565 # endif /* HAVE_LIBSSL */
566 }
567
568
569 /*
570 * '_httpCreate()' - Create an unconnected HTTP connection.
571 */
572
573 http_t * /* O - HTTP connection */
574 _httpCreate(
575 const char *host, /* I - Hostname */
576 int port, /* I - Port number */
577 http_addrlist_t *addrlist, /* I - Address list or NULL */
578 http_encryption_t encryption, /* I - Encryption to use */
579 int family) /* I - Address family or AF_UNSPEC */
580 {
581 http_t *http; /* New HTTP connection */
582 char service[255]; /* Service name */
583
584
585 DEBUG_printf(("4_httpCreate(host=\"%s\", port=%d, encryption=%d)",
586 host, port, encryption));
587
588 if (!host)
589 return (NULL);
590
591 httpInitialize();
592
593 /*
594 * Lookup the host...
595 */
596
597 sprintf(service, "%d", port);
598
599 if (!addrlist)
600 if ((addrlist = httpAddrGetList(host, family, service)) == NULL)
601 return (NULL);
602
603 /*
604 * Allocate memory for the structure...
605 */
606
607 if ((http = calloc(sizeof(http_t), 1)) == NULL)
608 {
609 httpAddrFreeList(addrlist);
610 return (NULL);
611 }
612
613 /*
614 * Initialize the HTTP data...
615 */
616
617 http->activity = time(NULL);
618 http->addrlist = addrlist;
619 http->blocking = 1;
620 http->fd = -1;
621 #ifdef HAVE_GSSAPI
622 http->gssctx = GSS_C_NO_CONTEXT;
623 http->gssname = GSS_C_NO_NAME;
624 #endif /* HAVE_GSSAPI */
625 http->version = HTTP_1_1;
626
627 strlcpy(http->hostname, host, sizeof(http->hostname));
628
629 if (port == 443) /* Always use encryption for https */
630 http->encryption = HTTP_ENCRYPT_ALWAYS;
631 else
632 http->encryption = encryption;
633
634 http_set_wait(http);
635
636 /*
637 * Return the new structure...
638 */
639
640 return (http);
641 }
642
643
644 /*
645 * '_httpCreateCredentials()' - Create credentials in the internal format.
646 */
647
648 http_tls_credentials_t /* O - Internal credentials */
649 _httpCreateCredentials(
650 cups_array_t *credentials) /* I - Array of credentials */
651 {
652 if (!credentials)
653 return (NULL);
654
655 # ifdef HAVE_LIBSSL
656 return (NULL);
657
658 # elif defined(HAVE_GNUTLS)
659 return (NULL);
660
661 # elif defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
662 CFMutableArrayRef peerCerts; /* Peer credentials reference */
663 SecCertificateRef secCert; /* Certificate reference */
664 CFDataRef data; /* Credential data reference */
665 http_credential_t *credential; /* Credential data */
666
667
668 if ((peerCerts = CFArrayCreateMutable(kCFAllocatorDefault,
669 cupsArrayCount(credentials),
670 &kCFTypeArrayCallBacks)) == NULL)
671 return (NULL);
672
673 for (credential = (http_credential_t *)cupsArrayFirst(credentials);
674 credential;
675 credential = (http_credential_t *)cupsArrayNext(credentials))
676 {
677 if ((data = CFDataCreate(kCFAllocatorDefault, credential->data,
678 credential->datalen)))
679 {
680 if ((secCert = SecCertificateCreateWithData(kCFAllocatorDefault, data))
681 != NULL)
682 {
683 CFArrayAppendValue(peerCerts, secCert);
684 CFRelease(secCert);
685 }
686
687 CFRelease(data);
688 }
689 }
690
691 return (peerCerts);
692
693 # elif defined(HAVE_SSPISSL)
694 return (NULL);
695
696 # else
697 return (NULL);
698 # endif /* HAVE_LIBSSL */
699 }
700
701
702 /*
703 * 'httpDelete()' - Send a DELETE request to the server.
704 */
705
706 int /* O - Status of call (0 = success) */
707 httpDelete(http_t *http, /* I - Connection to server */
708 const char *uri) /* I - URI to delete */
709 {
710 return (http_send(http, HTTP_DELETE, uri));
711 }
712
713
714 /*
715 * '_httpDisconnect()' - Disconnect a HTTP connection.
716 */
717
718 void
719 _httpDisconnect(http_t *http) /* I - Connection to server */
720 {
721 #ifdef HAVE_SSL
722 if (http->tls)
723 http_shutdown_ssl(http);
724 #endif /* HAVE_SSL */
725
726 #ifdef WIN32
727 closesocket(http->fd);
728 #else
729 close(http->fd);
730 #endif /* WIN32 */
731
732 http->fd = -1;
733 }
734
735
736 /*
737 * 'httpEncryption()' - Set the required encryption on the link.
738 */
739
740 int /* O - -1 on error, 0 on success */
741 httpEncryption(http_t *http, /* I - Connection to server */
742 http_encryption_t e) /* I - New encryption preference */
743 {
744 DEBUG_printf(("httpEncryption(http=%p, e=%d)", http, e));
745
746 #ifdef HAVE_SSL
747 if (!http)
748 return (0);
749
750 http->encryption = e;
751
752 if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||
753 (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))
754 return (httpReconnect(http));
755 else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
756 return (http_upgrade(http));
757 else
758 return (0);
759 #else
760 if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)
761 return (-1);
762 else
763 return (0);
764 #endif /* HAVE_SSL */
765 }
766
767
768 /*
769 * 'httpError()' - Get the last error on a connection.
770 */
771
772 int /* O - Error code (errno) value */
773 httpError(http_t *http) /* I - Connection to server */
774 {
775 if (http)
776 return (http->error);
777 else
778 return (EINVAL);
779 }
780
781
782 /*
783 * 'httpFlush()' - Flush data from a HTTP connection.
784 */
785
786 void
787 httpFlush(http_t *http) /* I - Connection to server */
788 {
789 char buffer[8192]; /* Junk buffer */
790 int blocking; /* To block or not to block */
791 http_state_t oldstate; /* Old state */
792
793
794 DEBUG_printf(("httpFlush(http=%p), state=%s", http,
795 http_states[http->state]));
796
797 /*
798 * Temporarily set non-blocking mode so we don't get stuck in httpRead()...
799 */
800
801 blocking = http->blocking;
802 http->blocking = 0;
803
804 /*
805 * Read any data we can...
806 */
807
808 oldstate = http->state;
809 while (httpRead2(http, buffer, sizeof(buffer)) > 0);
810
811 /*
812 * Restore blocking and reset the connection if we didn't get all of
813 * the remaining data...
814 */
815
816 http->blocking = blocking;
817
818 if (http->state == oldstate && http->state != HTTP_WAITING && http->fd >= 0)
819 {
820 /*
821 * Didn't get the data back, so close the current connection.
822 */
823
824 http->state = HTTP_WAITING;
825
826 #ifdef HAVE_SSL
827 if (http->tls)
828 http_shutdown_ssl(http);
829 #endif /* HAVE_SSL */
830
831 #ifdef WIN32
832 closesocket(http->fd);
833 #else
834 close(http->fd);
835 #endif /* WIN32 */
836
837 http->fd = -1;
838 }
839 }
840
841
842 /*
843 * 'httpFlushWrite()' - Flush data in write buffer.
844 *
845 * @since CUPS 1.2/Mac OS X 10.5@
846 */
847
848 int /* O - Bytes written or -1 on error */
849 httpFlushWrite(http_t *http) /* I - Connection to server */
850 {
851 int bytes; /* Bytes written */
852
853
854 DEBUG_printf(("httpFlushWrite(http=%p)", http));
855
856 if (!http || !http->wused)
857 {
858 DEBUG_puts(http ? "1httpFlushWrite: Write buffer is empty." :
859 "1httpFlushWrite: No connection.");
860 return (0);
861 }
862
863 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
864 bytes = http_write_chunk(http, http->wbuffer, http->wused);
865 else
866 bytes = http_write(http, http->wbuffer, http->wused);
867
868 http->wused = 0;
869
870 DEBUG_printf(("1httpFlushWrite: Returning %d, errno=%d.", bytes, errno));
871
872 return (bytes);
873 }
874
875
876 /*
877 * '_httpFreeCredentials()' - Free internal credentials.
878 */
879
880 void
881 _httpFreeCredentials(
882 http_tls_credentials_t credentials) /* I - Internal credentials */
883 {
884 if (!credentials)
885 return;
886
887 #ifdef HAVE_LIBSSL
888 (void)credentials;
889
890 #elif defined(HAVE_GNUTLS)
891 (void)credentials;
892
893 #elif defined(HAVE_CDSASSL)
894 CFRelease(credentials);
895
896 #elif defined(HAVE_SSPISSL)
897 (void)credentials;
898
899 #endif /* HAVE_LIBSSL */
900 }
901
902
903 /*
904 * 'httpFreeCredentials()' - Free an array of credentials.
905 */
906
907 void
908 httpFreeCredentials(
909 cups_array_t *credentials) /* I - Array of credentials */
910 {
911 http_credential_t *credential; /* Credential */
912
913
914 for (credential = (http_credential_t *)cupsArrayFirst(credentials);
915 credential;
916 credential = (http_credential_t *)cupsArrayNext(credentials))
917 {
918 cupsArrayRemove(credentials, credential);
919 free((void *)credential->data);
920 free(credential);
921 }
922
923 cupsArrayDelete(credentials);
924 }
925
926
927 /*
928 * 'httpGet()' - Send a GET request to the server.
929 */
930
931 int /* O - Status of call (0 = success) */
932 httpGet(http_t *http, /* I - Connection to server */
933 const char *uri) /* I - URI to get */
934 {
935 return (http_send(http, HTTP_GET, uri));
936 }
937
938
939 /*
940 * 'httpGetAuthString()' - Get the current authorization string.
941 *
942 * The authorization string is set by cupsDoAuthentication() and
943 * httpSetAuthString(). Use httpGetAuthString() to retrieve the
944 * string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION
945 * value.
946 *
947 * @since CUPS 1.3/Mac OS X 10.5@
948 */
949
950 char * /* O - Authorization string */
951 httpGetAuthString(http_t *http) /* I - Connection to server */
952 {
953 if (http)
954 return (http->authstring);
955 else
956 return (NULL);
957 }
958
959
960 /*
961 * 'httpGetBlocking()' - Get the blocking/non-block state of a connection.
962 *
963 * @since CUPS 1.2/Mac OS X 10.5@
964 */
965
966 int /* O - 1 if blocking, 0 if non-blocking */
967 httpGetBlocking(http_t *http) /* I - Connection to server */
968 {
969 return (http ? http->blocking : 0);
970 }
971
972
973 /*
974 * 'httpGetCookie()' - Get any cookie data from the response.
975 *
976 * @since CUPS 1.1.19/Mac OS X 10.3@
977 */
978
979 const char * /* O - Cookie data or NULL */
980 httpGetCookie(http_t *http) /* I - HTTP connecion */
981 {
982 return (http ? http->cookie : NULL);
983 }
984
985
986 /*
987 * 'httpGetFd()' - Get the file descriptor associated with a connection.
988 *
989 * @since CUPS 1.2/Mac OS X 10.5@
990 */
991
992 int /* O - File descriptor or -1 if none */
993 httpGetFd(http_t *http) /* I - Connection to server */
994 {
995 return (http ? http->fd : -1);
996 }
997
998
999 /*
1000 * 'httpGetField()' - Get a field value from a request/response.
1001 */
1002
1003 const char * /* O - Field value */
1004 httpGetField(http_t *http, /* I - Connection to server */
1005 http_field_t field) /* I - Field to get */
1006 {
1007 if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
1008 return (NULL);
1009 else if (field == HTTP_FIELD_AUTHORIZATION &&
1010 http->field_authorization)
1011 {
1012 /*
1013 * Special case for WWW-Authenticate: as its contents can be
1014 * longer than HTTP_MAX_VALUE...
1015 */
1016
1017 return (http->field_authorization);
1018 }
1019 else
1020 return (http->fields[field]);
1021 }
1022
1023
1024 /*
1025 * 'httpGetLength()' - Get the amount of data remaining from the
1026 * content-length or transfer-encoding fields.
1027 *
1028 * This function is deprecated and will not return lengths larger than
1029 * 2^31 - 1; use httpGetLength2() instead.
1030 *
1031 * @deprecated@
1032 */
1033
1034 int /* O - Content length */
1035 httpGetLength(http_t *http) /* I - Connection to server */
1036 {
1037 /*
1038 * Get the read content length and return the 32-bit value.
1039 */
1040
1041 if (http)
1042 {
1043 httpGetLength2(http);
1044
1045 return (http->_data_remaining);
1046 }
1047 else
1048 return (-1);
1049 }
1050
1051
1052 /*
1053 * 'httpGetLength2()' - Get the amount of data remaining from the
1054 * content-length or transfer-encoding fields.
1055 *
1056 * This function returns the complete content length, even for
1057 * content larger than 2^31 - 1.
1058 *
1059 * @since CUPS 1.2/Mac OS X 10.5@
1060 */
1061
1062 off_t /* O - Content length */
1063 httpGetLength2(http_t *http) /* I - Connection to server */
1064 {
1065 DEBUG_printf(("2httpGetLength2(http=%p), state=%s", http,
1066 http_states[http->state]));
1067
1068 if (!http)
1069 return (-1);
1070
1071 if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked"))
1072 {
1073 DEBUG_puts("4httpGetLength2: chunked request!");
1074
1075 http->data_encoding = HTTP_ENCODE_CHUNKED;
1076 http->data_remaining = 0;
1077 }
1078 else
1079 {
1080 http->data_encoding = HTTP_ENCODE_LENGTH;
1081
1082 /*
1083 * The following is a hack for HTTP servers that don't send a
1084 * content-length or transfer-encoding field...
1085 *
1086 * If there is no content-length then the connection must close
1087 * after the transfer is complete...
1088 */
1089
1090 if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0])
1091 {
1092 /*
1093 * Default content length is 0 for errors and 2^31-1 for other
1094 * successful requests...
1095 */
1096
1097 if (http->status >= HTTP_MULTIPLE_CHOICES)
1098 http->data_remaining = 0;
1099 else
1100 http->data_remaining = 2147483647;
1101 }
1102 else
1103 http->data_remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH],
1104 NULL, 10);
1105
1106 DEBUG_printf(("4httpGetLength2: content_length=" CUPS_LLFMT,
1107 CUPS_LLCAST http->data_remaining));
1108 }
1109
1110 if (http->data_remaining <= INT_MAX)
1111 http->_data_remaining = (int)http->data_remaining;
1112 else
1113 http->_data_remaining = INT_MAX;
1114
1115 return (http->data_remaining);
1116 }
1117
1118
1119 /*
1120 * 'httpGets()' - Get a line of text from a HTTP connection.
1121 */
1122
1123 char * /* O - Line or NULL */
1124 httpGets(char *line, /* I - Line to read into */
1125 int length, /* I - Max length of buffer */
1126 http_t *http) /* I - Connection to server */
1127 {
1128 char *lineptr, /* Pointer into line */
1129 *lineend, /* End of line */
1130 *bufptr, /* Pointer into input buffer */
1131 *bufend; /* Pointer to end of buffer */
1132 int bytes, /* Number of bytes read */
1133 eol; /* End-of-line? */
1134
1135
1136 DEBUG_printf(("2httpGets(line=%p, length=%d, http=%p)", line, length, http));
1137
1138 if (http == NULL || line == NULL)
1139 return (NULL);
1140
1141 /*
1142 * Read a line from the buffer...
1143 */
1144
1145 http->error = 0;
1146 lineptr = line;
1147 lineend = line + length - 1;
1148 eol = 0;
1149
1150 while (lineptr < lineend)
1151 {
1152 /*
1153 * Pre-load the buffer as needed...
1154 */
1155
1156 #ifdef WIN32
1157 WSASetLastError(0);
1158 #else
1159 errno = 0;
1160 #endif /* WIN32 */
1161
1162 while (http->used == 0)
1163 {
1164 /*
1165 * No newline; see if there is more data to be read...
1166 */
1167
1168 while (!_httpWait(http, http->wait_value, 1))
1169 {
1170 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1171 continue;
1172
1173 DEBUG_puts("3httpGets: Timed out!");
1174 #ifdef WIN32
1175 http->error = WSAETIMEDOUT;
1176 #else
1177 http->error = ETIMEDOUT;
1178 #endif /* WIN32 */
1179 return (NULL);
1180 }
1181
1182 #ifdef HAVE_SSL
1183 if (http->tls)
1184 bytes = http_read_ssl(http, http->buffer + http->used,
1185 HTTP_MAX_BUFFER - http->used);
1186 else
1187 #endif /* HAVE_SSL */
1188 bytes = recv(http->fd, http->buffer + http->used,
1189 HTTP_MAX_BUFFER - http->used, 0);
1190
1191 DEBUG_printf(("4httpGets: read %d bytes...", bytes));
1192
1193 if (bytes < 0)
1194 {
1195 /*
1196 * Nope, can't get a line this time...
1197 */
1198
1199 #ifdef WIN32
1200 DEBUG_printf(("3httpGets: recv() error %d!", WSAGetLastError()));
1201
1202 if (WSAGetLastError() == WSAEINTR)
1203 continue;
1204 else if (WSAGetLastError() == WSAEWOULDBLOCK)
1205 {
1206 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1207 continue;
1208
1209 http->error = WSAGetLastError();
1210 }
1211 else if (WSAGetLastError() != http->error)
1212 {
1213 http->error = WSAGetLastError();
1214 continue;
1215 }
1216
1217 #else
1218 DEBUG_printf(("3httpGets: recv() error %d!", errno));
1219
1220 if (errno == EINTR)
1221 continue;
1222 else if (errno == EWOULDBLOCK || errno == EAGAIN)
1223 {
1224 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1225 continue;
1226 else if (!http->timeout_cb && errno == EAGAIN)
1227 continue;
1228
1229 http->error = errno;
1230 }
1231 else if (errno != http->error)
1232 {
1233 http->error = errno;
1234 continue;
1235 }
1236 #endif /* WIN32 */
1237
1238 return (NULL);
1239 }
1240 else if (bytes == 0)
1241 {
1242 http->error = EPIPE;
1243
1244 return (NULL);
1245 }
1246
1247 /*
1248 * Yup, update the amount used...
1249 */
1250
1251 http->used += bytes;
1252 }
1253
1254 /*
1255 * Now copy as much of the current line as possible...
1256 */
1257
1258 for (bufptr = http->buffer, bufend = http->buffer + http->used;
1259 lineptr < lineend && bufptr < bufend;)
1260 {
1261 if (*bufptr == 0x0a)
1262 {
1263 eol = 1;
1264 bufptr ++;
1265 break;
1266 }
1267 else if (*bufptr == 0x0d)
1268 bufptr ++;
1269 else
1270 *lineptr++ = *bufptr++;
1271 }
1272
1273 http->used -= (int)(bufptr - http->buffer);
1274 if (http->used > 0)
1275 memmove(http->buffer, bufptr, http->used);
1276
1277 if (eol)
1278 {
1279 /*
1280 * End of line...
1281 */
1282
1283 http->activity = time(NULL);
1284
1285 *lineptr = '\0';
1286
1287 DEBUG_printf(("3httpGets: Returning \"%s\"", line));
1288
1289 return (line);
1290 }
1291 }
1292
1293 DEBUG_puts("3httpGets: No new line available!");
1294
1295 return (NULL);
1296 }
1297
1298
1299 /*
1300 * 'httpGetState()' - Get the current state of the HTTP request.
1301 */
1302
1303 http_state_t /* O - HTTP state */
1304 httpGetState(http_t *http) /* I - Connection to server */
1305 {
1306 return (http ? http->state : HTTP_ERROR);
1307 }
1308
1309
1310 /*
1311 * 'httpGetStatus()' - Get the status of the last HTTP request.
1312 *
1313 * @since CUPS 1.2/Mac OS X 10.5@
1314 */
1315
1316 http_status_t /* O - HTTP status */
1317 httpGetStatus(http_t *http) /* I - Connection to server */
1318 {
1319 return (http ? http->status : HTTP_ERROR);
1320 }
1321
1322
1323 /*
1324 * 'httpGetSubField()' - Get a sub-field value.
1325 *
1326 * @deprecated@
1327 */
1328
1329 char * /* O - Value or NULL */
1330 httpGetSubField(http_t *http, /* I - Connection to server */
1331 http_field_t field, /* I - Field index */
1332 const char *name, /* I - Name of sub-field */
1333 char *value) /* O - Value string */
1334 {
1335 return (httpGetSubField2(http, field, name, value, HTTP_MAX_VALUE));
1336 }
1337
1338
1339 /*
1340 * 'httpGetSubField2()' - Get a sub-field value.
1341 *
1342 * @since CUPS 1.2/Mac OS X 10.5@
1343 */
1344
1345 char * /* O - Value or NULL */
1346 httpGetSubField2(http_t *http, /* I - Connection to server */
1347 http_field_t field, /* I - Field index */
1348 const char *name, /* I - Name of sub-field */
1349 char *value, /* O - Value string */
1350 int valuelen) /* I - Size of value buffer */
1351 {
1352 const char *fptr; /* Pointer into field */
1353 char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */
1354 *ptr, /* Pointer into string buffer */
1355 *end; /* End of value buffer */
1356
1357 DEBUG_printf(("2httpGetSubField2(http=%p, field=%d, name=\"%s\", value=%p, "
1358 "valuelen=%d)", http, field, name, value, valuelen));
1359
1360 if (!http || !name || !value || valuelen < 2 ||
1361 field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX)
1362 return (NULL);
1363
1364 end = value + valuelen - 1;
1365
1366 for (fptr = http->fields[field]; *fptr;)
1367 {
1368 /*
1369 * Skip leading whitespace...
1370 */
1371
1372 while (_cups_isspace(*fptr))
1373 fptr ++;
1374
1375 if (*fptr == ',')
1376 {
1377 fptr ++;
1378 continue;
1379 }
1380
1381 /*
1382 * Get the sub-field name...
1383 */
1384
1385 for (ptr = temp;
1386 *fptr && *fptr != '=' && !_cups_isspace(*fptr) &&
1387 ptr < (temp + sizeof(temp) - 1);
1388 *ptr++ = *fptr++);
1389
1390 *ptr = '\0';
1391
1392 DEBUG_printf(("4httpGetSubField2: name=\"%s\"", temp));
1393
1394 /*
1395 * Skip trailing chars up to the '='...
1396 */
1397
1398 while (_cups_isspace(*fptr))
1399 fptr ++;
1400
1401 if (!*fptr)
1402 break;
1403
1404 if (*fptr != '=')
1405 continue;
1406
1407 /*
1408 * Skip = and leading whitespace...
1409 */
1410
1411 fptr ++;
1412
1413 while (_cups_isspace(*fptr))
1414 fptr ++;
1415
1416 if (*fptr == '\"')
1417 {
1418 /*
1419 * Read quoted string...
1420 */
1421
1422 for (ptr = value, fptr ++;
1423 *fptr && *fptr != '\"' && ptr < end;
1424 *ptr++ = *fptr++);
1425
1426 *ptr = '\0';
1427
1428 while (*fptr && *fptr != '\"')
1429 fptr ++;
1430
1431 if (*fptr)
1432 fptr ++;
1433 }
1434 else
1435 {
1436 /*
1437 * Read unquoted string...
1438 */
1439
1440 for (ptr = value;
1441 *fptr && !_cups_isspace(*fptr) && *fptr != ',' && ptr < end;
1442 *ptr++ = *fptr++);
1443
1444 *ptr = '\0';
1445
1446 while (*fptr && !_cups_isspace(*fptr) && *fptr != ',')
1447 fptr ++;
1448 }
1449
1450 DEBUG_printf(("4httpGetSubField2: value=\"%s\"", value));
1451
1452 /*
1453 * See if this is the one...
1454 */
1455
1456 if (!strcmp(name, temp))
1457 {
1458 DEBUG_printf(("3httpGetSubField2: Returning \"%s\"", value));
1459 return (value);
1460 }
1461 }
1462
1463 value[0] = '\0';
1464
1465 DEBUG_puts("3httpGetSubField2: Returning NULL");
1466
1467 return (NULL);
1468 }
1469
1470
1471 /*
1472 * 'httpGetVersion()' - Get the HTTP version at the other end.
1473 */
1474
1475 http_version_t /* O - Version number */
1476 httpGetVersion(http_t *http) /* I - Connection to server */
1477 {
1478 return (http ? http->version : HTTP_1_0);
1479 }
1480
1481
1482 /*
1483 * 'httpHead()' - Send a HEAD request to the server.
1484 */
1485
1486 int /* O - Status of call (0 = success) */
1487 httpHead(http_t *http, /* I - Connection to server */
1488 const char *uri) /* I - URI for head */
1489 {
1490 DEBUG_printf(("httpHead(http=%p, uri=\"%s\")", http, uri));
1491 return (http_send(http, HTTP_HEAD, uri));
1492 }
1493
1494
1495 /*
1496 * 'httpInitialize()' - Initialize the HTTP interface library and set the
1497 * default HTTP proxy (if any).
1498 */
1499
1500 void
1501 httpInitialize(void)
1502 {
1503 static int initialized = 0; /* Have we been called before? */
1504 #ifdef WIN32
1505 WSADATA winsockdata; /* WinSock data */
1506 #endif /* WIN32 */
1507 #ifdef HAVE_LIBSSL
1508 int i; /* Looping var */
1509 unsigned char data[1024]; /* Seed data */
1510 #endif /* HAVE_LIBSSL */
1511
1512
1513 _cupsGlobalLock();
1514 if (initialized)
1515 {
1516 _cupsGlobalUnlock();
1517 return;
1518 }
1519
1520 #ifdef WIN32
1521 WSAStartup(MAKEWORD(2,2), &winsockdata);
1522
1523 #elif !defined(SO_NOSIGPIPE)
1524 /*
1525 * Ignore SIGPIPE signals...
1526 */
1527
1528 # ifdef HAVE_SIGSET
1529 sigset(SIGPIPE, SIG_IGN);
1530
1531 # elif defined(HAVE_SIGACTION)
1532 struct sigaction action; /* POSIX sigaction data */
1533
1534
1535 memset(&action, 0, sizeof(action));
1536 action.sa_handler = SIG_IGN;
1537 sigaction(SIGPIPE, &action, NULL);
1538
1539 # else
1540 signal(SIGPIPE, SIG_IGN);
1541 # endif /* !SO_NOSIGPIPE */
1542 #endif /* WIN32 */
1543
1544 #ifdef HAVE_GNUTLS
1545 /*
1546 * Initialize GNU TLS...
1547 */
1548
1549 gnutls_global_init();
1550
1551 #elif defined(HAVE_LIBSSL)
1552 /*
1553 * Initialize OpenSSL...
1554 */
1555
1556 SSL_load_error_strings();
1557 SSL_library_init();
1558
1559 /*
1560 * Using the current time is a dubious random seed, but on some systems
1561 * it is the best we can do (on others, this seed isn't even used...)
1562 */
1563
1564 CUPS_SRAND(time(NULL));
1565
1566 for (i = 0; i < sizeof(data); i ++)
1567 data[i] = CUPS_RAND();
1568
1569 RAND_seed(data, sizeof(data));
1570 #endif /* HAVE_GNUTLS */
1571
1572 initialized = 1;
1573 _cupsGlobalUnlock();
1574 }
1575
1576
1577 /*
1578 * 'httpOptions()' - Send an OPTIONS request to the server.
1579 */
1580
1581 int /* O - Status of call (0 = success) */
1582 httpOptions(http_t *http, /* I - Connection to server */
1583 const char *uri) /* I - URI for options */
1584 {
1585 return (http_send(http, HTTP_OPTIONS, uri));
1586 }
1587
1588
1589 /*
1590 * '_httpPeek()' - Peek at data from a HTTP connection.
1591 *
1592 * This function copies available data from the given HTTP connection, reading
1593 * a buffer as needed. The data is still available for reading using
1594 * @link httpRead@ or @link httpRead2@.
1595 *
1596 * For non-blocking connections the usual timeouts apply.
1597 */
1598
1599 ssize_t /* O - Number of bytes copied */
1600 _httpPeek(http_t *http, /* I - Connection to server */
1601 char *buffer, /* I - Buffer for data */
1602 size_t length) /* I - Maximum number of bytes */
1603 {
1604 ssize_t bytes; /* Bytes read */
1605 char len[32]; /* Length string */
1606
1607
1608 DEBUG_printf(("_httpPeek(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
1609 http, buffer, CUPS_LLCAST length));
1610
1611 if (http == NULL || buffer == NULL)
1612 return (-1);
1613
1614 http->activity = time(NULL);
1615 http->error = 0;
1616
1617 if (length <= 0)
1618 return (0);
1619
1620 if (http->data_encoding == HTTP_ENCODE_CHUNKED &&
1621 http->data_remaining <= 0)
1622 {
1623 DEBUG_puts("2_httpPeek: Getting chunk length...");
1624
1625 if (httpGets(len, sizeof(len), http) == NULL)
1626 {
1627 DEBUG_puts("1_httpPeek: Could not get length!");
1628 return (0);
1629 }
1630
1631 http->data_remaining = strtoll(len, NULL, 16);
1632 if (http->data_remaining < 0)
1633 {
1634 DEBUG_puts("1_httpPeek: Negative chunk length!");
1635 return (0);
1636 }
1637 }
1638
1639 DEBUG_printf(("2_httpPeek: data_remaining=" CUPS_LLFMT,
1640 CUPS_LLCAST http->data_remaining));
1641
1642 if (http->data_remaining <= 0)
1643 {
1644 /*
1645 * A zero-length chunk ends a transfer; unless we are reading POST
1646 * data, go idle...
1647 */
1648
1649 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1650 httpGets(len, sizeof(len), http);
1651
1652 if (http->state == HTTP_POST_RECV)
1653 http->state ++;
1654 else
1655 http->state = HTTP_WAITING;
1656
1657 /*
1658 * Prevent future reads for this request...
1659 */
1660
1661 http->data_encoding = HTTP_ENCODE_LENGTH;
1662
1663 return (0);
1664 }
1665 else if (length > (size_t)http->data_remaining)
1666 length = (size_t)http->data_remaining;
1667
1668 if (http->used == 0)
1669 {
1670 /*
1671 * Buffer small reads for better performance...
1672 */
1673
1674 if (!http->blocking)
1675 {
1676 while (!httpWait(http, http->wait_value))
1677 {
1678 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1679 continue;
1680
1681 return (0);
1682 }
1683 }
1684
1685 if (http->data_remaining > sizeof(http->buffer))
1686 bytes = sizeof(http->buffer);
1687 else
1688 bytes = http->data_remaining;
1689
1690 #ifdef HAVE_SSL
1691 if (http->tls)
1692 bytes = http_read_ssl(http, http->buffer, bytes);
1693 else
1694 #endif /* HAVE_SSL */
1695 {
1696 DEBUG_printf(("2_httpPeek: reading %d bytes from socket into buffer...",
1697 (int)bytes));
1698
1699 bytes = recv(http->fd, http->buffer, bytes, 0);
1700
1701 DEBUG_printf(("2_httpPeek: read %d bytes from socket into buffer...",
1702 (int)bytes));
1703 }
1704
1705 if (bytes > 0)
1706 http->used = bytes;
1707 else if (bytes < 0)
1708 {
1709 #ifdef WIN32
1710 if (WSAGetLastError() != WSAEINTR && WSAGetLastError() != WSAEWOULDBLOCK)
1711 {
1712 http->error = WSAGetLastError();
1713 return (-1);
1714 }
1715 #else
1716 if (errno != EINTR && errno != EAGAIN)
1717 {
1718 http->error = errno;
1719 return (-1);
1720 }
1721 #endif /* WIN32 */
1722 }
1723 else
1724 {
1725 http->error = EPIPE;
1726 return (0);
1727 }
1728 }
1729
1730 if (http->used > 0)
1731 {
1732 if (length > (size_t)http->used)
1733 length = (size_t)http->used;
1734
1735 bytes = (ssize_t)length;
1736
1737 DEBUG_printf(("2_httpPeek: grabbing %d bytes from input buffer...",
1738 (int)bytes));
1739
1740 memcpy(buffer, http->buffer, length);
1741 }
1742 else
1743 bytes = 0;
1744
1745 if (bytes < 0)
1746 {
1747 #ifdef WIN32
1748 if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)
1749 bytes = 0;
1750 else
1751 http->error = WSAGetLastError();
1752 #else
1753 if (errno == EINTR || errno == EAGAIN)
1754 bytes = 0;
1755 else
1756 http->error = errno;
1757 #endif /* WIN32 */
1758 }
1759 else if (bytes == 0)
1760 {
1761 http->error = EPIPE;
1762 return (0);
1763 }
1764
1765 #ifdef DEBUG
1766 http_debug_hex("_httpPeek", buffer, (int)bytes);
1767 #endif /* DEBUG */
1768
1769 return (bytes);
1770 }
1771
1772
1773 /*
1774 * 'httpPost()' - Send a POST request to the server.
1775 */
1776
1777 int /* O - Status of call (0 = success) */
1778 httpPost(http_t *http, /* I - Connection to server */
1779 const char *uri) /* I - URI for post */
1780 {
1781 return (http_send(http, HTTP_POST, uri));
1782 }
1783
1784
1785 /*
1786 * 'httpPrintf()' - Print a formatted string to a HTTP connection.
1787 *
1788 * @private@
1789 */
1790
1791 int /* O - Number of bytes written */
1792 httpPrintf(http_t *http, /* I - Connection to server */
1793 const char *format, /* I - printf-style format string */
1794 ...) /* I - Additional args as needed */
1795 {
1796 int bytes; /* Number of bytes to write */
1797 char buf[16384]; /* Buffer for formatted string */
1798 va_list ap; /* Variable argument pointer */
1799
1800
1801 DEBUG_printf(("2httpPrintf(http=%p, format=\"%s\", ...)", http, format));
1802
1803 va_start(ap, format);
1804 bytes = vsnprintf(buf, sizeof(buf), format, ap);
1805 va_end(ap);
1806
1807 DEBUG_printf(("3httpPrintf: %s", buf));
1808
1809 if (http->data_encoding == HTTP_ENCODE_FIELDS)
1810 return (httpWrite2(http, buf, bytes));
1811 else
1812 {
1813 if (http->wused)
1814 {
1815 DEBUG_puts("4httpPrintf: flushing existing data...");
1816
1817 if (httpFlushWrite(http) < 0)
1818 return (-1);
1819 }
1820
1821 return (http_write(http, buf, bytes));
1822 }
1823 }
1824
1825
1826 /*
1827 * 'httpPut()' - Send a PUT request to the server.
1828 */
1829
1830 int /* O - Status of call (0 = success) */
1831 httpPut(http_t *http, /* I - Connection to server */
1832 const char *uri) /* I - URI to put */
1833 {
1834 DEBUG_printf(("httpPut(http=%p, uri=\"%s\")", http, uri));
1835 return (http_send(http, HTTP_PUT, uri));
1836 }
1837
1838
1839 /*
1840 * 'httpRead()' - Read data from a HTTP connection.
1841 *
1842 * This function is deprecated. Use the httpRead2() function which can
1843 * read more than 2GB of data.
1844 *
1845 * @deprecated@
1846 */
1847
1848 int /* O - Number of bytes read */
1849 httpRead(http_t *http, /* I - Connection to server */
1850 char *buffer, /* I - Buffer for data */
1851 int length) /* I - Maximum number of bytes */
1852 {
1853 return ((int)httpRead2(http, buffer, length));
1854 }
1855
1856
1857 /*
1858 * 'httpRead2()' - Read data from a HTTP connection.
1859 *
1860 * @since CUPS 1.2/Mac OS X 10.5@
1861 */
1862
1863 ssize_t /* O - Number of bytes read */
1864 httpRead2(http_t *http, /* I - Connection to server */
1865 char *buffer, /* I - Buffer for data */
1866 size_t length) /* I - Maximum number of bytes */
1867 {
1868 ssize_t bytes; /* Bytes read */
1869 char len[32]; /* Length string */
1870
1871
1872 DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT ")",
1873 http, buffer, CUPS_LLCAST length));
1874
1875 if (http == NULL || buffer == NULL)
1876 return (-1);
1877
1878 http->activity = time(NULL);
1879 http->error = 0;
1880
1881 if (length <= 0)
1882 return (0);
1883
1884 if (http->data_encoding == HTTP_ENCODE_CHUNKED &&
1885 http->data_remaining <= 0)
1886 {
1887 DEBUG_puts("2httpRead2: Getting chunk length...");
1888
1889 if (httpGets(len, sizeof(len), http) == NULL)
1890 {
1891 DEBUG_puts("1httpRead2: Could not get length!");
1892 return (0);
1893 }
1894
1895 http->data_remaining = strtoll(len, NULL, 16);
1896 if (http->data_remaining < 0)
1897 {
1898 DEBUG_puts("1httpRead2: Negative chunk length!");
1899 return (0);
1900 }
1901 }
1902
1903 DEBUG_printf(("2httpRead2: data_remaining=" CUPS_LLFMT,
1904 CUPS_LLCAST http->data_remaining));
1905
1906 if (http->data_remaining <= 0)
1907 {
1908 /*
1909 * A zero-length chunk ends a transfer; unless we are reading POST
1910 * data, go idle...
1911 */
1912
1913 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
1914 httpGets(len, sizeof(len), http);
1915
1916 if (http->state == HTTP_POST_RECV)
1917 http->state ++;
1918 else
1919 http->state = HTTP_WAITING;
1920
1921 /*
1922 * Prevent future reads for this request...
1923 */
1924
1925 http->data_encoding = HTTP_ENCODE_LENGTH;
1926
1927 return (0);
1928 }
1929 else if (length > (size_t)http->data_remaining)
1930 length = (size_t)http->data_remaining;
1931
1932 if (http->used == 0 && length <= 256)
1933 {
1934 /*
1935 * Buffer small reads for better performance...
1936 */
1937
1938 ssize_t buflen; /* Length of read for buffer */
1939
1940 if (!http->blocking)
1941 {
1942 while (!httpWait(http, http->wait_value))
1943 {
1944 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
1945 continue;
1946
1947 return (0);
1948 }
1949 }
1950
1951 if (http->data_remaining > sizeof(http->buffer))
1952 buflen = sizeof(http->buffer);
1953 else
1954 buflen = http->data_remaining;
1955
1956 DEBUG_printf(("2httpRead2: Reading %d bytes into buffer.", (int)buflen));
1957
1958 do
1959 {
1960 #ifdef HAVE_SSL
1961 if (http->tls)
1962 bytes = http_read_ssl(http, http->buffer, buflen);
1963 else
1964 #endif /* HAVE_SSL */
1965 bytes = recv(http->fd, http->buffer, buflen, 0);
1966
1967 if (bytes < 0)
1968 {
1969 #ifdef WIN32
1970 if (WSAGetLastError() != WSAEINTR)
1971 {
1972 http->error = WSAGetLastError();
1973 return (-1);
1974 }
1975 else if (WSAGetLastError() == WSAEWOULDBLOCK)
1976 {
1977 if (!http->timeout_cb ||
1978 !(*http->timeout_cb)(http, http->timeout_data))
1979 {
1980 http->error = WSAEWOULDBLOCK;
1981 return (-1);
1982 }
1983 }
1984 #else
1985 if (errno == EWOULDBLOCK || errno == EAGAIN)
1986 {
1987 if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data))
1988 {
1989 http->error = errno;
1990 return (-1);
1991 }
1992 else if (!http->timeout_cb && errno != EAGAIN)
1993 {
1994 http->error = errno;
1995 return (-1);
1996 }
1997 }
1998 else if (errno != EINTR)
1999 {
2000 http->error = errno;
2001 return (-1);
2002 }
2003 #endif /* WIN32 */
2004 }
2005 }
2006 while (bytes < 0);
2007
2008 DEBUG_printf(("2httpRead2: Read %d bytes into buffer.", (int)bytes));
2009
2010 http->used = bytes;
2011 }
2012
2013 if (http->used > 0)
2014 {
2015 if (length > (size_t)http->used)
2016 length = (size_t)http->used;
2017
2018 bytes = (ssize_t)length;
2019
2020 DEBUG_printf(("2httpRead2: grabbing %d bytes from input buffer...",
2021 (int)bytes));
2022
2023 memcpy(buffer, http->buffer, length);
2024 http->used -= (int)length;
2025
2026 if (http->used > 0)
2027 memmove(http->buffer, http->buffer + length, http->used);
2028 }
2029 #ifdef HAVE_SSL
2030 else if (http->tls)
2031 {
2032 if (!http->blocking)
2033 {
2034 while (!httpWait(http, http->wait_value))
2035 {
2036 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
2037 continue;
2038
2039 return (0);
2040 }
2041 }
2042
2043 while ((bytes = (ssize_t)http_read_ssl(http, buffer, (int)length)) < 0)
2044 {
2045 #ifdef WIN32
2046 if (WSAGetLastError() == WSAEWOULDBLOCK)
2047 {
2048 if (!http->timeout_cb || !(*http->timeout_cb)(http, http->timeout_data))
2049 break;
2050 }
2051 else if (WSAGetLastError() != WSAEINTR)
2052 break;
2053 #else
2054 if (errno == EWOULDBLOCK || errno == EAGAIN)
2055 {
2056 if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data))
2057 break;
2058 else if (!http->timeout_cb && errno != EAGAIN)
2059 break;
2060 }
2061 else if (errno != EINTR)
2062 break;
2063 #endif /* WIN32 */
2064 }
2065 }
2066 #endif /* HAVE_SSL */
2067 else
2068 {
2069 if (!http->blocking)
2070 {
2071 while (!httpWait(http, http->wait_value))
2072 {
2073 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
2074 continue;
2075
2076 return (0);
2077 }
2078 }
2079
2080 DEBUG_printf(("2httpRead2: reading " CUPS_LLFMT " bytes from socket...",
2081 CUPS_LLCAST length));
2082
2083 #ifdef WIN32
2084 while ((bytes = (ssize_t)recv(http->fd, buffer, (int)length, 0)) < 0)
2085 {
2086 if (WSAGetLastError() == WSAEWOULDBLOCK)
2087 {
2088 if (!http->timeout_cb || !(*http->timeout_cb)(http, http->timeout_data))
2089 break;
2090 }
2091 else if (WSAGetLastError() != WSAEINTR)
2092 break;
2093 }
2094 #else
2095 while ((bytes = recv(http->fd, buffer, length, 0)) < 0)
2096 {
2097 if (errno == EWOULDBLOCK || errno == EAGAIN)
2098 {
2099 if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data))
2100 break;
2101 else if (!http->timeout_cb && errno != EAGAIN)
2102 break;
2103 }
2104 else if (errno != EINTR)
2105 break;
2106 }
2107 #endif /* WIN32 */
2108
2109 DEBUG_printf(("2httpRead2: read " CUPS_LLFMT " bytes from socket...",
2110 CUPS_LLCAST bytes));
2111 }
2112
2113 if (bytes > 0)
2114 {
2115 http->data_remaining -= bytes;
2116
2117 if (http->data_remaining <= INT_MAX)
2118 http->_data_remaining = (int)http->data_remaining;
2119 else
2120 http->_data_remaining = INT_MAX;
2121 }
2122 else if (bytes < 0)
2123 {
2124 #ifdef WIN32
2125 if (WSAGetLastError() == WSAEINTR)
2126 bytes = 0;
2127 else
2128 http->error = WSAGetLastError();
2129 #else
2130 if (errno == EINTR || (errno == EAGAIN && !http->timeout_cb))
2131 bytes = 0;
2132 else
2133 http->error = errno;
2134 #endif /* WIN32 */
2135 }
2136 else
2137 {
2138 http->error = EPIPE;
2139 return (0);
2140 }
2141
2142 if (http->data_remaining == 0)
2143 {
2144 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
2145 httpGets(len, sizeof(len), http);
2146
2147 if (http->data_encoding != HTTP_ENCODE_CHUNKED)
2148 {
2149 if (http->state == HTTP_POST_RECV)
2150 http->state ++;
2151 else
2152 http->state = HTTP_WAITING;
2153 }
2154 }
2155
2156 #ifdef DEBUG
2157 http_debug_hex("httpRead2", buffer, (int)bytes);
2158 #endif /* DEBUG */
2159
2160 return (bytes);
2161 }
2162
2163
2164 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
2165 /*
2166 * '_httpReadCDSA()' - Read function for the CDSA library.
2167 */
2168
2169 OSStatus /* O - -1 on error, 0 on success */
2170 _httpReadCDSA(
2171 SSLConnectionRef connection, /* I - SSL/TLS connection */
2172 void *data, /* I - Data buffer */
2173 size_t *dataLength) /* IO - Number of bytes */
2174 {
2175 OSStatus result; /* Return value */
2176 ssize_t bytes; /* Number of bytes read */
2177 http_t *http; /* HTTP connection */
2178
2179
2180 http = (http_t *)connection;
2181
2182 if (!http->blocking)
2183 {
2184 /*
2185 * Make sure we have data before we read...
2186 */
2187
2188 while (!_httpWait(http, http->wait_value, 0))
2189 {
2190 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
2191 continue;
2192
2193 http->error = ETIMEDOUT;
2194 return (-1);
2195 }
2196 }
2197
2198 do
2199 {
2200 bytes = recv(http->fd, data, *dataLength, 0);
2201 }
2202 while (bytes == -1 && (errno == EINTR || errno == EAGAIN));
2203
2204 if (bytes == *dataLength)
2205 {
2206 result = 0;
2207 }
2208 else if (bytes > 0)
2209 {
2210 *dataLength = bytes;
2211 result = errSSLWouldBlock;
2212 }
2213 else
2214 {
2215 *dataLength = 0;
2216
2217 if (bytes == 0)
2218 result = errSSLClosedGraceful;
2219 else if (errno == EAGAIN)
2220 result = errSSLWouldBlock;
2221 else
2222 result = errSSLClosedAbort;
2223 }
2224
2225 return (result);
2226 }
2227 #endif /* HAVE_SSL && HAVE_CDSASSL */
2228
2229
2230 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
2231 /*
2232 * '_httpReadGNUTLS()' - Read function for the GNU TLS library.
2233 */
2234
2235 ssize_t /* O - Number of bytes read or -1 on error */
2236 _httpReadGNUTLS(
2237 gnutls_transport_ptr ptr, /* I - Connection to server */
2238 void *data, /* I - Buffer */
2239 size_t length) /* I - Number of bytes to read */
2240 {
2241 http_t *http; /* HTTP connection */
2242 ssize_t bytes; /* Bytes read */
2243
2244
2245 DEBUG_printf(("6_httpReadGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data, (int)length));
2246
2247 http = (http_t *)ptr;
2248
2249 if (!http->blocking)
2250 {
2251 /*
2252 * Make sure we have data before we read...
2253 */
2254
2255 while (!_httpWait(http, http->wait_value, 0))
2256 {
2257 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
2258 continue;
2259
2260 http->error = ETIMEDOUT;
2261 return (-1);
2262 }
2263 }
2264
2265 bytes = recv(http->fd, data, length, 0);
2266 DEBUG_printf(("6_httpReadGNUTLS: bytes=%d", (int)bytes));
2267 return (bytes);
2268 }
2269 #endif /* HAVE_SSL && HAVE_GNUTLS */
2270
2271
2272 /*
2273 * 'httpReconnect()' - Reconnect to a HTTP server.
2274 */
2275
2276 int /* O - 0 on success, non-zero on failure */
2277 httpReconnect(http_t *http) /* I - Connection to server */
2278 {
2279 http_addrlist_t *addr; /* Connected address */
2280 #ifdef DEBUG
2281 http_addrlist_t *current; /* Current address */
2282 char temp[256]; /* Temporary address string */
2283 #endif /* DEBUG */
2284
2285
2286 DEBUG_printf(("httpReconnect(http=%p)", http));
2287
2288 if (!http)
2289 return (-1);
2290
2291 #ifdef HAVE_SSL
2292 if (http->tls)
2293 {
2294 DEBUG_puts("2httpReconnect: Shutting down SSL/TLS...");
2295 http_shutdown_ssl(http);
2296 }
2297 #endif /* HAVE_SSL */
2298
2299 /*
2300 * Close any previously open socket...
2301 */
2302
2303 if (http->fd >= 0)
2304 {
2305 DEBUG_printf(("2httpReconnect: Closing socket %d...", http->fd));
2306
2307 #ifdef WIN32
2308 closesocket(http->fd);
2309 #else
2310 close(http->fd);
2311 #endif /* WIN32 */
2312
2313 http->fd = -1;
2314 }
2315
2316 /*
2317 * Connect to the server...
2318 */
2319
2320 #ifdef DEBUG
2321 for (current = http->addrlist; current; current = current->next)
2322 DEBUG_printf(("2httpReconnect: Address %s:%d",
2323 httpAddrString(&(current->addr), temp, sizeof(temp)),
2324 _httpAddrPort(&(current->addr))));
2325 #endif /* DEBUG */
2326
2327 if ((addr = httpAddrConnect(http->addrlist, &(http->fd))) == NULL)
2328 {
2329 /*
2330 * Unable to connect...
2331 */
2332
2333 #ifdef WIN32
2334 http->error = WSAGetLastError();
2335 #else
2336 http->error = errno;
2337 #endif /* WIN32 */
2338 http->status = HTTP_ERROR;
2339
2340 DEBUG_printf(("1httpReconnect: httpAddrConnect failed: %s",
2341 strerror(http->error)));
2342
2343 return (-1);
2344 }
2345
2346 DEBUG_printf(("2httpReconnect: New socket=%d", http->fd));
2347
2348 if (http->timeout_value > 0)
2349 http_set_timeout(http->fd, http->timeout_value);
2350
2351 http->hostaddr = &(addr->addr);
2352 http->error = 0;
2353 http->status = HTTP_CONTINUE;
2354 http->state = HTTP_WAITING;
2355
2356 #ifdef HAVE_SSL
2357 if (http->encryption == HTTP_ENCRYPT_ALWAYS)
2358 {
2359 /*
2360 * Always do encryption via SSL.
2361 */
2362
2363 if (http_setup_ssl(http) != 0)
2364 {
2365 # ifdef WIN32
2366 closesocket(http->fd);
2367 # else
2368 close(http->fd);
2369 # endif /* WIN32 */
2370
2371 return (-1);
2372 }
2373 }
2374 else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
2375 return (http_upgrade(http));
2376 #endif /* HAVE_SSL */
2377
2378 DEBUG_printf(("1httpReconnect: Connected to %s:%d...",
2379 httpAddrString(http->hostaddr, temp, sizeof(temp)),
2380 _httpAddrPort(http->hostaddr)));
2381
2382 return (0);
2383 }
2384
2385
2386 /*
2387 * 'httpSetAuthString()' - Set the current authorization string.
2388 *
2389 * This function just stores a copy of the current authorization string in
2390 * the HTTP connection object. You must still call httpSetField() to set
2391 * HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(),
2392 * httpHead(), httpOptions(), httpPost, or httpPut().
2393 *
2394 * @since CUPS 1.3/Mac OS X 10.5@
2395 */
2396
2397 void
2398 httpSetAuthString(http_t *http, /* I - Connection to server */
2399 const char *scheme, /* I - Auth scheme (NULL to clear it) */
2400 const char *data) /* I - Auth data (NULL for none) */
2401 {
2402 /*
2403 * Range check input...
2404 */
2405
2406 if (!http)
2407 return;
2408
2409 if (http->authstring && http->authstring != http->_authstring)
2410 free(http->authstring);
2411
2412 http->authstring = http->_authstring;
2413
2414 if (scheme)
2415 {
2416 /*
2417 * Set the current authorization string...
2418 */
2419
2420 int len = (int)strlen(scheme) + (data ? (int)strlen(data) + 1 : 0) + 1;
2421 char *temp;
2422
2423 if (len > (int)sizeof(http->_authstring))
2424 {
2425 if ((temp = malloc(len)) == NULL)
2426 len = sizeof(http->_authstring);
2427 else
2428 http->authstring = temp;
2429 }
2430
2431 if (data)
2432 snprintf(http->authstring, len, "%s %s", scheme, data);
2433 else
2434 strlcpy(http->authstring, scheme, len);
2435 }
2436 else
2437 {
2438 /*
2439 * Clear the current authorization string...
2440 */
2441
2442 http->_authstring[0] = '\0';
2443 }
2444 }
2445
2446
2447 /*
2448 * 'httpSetCredentials()' - Set the credentials associated with an encrypted
2449 * connection.
2450 *
2451 * @since CUPS 1.5/Mac OS X 10.7@
2452 */
2453
2454 int /* O - Status of call (0 = success) */
2455 httpSetCredentials(http_t *http, /* I - Connection to server */
2456 cups_array_t *credentials) /* I - Array of credentials */
2457 {
2458 if (!http || cupsArrayCount(credentials) < 1)
2459 return (-1);
2460
2461 _httpFreeCredentials(http->tls_credentials);
2462
2463 http->tls_credentials = _httpCreateCredentials(credentials);
2464
2465 return (http->tls_credentials ? 0 : -1);
2466 }
2467
2468
2469 /*
2470 * 'httpSetCookie()' - Set the cookie value(s).
2471 *
2472 * @since CUPS 1.1.19/Mac OS X 10.3@
2473 */
2474
2475 void
2476 httpSetCookie(http_t *http, /* I - Connection */
2477 const char *cookie) /* I - Cookie string */
2478 {
2479 if (!http)
2480 return;
2481
2482 if (http->cookie)
2483 free(http->cookie);
2484
2485 if (cookie)
2486 http->cookie = strdup(cookie);
2487 else
2488 http->cookie = NULL;
2489 }
2490
2491
2492 /*
2493 * 'httpSetExpect()' - Set the Expect: header in a request.
2494 *
2495 * Currently only HTTP_CONTINUE is supported for the "expect" argument.
2496 *
2497 * @since CUPS 1.2/Mac OS X 10.5@
2498 */
2499
2500 void
2501 httpSetExpect(http_t *http, /* I - Connection to server */
2502 http_status_t expect) /* I - HTTP status to expect (HTTP_CONTINUE) */
2503 {
2504 if (http)
2505 http->expect = expect;
2506 }
2507
2508
2509 /*
2510 * 'httpSetField()' - Set the value of an HTTP header.
2511 */
2512
2513 void
2514 httpSetField(http_t *http, /* I - Connection to server */
2515 http_field_t field, /* I - Field index */
2516 const char *value) /* I - Value */
2517 {
2518 if (http == NULL ||
2519 field < HTTP_FIELD_ACCEPT_LANGUAGE ||
2520 field > HTTP_FIELD_WWW_AUTHENTICATE ||
2521 value == NULL)
2522 return;
2523
2524 strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
2525
2526 if (field == HTTP_FIELD_AUTHORIZATION)
2527 {
2528 /*
2529 * Special case for Authorization: as its contents can be
2530 * longer than HTTP_MAX_VALUE
2531 */
2532
2533 if (http->field_authorization)
2534 free(http->field_authorization);
2535
2536 http->field_authorization = strdup(value);
2537 }
2538 else if (field == HTTP_FIELD_HOST)
2539 {
2540 /*
2541 * Special-case for Host: as we don't want a trailing "." on the hostname and
2542 * need to bracket IPv6 numeric addresses.
2543 */
2544
2545 char *ptr = strchr(value, ':');
2546
2547 if (value[0] != '[' && ptr && strchr(ptr + 1, ':'))
2548 {
2549 /*
2550 * Bracket IPv6 numeric addresses...
2551 *
2552 * This is slightly inefficient (basically copying twice), but is an edge
2553 * case and not worth optimizing...
2554 */
2555
2556 snprintf(http->fields[HTTP_FIELD_HOST],
2557 sizeof(http->fields[HTTP_FIELD_HOST]), "[%s]", value);
2558 }
2559 else
2560 {
2561 /*
2562 * Check for a trailing dot on the hostname...
2563 */
2564
2565 ptr = http->fields[HTTP_FIELD_HOST];
2566
2567 if (*ptr)
2568 {
2569 ptr += strlen(ptr) - 1;
2570
2571 if (*ptr == '.')
2572 *ptr = '\0';
2573 }
2574 }
2575 }
2576 }
2577
2578
2579 /*
2580 * 'httpSetLength()' - Set the content-length and content-encoding.
2581 *
2582 * @since CUPS 1.2/Mac OS X 10.5@
2583 */
2584
2585 void
2586 httpSetLength(http_t *http, /* I - Connection to server */
2587 size_t length) /* I - Length (0 for chunked) */
2588 {
2589 if (!http)
2590 return;
2591
2592 if (!length)
2593 {
2594 strcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked");
2595 http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0';
2596 }
2597 else
2598 {
2599 http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0';
2600 snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE,
2601 CUPS_LLFMT, CUPS_LLCAST length);
2602 }
2603 }
2604
2605
2606 /*
2607 * 'httpSetTimeout()' - Set read/write timeouts and an optional callback.
2608 *
2609 * The optional timeout callback receives both the HTTP connection and a user
2610 * data pointer and must return 1 to continue or 0 to error (time) out.
2611 *
2612 * @since CUPS 1.5/Mac OS X 10.7@
2613 */
2614
2615 void
2616 httpSetTimeout(
2617 http_t *http, /* I - Connection to server */
2618 double timeout, /* I - Number of seconds for timeout,
2619 must be greater than 0 */
2620 http_timeout_cb_t cb, /* I - Callback function or NULL */
2621 void *user_data) /* I - User data pointer */
2622 {
2623 if (!http || timeout <= 0.0)
2624 return;
2625
2626 http->timeout_cb = cb;
2627 http->timeout_data = user_data;
2628 http->timeout_value = timeout;
2629
2630 if (http->fd >= 0)
2631 http_set_timeout(http->fd, timeout);
2632
2633 http_set_wait(http);
2634 }
2635
2636
2637 /*
2638 * 'httpTrace()' - Send an TRACE request to the server.
2639 */
2640
2641 int /* O - Status of call (0 = success) */
2642 httpTrace(http_t *http, /* I - Connection to server */
2643 const char *uri) /* I - URI for trace */
2644 {
2645 return (http_send(http, HTTP_TRACE, uri));
2646 }
2647
2648
2649 /*
2650 * '_httpUpdate()' - Update the current HTTP status for incoming data.
2651 *
2652 * Note: Unlike httpUpdate(), this function does not flush pending write data
2653 * and only retrieves a single status line from the HTTP connection.
2654 */
2655
2656 int /* O - 1 to continue, 0 to stop */
2657 _httpUpdate(http_t *http, /* I - Connection to server */
2658 http_status_t *status) /* O - Current HTTP status */
2659 {
2660 char line[32768], /* Line from connection... */
2661 *value; /* Pointer to value on line */
2662 http_field_t field; /* Field index */
2663 int major, minor; /* HTTP version numbers */
2664
2665
2666 DEBUG_printf(("_httpUpdate(http=%p, status=%p), state=%s", http, status,
2667 http_states[http->state]));
2668
2669 /*
2670 * Grab a single line from the connection...
2671 */
2672
2673 if (!httpGets(line, sizeof(line), http))
2674 {
2675 *status = HTTP_ERROR;
2676 return (0);
2677 }
2678
2679 DEBUG_printf(("2_httpUpdate: Got \"%s\"", line));
2680
2681 if (line[0] == '\0')
2682 {
2683 /*
2684 * Blank line means the start of the data section (if any). Return
2685 * the result code, too...
2686 *
2687 * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
2688 * Instead, we just return HTTP_CONTINUE to the caller and keep on
2689 * tryin'...
2690 */
2691
2692 if (http->status == HTTP_CONTINUE)
2693 {
2694 *status = http->status;
2695 return (0);
2696 }
2697
2698 if (http->status < HTTP_BAD_REQUEST)
2699 http->digest_tries = 0;
2700
2701 #ifdef HAVE_SSL
2702 if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
2703 {
2704 if (http_setup_ssl(http) != 0)
2705 {
2706 # ifdef WIN32
2707 closesocket(http->fd);
2708 # else
2709 close(http->fd);
2710 # endif /* WIN32 */
2711
2712 *status = http->status = HTTP_ERROR;
2713 return (0);
2714 }
2715
2716 *status = HTTP_CONTINUE;
2717 return (0);
2718 }
2719 #endif /* HAVE_SSL */
2720
2721 httpGetLength2(http);
2722
2723 switch (http->state)
2724 {
2725 case HTTP_GET :
2726 case HTTP_POST :
2727 case HTTP_POST_RECV :
2728 case HTTP_PUT :
2729 http->state ++;
2730 case HTTP_POST_SEND :
2731 case HTTP_HEAD :
2732 break;
2733
2734 default :
2735 http->state = HTTP_WAITING;
2736 break;
2737 }
2738
2739 *status = http->status;
2740 return (0);
2741 }
2742 else if (!strncmp(line, "HTTP/", 5))
2743 {
2744 /*
2745 * Got the beginning of a response...
2746 */
2747
2748 int intstatus; /* Status value as an integer */
2749
2750 if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &intstatus) != 3)
2751 {
2752 *status = http->status = HTTP_ERROR;
2753 return (0);
2754 }
2755
2756 http->version = (http_version_t)(major * 100 + minor);
2757 *status = http->status = (http_status_t)intstatus;
2758 }
2759 else if ((value = strchr(line, ':')) != NULL)
2760 {
2761 /*
2762 * Got a value...
2763 */
2764
2765 *value++ = '\0';
2766 while (_cups_isspace(*value))
2767 value ++;
2768
2769 /*
2770 * Be tolerants of servers that send unknown attribute fields...
2771 */
2772
2773 if (!_cups_strcasecmp(line, "expect"))
2774 {
2775 /*
2776 * "Expect: 100-continue" or similar...
2777 */
2778
2779 http->expect = (http_status_t)atoi(value);
2780 }
2781 else if (!_cups_strcasecmp(line, "cookie"))
2782 {
2783 /*
2784 * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
2785 */
2786
2787 httpSetCookie(http, value);
2788 }
2789 else if ((field = http_field(line)) != HTTP_FIELD_UNKNOWN)
2790 httpSetField(http, field, value);
2791 #ifdef DEBUG
2792 else
2793 DEBUG_printf(("1_httpUpdate: unknown field %s seen!", line));
2794 #endif /* DEBUG */
2795 }
2796 else
2797 {
2798 DEBUG_printf(("1_httpUpdate: Bad response line \"%s\"!", line));
2799 *status = http->status = HTTP_ERROR;
2800 return (0);
2801 }
2802
2803 return (1);
2804 }
2805
2806
2807 /*
2808 * 'httpUpdate()' - Update the current HTTP state for incoming data.
2809 */
2810
2811 http_status_t /* O - HTTP status */
2812 httpUpdate(http_t *http) /* I - Connection to server */
2813 {
2814 http_status_t status; /* Request status */
2815
2816
2817 DEBUG_printf(("httpUpdate(http=%p), state=%s", http,
2818 http_states[http->state]));
2819
2820 /*
2821 * Flush pending data, if any...
2822 */
2823
2824 if (http->wused)
2825 {
2826 DEBUG_puts("2httpUpdate: flushing buffer...");
2827
2828 if (httpFlushWrite(http) < 0)
2829 return (HTTP_ERROR);
2830 }
2831
2832 /*
2833 * If we haven't issued any commands, then there is nothing to "update"...
2834 */
2835
2836 if (http->state == HTTP_WAITING)
2837 return (HTTP_CONTINUE);
2838
2839 /*
2840 * Grab all of the lines we can from the connection...
2841 */
2842
2843 while (_httpUpdate(http, &status));
2844
2845 /*
2846 * See if there was an error...
2847 */
2848
2849 if (http->error == EPIPE && http->status > HTTP_CONTINUE)
2850 {
2851 DEBUG_printf(("1httpUpdate: Returning status %d...", http->status));
2852 return (http->status);
2853 }
2854
2855 if (http->error)
2856 {
2857 DEBUG_printf(("1httpUpdate: socket error %d - %s", http->error,
2858 strerror(http->error)));
2859 http->status = HTTP_ERROR;
2860 return (HTTP_ERROR);
2861 }
2862
2863 /*
2864 * Return the current status...
2865 */
2866
2867 return (status);
2868 }
2869
2870
2871 /*
2872 * '_httpWait()' - Wait for data available on a connection (no flush).
2873 */
2874
2875 int /* O - 1 if data is available, 0 otherwise */
2876 _httpWait(http_t *http, /* I - Connection to server */
2877 int msec, /* I - Milliseconds to wait */
2878 int usessl) /* I - Use SSL context? */
2879 {
2880 #ifdef HAVE_POLL
2881 struct pollfd pfd; /* Polled file descriptor */
2882 #else
2883 fd_set input_set; /* select() input set */
2884 struct timeval timeout; /* Timeout */
2885 #endif /* HAVE_POLL */
2886 int nfds; /* Result from select()/poll() */
2887
2888
2889 DEBUG_printf(("4_httpWait(http=%p, msec=%d, usessl=%d)", http, msec, usessl));
2890
2891 if (http->fd < 0)
2892 {
2893 DEBUG_printf(("5_httpWait: Returning 0 since fd=%d", http->fd));
2894 return (0);
2895 }
2896
2897 /*
2898 * Check the SSL/TLS buffers for data first...
2899 */
2900
2901 #ifdef HAVE_SSL
2902 if (http->tls && usessl)
2903 {
2904 # ifdef HAVE_LIBSSL
2905 if (SSL_pending(http->tls))
2906 {
2907 DEBUG_puts("5_httpWait: Return 1 since there is pending SSL data.");
2908 return (1);
2909 }
2910
2911 # elif defined(HAVE_GNUTLS)
2912 if (gnutls_record_check_pending(http->tls))
2913 {
2914 DEBUG_puts("5_httpWait: Return 1 since there is pending SSL data.");
2915 return (1);
2916 }
2917
2918 # elif defined(HAVE_CDSASSL)
2919 size_t bytes; /* Bytes that are available */
2920
2921 if (!SSLGetBufferedReadSize(http->tls, &bytes) &&
2922 bytes > 0)
2923 {
2924 DEBUG_puts("5_httpWait: Return 1 since there is pending SSL data.");
2925 return (1);
2926 }
2927 # endif /* HAVE_LIBSSL */
2928 }
2929 #endif /* HAVE_SSL */
2930
2931 /*
2932 * Then try doing a select() or poll() to poll the socket...
2933 */
2934
2935 #ifdef HAVE_POLL
2936 pfd.fd = http->fd;
2937 pfd.events = POLLIN;
2938
2939 while ((nfds = poll(&pfd, 1, msec)) < 0 &&
2940 (errno == EINTR || errno == EAGAIN));
2941
2942 #else
2943 do
2944 {
2945 FD_ZERO(&input_set);
2946 FD_SET(http->fd, &input_set);
2947
2948 DEBUG_printf(("6_httpWait: msec=%d, http->fd=%d", msec, http->fd));
2949
2950 if (msec >= 0)
2951 {
2952 timeout.tv_sec = msec / 1000;
2953 timeout.tv_usec = (msec % 1000) * 1000;
2954
2955 nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout);
2956 }
2957 else
2958 nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL);
2959
2960 DEBUG_printf(("6_httpWait: select() returned %d...", nfds));
2961 }
2962 # ifdef WIN32
2963 while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
2964 WSAGetLastError() == WSAEWOULDBLOCK));
2965 # else
2966 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
2967 # endif /* WIN32 */
2968 #endif /* HAVE_POLL */
2969
2970 DEBUG_printf(("5_httpWait: returning with nfds=%d, errno=%d...", nfds,
2971 errno));
2972
2973 return (nfds > 0);
2974 }
2975
2976
2977 /*
2978 * 'httpWait()' - Wait for data available on a connection.
2979 *
2980 * @since CUPS 1.1.19/Mac OS X 10.3@
2981 */
2982
2983 int /* O - 1 if data is available, 0 otherwise */
2984 httpWait(http_t *http, /* I - Connection to server */
2985 int msec) /* I - Milliseconds to wait */
2986 {
2987 /*
2988 * First see if there is data in the buffer...
2989 */
2990
2991 DEBUG_printf(("2httpWait(http=%p, msec=%d)", http, msec));
2992
2993 if (http == NULL)
2994 return (0);
2995
2996 if (http->used)
2997 {
2998 DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready.");
2999 return (1);
3000 }
3001
3002 /*
3003 * Flush pending data, if any...
3004 */
3005
3006 if (http->wused)
3007 {
3008 DEBUG_puts("3httpWait: Flushing write buffer.");
3009
3010 if (httpFlushWrite(http) < 0)
3011 return (0);
3012 }
3013
3014 /*
3015 * If not, check the SSL/TLS buffers and do a select() on the connection...
3016 */
3017
3018 return (_httpWait(http, msec, 1));
3019 }
3020
3021
3022 /*
3023 * 'httpWrite()' - Write data to a HTTP connection.
3024 *
3025 * This function is deprecated. Use the httpWrite2() function which can
3026 * write more than 2GB of data.
3027 *
3028 * @deprecated@
3029 */
3030
3031 int /* O - Number of bytes written */
3032 httpWrite(http_t *http, /* I - Connection to server */
3033 const char *buffer, /* I - Buffer for data */
3034 int length) /* I - Number of bytes to write */
3035 {
3036 return ((int)httpWrite2(http, buffer, length));
3037 }
3038
3039
3040 /*
3041 * 'httpWrite2()' - Write data to a HTTP connection.
3042 *
3043 * @since CUPS 1.2/Mac OS X 10.5@
3044 */
3045
3046 ssize_t /* O - Number of bytes written */
3047 httpWrite2(http_t *http, /* I - Connection to server */
3048 const char *buffer, /* I - Buffer for data */
3049 size_t length) /* I - Number of bytes to write */
3050 {
3051 ssize_t bytes; /* Bytes written */
3052
3053
3054 DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http,
3055 buffer, CUPS_LLCAST length));
3056
3057 /*
3058 * Range check input...
3059 */
3060
3061 if (http == NULL || buffer == NULL)
3062 return (-1);
3063
3064 /*
3065 * Mark activity on the connection...
3066 */
3067
3068 http->activity = time(NULL);
3069
3070 /*
3071 * Buffer small writes for better performance...
3072 */
3073
3074 if (length > 0)
3075 {
3076 if (http->wused && (length + http->wused) > sizeof(http->wbuffer))
3077 {
3078 DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length="
3079 CUPS_LLFMT ")", http->wused, CUPS_LLCAST length));
3080
3081 httpFlushWrite(http);
3082 }
3083
3084 if ((length + http->wused) <= sizeof(http->wbuffer) &&
3085 length < sizeof(http->wbuffer))
3086 {
3087 /*
3088 * Write to buffer...
3089 */
3090
3091 DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...",
3092 CUPS_LLCAST length));
3093
3094 memcpy(http->wbuffer + http->wused, buffer, length);
3095 http->wused += (int)length;
3096 bytes = (ssize_t)length;
3097 }
3098 else
3099 {
3100 /*
3101 * Otherwise write the data directly...
3102 */
3103
3104 DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...",
3105 CUPS_LLCAST length));
3106
3107 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
3108 bytes = (ssize_t)http_write_chunk(http, buffer, (int)length);
3109 else
3110 bytes = (ssize_t)http_write(http, buffer, (int)length);
3111
3112 DEBUG_printf(("2httpWrite2: Wrote " CUPS_LLFMT " bytes...",
3113 CUPS_LLCAST bytes));
3114 }
3115
3116 if (http->data_encoding == HTTP_ENCODE_LENGTH)
3117 http->data_remaining -= bytes;
3118 }
3119 else
3120 bytes = 0;
3121
3122 /*
3123 * Handle end-of-request processing...
3124 */
3125
3126 if ((http->data_encoding == HTTP_ENCODE_CHUNKED && length == 0) ||
3127 (http->data_encoding == HTTP_ENCODE_LENGTH && http->data_remaining == 0))
3128 {
3129 /*
3130 * Finished with the transfer; unless we are sending POST or PUT
3131 * data, go idle...
3132 */
3133
3134 DEBUG_puts("2httpWrite: changing states...");
3135
3136 if (http->wused)
3137 httpFlushWrite(http);
3138
3139 if (http->data_encoding == HTTP_ENCODE_CHUNKED)
3140 {
3141 /*
3142 * Send a 0-length chunk at the end of the request...
3143 */
3144
3145 http_write(http, "0\r\n\r\n", 5);
3146
3147 /*
3148 * Reset the data state...
3149 */
3150
3151 http->data_encoding = HTTP_ENCODE_LENGTH;
3152 http->data_remaining = 0;
3153 }
3154 }
3155
3156 return (bytes);
3157 }
3158
3159
3160 #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
3161 /*
3162 * '_httpWriteCDSA()' - Write function for the CDSA library.
3163 */
3164
3165 OSStatus /* O - -1 on error, 0 on success */
3166 _httpWriteCDSA(
3167 SSLConnectionRef connection, /* I - SSL/TLS connection */
3168 const void *data, /* I - Data buffer */
3169 size_t *dataLength) /* IO - Number of bytes */
3170 {
3171 OSStatus result; /* Return value */
3172 ssize_t bytes; /* Number of bytes read */
3173 http_t *http; /* HTTP connection */
3174
3175
3176 http = (http_t *)connection;
3177
3178 do
3179 {
3180 bytes = write(http->fd, data, *dataLength);
3181 }
3182 while (bytes == -1 && (errno == EINTR || errno == EAGAIN));
3183
3184 if (bytes == *dataLength)
3185 {
3186 result = 0;
3187 }
3188 else if (bytes >= 0)
3189 {
3190 *dataLength = bytes;
3191 result = errSSLWouldBlock;
3192 }
3193 else
3194 {
3195 *dataLength = 0;
3196
3197 if (errno == EAGAIN)
3198 result = errSSLWouldBlock;
3199 else
3200 result = errSSLClosedAbort;
3201 }
3202
3203 return (result);
3204 }
3205 #endif /* HAVE_SSL && HAVE_CDSASSL */
3206
3207
3208 #if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
3209 /*
3210 * '_httpWriteGNUTLS()' - Write function for the GNU TLS library.
3211 */
3212
3213 ssize_t /* O - Number of bytes written or -1 on error */
3214 _httpWriteGNUTLS(
3215 gnutls_transport_ptr ptr, /* I - Connection to server */
3216 const void *data, /* I - Data buffer */
3217 size_t length) /* I - Number of bytes to write */
3218 {
3219 ssize_t bytes; /* Bytes written */
3220
3221
3222 DEBUG_printf(("6_httpWriteGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data,
3223 (int)length));
3224 #ifdef DEBUG
3225 http_debug_hex("_httpWriteGNUTLS", data, (int)length);
3226 #endif /* DEBUG */
3227
3228 bytes = send(((http_t *)ptr)->fd, data, length, 0);
3229 DEBUG_printf(("_httpWriteGNUTLS: bytes=%d", (int)bytes));
3230
3231 return (bytes);
3232 }
3233 #endif /* HAVE_SSL && HAVE_GNUTLS */
3234
3235
3236 #if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
3237 /*
3238 * 'http_bio_ctrl()' - Control the HTTP connection.
3239 */
3240
3241 static long /* O - Result/data */
3242 http_bio_ctrl(BIO *h, /* I - BIO data */
3243 int cmd, /* I - Control command */
3244 long arg1, /* I - First argument */
3245 void *arg2) /* I - Second argument */
3246 {
3247 switch (cmd)
3248 {
3249 default :
3250 return (0);
3251
3252 case BIO_CTRL_RESET :
3253 h->ptr = NULL;
3254 return (0);
3255
3256 case BIO_C_SET_FILE_PTR :
3257 h->ptr = arg2;
3258 h->init = 1;
3259 return (1);
3260
3261 case BIO_C_GET_FILE_PTR :
3262 if (arg2)
3263 {
3264 *((void **)arg2) = h->ptr;
3265 return (1);
3266 }
3267 else
3268 return (0);
3269
3270 case BIO_CTRL_DUP :
3271 case BIO_CTRL_FLUSH :
3272 return (1);
3273 }
3274 }
3275
3276
3277 /*
3278 * 'http_bio_free()' - Free OpenSSL data.
3279 */
3280
3281 static int /* O - 1 on success, 0 on failure */
3282 http_bio_free(BIO *h) /* I - BIO data */
3283 {
3284 if (!h)
3285 return (0);
3286
3287 if (h->shutdown)
3288 {
3289 h->init = 0;
3290 h->flags = 0;
3291 }
3292
3293 return (1);
3294 }
3295
3296
3297 /*
3298 * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
3299 */
3300
3301 static int /* O - 1 on success, 0 on failure */
3302 http_bio_new(BIO *h) /* I - BIO data */
3303 {
3304 if (!h)
3305 return (0);
3306
3307 h->init = 0;
3308 h->num = 0;
3309 h->ptr = NULL;
3310 h->flags = 0;
3311
3312 return (1);
3313 }
3314
3315
3316 /*
3317 * 'http_bio_puts()' - Send a string for OpenSSL.
3318 */
3319
3320 static int /* O - Bytes written */
3321 http_bio_puts(BIO *h, /* I - BIO data */
3322 const char *str) /* I - String to write */
3323 {
3324 #ifdef WIN32
3325 return (send(((http_t *)h->ptr)->fd, str, (int)strlen(str), 0));
3326 #else
3327 return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0));
3328 #endif /* WIN32 */
3329 }
3330
3331
3332 /*
3333 * 'http_bio_read()' - Read data for OpenSSL.
3334 */
3335
3336 static int /* O - Bytes read */
3337 http_bio_read(BIO *h, /* I - BIO data */
3338 char *buf, /* I - Buffer */
3339 int size) /* I - Number of bytes to read */
3340 {
3341 http_t *http; /* HTTP connection */
3342
3343
3344 http = (http_t *)h->ptr;
3345
3346 if (!http->blocking)
3347 {
3348 /*
3349 * Make sure we have data before we read...
3350 */
3351
3352 while (!_httpWait(http, http->wait_value, 0))
3353 {
3354 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
3355 continue;
3356
3357 #ifdef WIN32
3358 http->error = WSAETIMEDOUT;
3359 #else
3360 http->error = ETIMEDOUT;
3361 #endif /* WIN32 */
3362
3363 return (-1);
3364 }
3365 }
3366
3367 return (recv(http->fd, buf, size, 0));
3368 }
3369
3370
3371 /*
3372 * 'http_bio_write()' - Write data for OpenSSL.
3373 */
3374
3375 static int /* O - Bytes written */
3376 http_bio_write(BIO *h, /* I - BIO data */
3377 const char *buf, /* I - Buffer to write */
3378 int num) /* I - Number of bytes to write */
3379 {
3380 return (send(((http_t *)h->ptr)->fd, buf, num, 0));
3381 }
3382 #endif /* HAVE_SSL && HAVE_LIBSSL */
3383
3384
3385 #ifdef DEBUG
3386 /*
3387 * 'http_debug_hex()' - Do a hex dump of a buffer.
3388 */
3389
3390 static void
3391 http_debug_hex(const char *prefix, /* I - Prefix for line */
3392 const char *buffer, /* I - Buffer to dump */
3393 int bytes) /* I - Bytes to dump */
3394 {
3395 int i, j, /* Looping vars */
3396 ch; /* Current character */
3397 char line[255], /* Line buffer */
3398 *start, /* Start of line after prefix */
3399 *ptr; /* Pointer into line */
3400
3401
3402 if (_cups_debug_fd < 0 || _cups_debug_level < 6)
3403 return;
3404
3405 DEBUG_printf(("6%s: %d bytes:", prefix, bytes));
3406
3407 snprintf(line, sizeof(line), "6%s: ", prefix);
3408 start = line + strlen(line);
3409
3410 for (i = 0; i < bytes; i += 16)
3411 {
3412 for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2)
3413 sprintf(ptr, "%02X", buffer[i + j] & 255);
3414
3415 while (j < 16)
3416 {
3417 strcpy(ptr, " ");
3418 ptr += 2;
3419 j ++;
3420 }
3421
3422 strcpy(ptr, " ");
3423 ptr += 2;
3424
3425 for (j = 0; j < 16 && (i + j) < bytes; j ++)
3426 {
3427 ch = buffer[i + j] & 255;
3428
3429 if (ch < ' ' || ch >= 127)
3430 ch = '.';
3431
3432 *ptr++ = ch;
3433 }
3434
3435 *ptr = '\0';
3436 DEBUG_puts(line);
3437 }
3438 }
3439 #endif /* DEBUG */
3440
3441
3442 /*
3443 * 'http_field()' - Return the field index for a field name.
3444 */
3445
3446 static http_field_t /* O - Field index */
3447 http_field(const char *name) /* I - String name */
3448 {
3449 int i; /* Looping var */
3450
3451
3452 for (i = 0; i < HTTP_FIELD_MAX; i ++)
3453 if (_cups_strcasecmp(name, http_fields[i]) == 0)
3454 return ((http_field_t)i);
3455
3456 return (HTTP_FIELD_UNKNOWN);
3457 }
3458
3459
3460 #ifdef HAVE_SSL
3461 /*
3462 * 'http_read_ssl()' - Read from a SSL/TLS connection.
3463 */
3464
3465 static int /* O - Bytes read */
3466 http_read_ssl(http_t *http, /* I - Connection to server */
3467 char *buf, /* I - Buffer to store data */
3468 int len) /* I - Length of buffer */
3469 {
3470 # if defined(HAVE_LIBSSL)
3471 return (SSL_read((SSL *)(http->tls), buf, len));
3472
3473 # elif defined(HAVE_GNUTLS)
3474 ssize_t result; /* Return value */
3475
3476
3477 result = gnutls_record_recv(http->tls, buf, len);
3478
3479 if (result < 0 && !errno)
3480 {
3481 /*
3482 * Convert GNU TLS error to errno value...
3483 */
3484
3485 switch (result)
3486 {
3487 case GNUTLS_E_INTERRUPTED :
3488 errno = EINTR;
3489 break;
3490
3491 case GNUTLS_E_AGAIN :
3492 errno = EAGAIN;
3493 break;
3494
3495 default :
3496 errno = EPIPE;
3497 break;
3498 }
3499
3500 result = -1;
3501 }
3502
3503 return ((int)result);
3504
3505 # elif defined(HAVE_CDSASSL)
3506 int result; /* Return value */
3507 OSStatus error; /* Error info */
3508 size_t processed; /* Number of bytes processed */
3509
3510
3511 error = SSLRead(http->tls, buf, len, &processed);
3512 DEBUG_printf(("6http_read_ssl: error=%d, processed=%d", (int)error,
3513 (int)processed));
3514 switch (error)
3515 {
3516 case 0 :
3517 result = (int)processed;
3518 break;
3519
3520 case errSSLWouldBlock :
3521 if (processed)
3522 result = (int)processed;
3523 else
3524 {
3525 result = -1;
3526 errno = EINTR;
3527 }
3528 break;
3529
3530 case errSSLClosedGraceful :
3531 default :
3532 if (processed)
3533 result = (int)processed;
3534 else
3535 {
3536 result = -1;
3537 errno = EPIPE;
3538 }
3539 break;
3540 }
3541
3542 return (result);
3543
3544 # elif defined(HAVE_SSPISSL)
3545 return _sspiRead((_sspi_struct_t*) http->tls, buf, len);
3546 # endif /* HAVE_LIBSSL */
3547 }
3548 #endif /* HAVE_SSL */
3549
3550
3551 /*
3552 * 'http_send()' - Send a request with all fields and the trailing blank line.
3553 */
3554
3555 static int /* O - 0 on success, non-zero on error */
3556 http_send(http_t *http, /* I - Connection to server */
3557 http_state_t request, /* I - Request code */
3558 const char *uri) /* I - URI */
3559 {
3560 int i; /* Looping var */
3561 char buf[1024]; /* Encoded URI buffer */
3562 static const char * const codes[] =
3563 { /* Request code strings */
3564 NULL,
3565 "OPTIONS",
3566 "GET",
3567 NULL,
3568 "HEAD",
3569 "POST",
3570 NULL,
3571 NULL,
3572 "PUT",
3573 NULL,
3574 "DELETE",
3575 "TRACE",
3576 "CLOSE"
3577 };
3578
3579
3580 DEBUG_printf(("7http_send(http=%p, request=HTTP_%s, uri=\"%s\")",
3581 http, codes[request], uri));
3582
3583 if (http == NULL || uri == NULL)
3584 return (-1);
3585
3586 /*
3587 * Set the User-Agent field if it isn't already...
3588 */
3589
3590 if (!http->fields[HTTP_FIELD_USER_AGENT][0])
3591 httpSetField(http, HTTP_FIELD_USER_AGENT, CUPS_MINIMAL);
3592
3593 /*
3594 * Encode the URI as needed...
3595 */
3596
3597 _httpEncodeURI(buf, uri, sizeof(buf));
3598
3599 /*
3600 * See if we had an error the last time around; if so, reconnect...
3601 */
3602
3603 if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
3604 if (httpReconnect(http))
3605 return (-1);
3606
3607 /*
3608 * Flush any written data that is pending...
3609 */
3610
3611 if (http->wused)
3612 {
3613 if (httpFlushWrite(http) < 0)
3614 if (httpReconnect(http))
3615 return (-1);
3616 }
3617
3618 /*
3619 * Send the request header...
3620 */
3621
3622 http->state = request;
3623 http->data_encoding = HTTP_ENCODE_FIELDS;
3624
3625 if (request == HTTP_POST || request == HTTP_PUT)
3626 http->state ++;
3627
3628 http->status = HTTP_CONTINUE;
3629
3630 #ifdef HAVE_SSL
3631 if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
3632 {
3633 httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
3634 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
3635 }
3636 #endif /* HAVE_SSL */
3637
3638 if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
3639 {
3640 http->status = HTTP_ERROR;
3641 return (-1);
3642 }
3643
3644 for (i = 0; i < HTTP_FIELD_MAX; i ++)
3645 if (http->fields[i][0] != '\0')
3646 {
3647 DEBUG_printf(("9http_send: %s: %s", http_fields[i],
3648 httpGetField(http, i)));
3649
3650 if (httpPrintf(http, "%s: %s\r\n", http_fields[i],
3651 httpGetField(http, i)) < 1)
3652 {
3653 http->status = HTTP_ERROR;
3654 return (-1);
3655 }
3656 }
3657
3658 if (http->cookie)
3659 if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1)
3660 {
3661 http->status = HTTP_ERROR;
3662 return (-1);
3663 }
3664
3665 if (http->expect == HTTP_CONTINUE &&
3666 (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV))
3667 if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
3668 {
3669 http->status = HTTP_ERROR;
3670 return (-1);
3671 }
3672
3673 if (httpPrintf(http, "\r\n") < 1)
3674 {
3675 http->status = HTTP_ERROR;
3676 return (-1);
3677 }
3678
3679 if (httpFlushWrite(http) < 0)
3680 return (-1);
3681
3682 httpGetLength2(http);
3683 httpClearFields(http);
3684
3685 /*
3686 * The Kerberos and AuthRef authentication strings can only be used once...
3687 */
3688
3689 if (http->field_authorization && http->authstring &&
3690 (!strncmp(http->authstring, "Negotiate", 9) ||
3691 !strncmp(http->authstring, "AuthRef", 7)))
3692 {
3693 http->_authstring[0] = '\0';
3694
3695 if (http->authstring != http->_authstring)
3696 free(http->authstring);
3697
3698 http->authstring = http->_authstring;
3699 }
3700
3701 return (0);
3702 }
3703
3704
3705 #ifdef HAVE_SSL
3706 # if defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
3707 /*
3708 * 'http_set_credentials()' - Set the SSL/TLS credentials.
3709 */
3710
3711 static int /* O - Status of connection */
3712 http_set_credentials(http_t *http) /* I - Connection to server */
3713 {
3714 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
3715 OSStatus error = 0; /* Error code */
3716 http_tls_credentials_t credentials = NULL;
3717 /* TLS credentials */
3718
3719
3720 DEBUG_printf(("7http_set_credentials(%p)", http));
3721
3722 /*
3723 * Prefer connection specific credentials...
3724 */
3725
3726 if ((credentials = http->tls_credentials) == NULL)
3727 credentials = cg->tls_credentials;
3728
3729 # if HAVE_SECPOLICYCREATESSL
3730 /*
3731 * Otherwise root around in the user's keychain to see if one can be found...
3732 */
3733
3734 if (!credentials)
3735 {
3736 CFDictionaryRef query; /* Query dictionary */
3737 CFTypeRef matches = NULL; /* Matching credentials */
3738 CFArrayRef dn_array = NULL;/* Distinguished names array */
3739 CFTypeRef keys[] = { kSecClass,
3740 kSecMatchLimit,
3741 kSecReturnRef };
3742 /* Keys for dictionary */
3743 CFTypeRef values[] = { kSecClassCertificate,
3744 kSecMatchLimitOne,
3745 kCFBooleanTrue };
3746 /* Values for dictionary */
3747
3748 /*
3749 * Get the names associated with the server.
3750 */
3751
3752 if ((error = SSLCopyDistinguishedNames(http->tls, &dn_array)) != noErr)
3753 {
3754 DEBUG_printf(("4http_set_credentials: SSLCopyDistinguishedNames, error=%d",
3755 (int)error));
3756 return (error);
3757 }
3758
3759 /*
3760 * Create a query which will return all identities that can sign and match
3761 * the passed in policy.
3762 */
3763
3764 query = CFDictionaryCreate(NULL,
3765 (const void**)(&keys[0]),
3766 (const void**)(&values[0]),
3767 sizeof(keys) / sizeof(keys[0]),
3768 &kCFTypeDictionaryKeyCallBacks,
3769 &kCFTypeDictionaryValueCallBacks);
3770 if (query)
3771 {
3772 error = SecItemCopyMatching(query, &matches);
3773 DEBUG_printf(("4http_set_credentials: SecItemCopyMatching, error=%d",
3774 (int)error));
3775 CFRelease(query);
3776 }
3777
3778 if (matches)
3779 CFRelease(matches);
3780
3781 if (dn_array)
3782 CFRelease(dn_array);
3783 }
3784 # endif /* HAVE_SECPOLICYCREATESSL */
3785
3786 if (credentials)
3787 {
3788 error = SSLSetCertificate(http->tls, credentials);
3789 DEBUG_printf(("4http_set_credentials: SSLSetCertificate, error=%d",
3790 (int)error));
3791 }
3792 else
3793 DEBUG_puts("4http_set_credentials: No credentials to set.");
3794
3795 return (error);
3796 }
3797 # endif /* HAVE_CDSASSL && HAVE_SECCERTIFICATECOPYDATA */
3798 #endif /* HAVE_SSL */
3799
3800
3801 /*
3802 * 'http_set_timeout()' - Set the socket timeout values.
3803 */
3804
3805 static void
3806 http_set_timeout(int fd, /* I - File descriptor */
3807 double timeout) /* I - Timeout in seconds */
3808 {
3809 #ifdef WIN32
3810 DWORD tv = (DWORD)(timeout * 1000);
3811 /* Timeout in milliseconds */
3812
3813 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
3814 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));
3815
3816 #else
3817 struct timeval tv; /* Timeout in secs and usecs */
3818
3819 tv.tv_sec = (int)timeout;
3820 tv.tv_usec = (int)(1000000 * fmod(timeout, 1.0));
3821
3822 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
3823 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
3824 #endif /* WIN32 */
3825 }
3826
3827
3828 /*
3829 * 'http_set_wait()' - Set the default wait value for reads.
3830 */
3831
3832 static void
3833 http_set_wait(http_t *http) /* I - Connection to server */
3834 {
3835 if (http->blocking)
3836 {
3837 http->wait_value = (int)(http->timeout_value * 1000);
3838
3839 if (http->wait_value <= 0)
3840 http->wait_value = 60000;
3841 }
3842 else
3843 http->wait_value = 10000;
3844 }
3845
3846
3847 #ifdef HAVE_SSL
3848 /*
3849 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
3850 */
3851
3852 static int /* O - 0 on success, -1 on failure */
3853 http_setup_ssl(http_t *http) /* I - Connection to server */
3854 {
3855 _cups_globals_t *cg = _cupsGlobals();
3856 /* Pointer to library globals */
3857 int any_root; /* Allow any root */
3858
3859 # ifdef HAVE_LIBSSL
3860 SSL_CTX *context; /* Context for encryption */
3861 BIO *bio; /* BIO data */
3862 const char *message = NULL;/* Error message */
3863 # elif defined(HAVE_GNUTLS)
3864 int status; /* Status of handshake */
3865 gnutls_certificate_client_credentials *credentials;
3866 /* TLS credentials */
3867 # elif defined(HAVE_CDSASSL)
3868 OSStatus error; /* Error code */
3869 char *hostname; /* Hostname */
3870 const char *message = NULL;/* Error message */
3871 # ifdef HAVE_SECCERTIFICATECOPYDATA
3872 cups_array_t *credentials; /* Credentials array */
3873 cups_array_t *names; /* CUPS distinguished names */
3874 CFArrayRef dn_array; /* CF distinguished names array */
3875 CFIndex count; /* Number of credentials */
3876 CFDataRef data; /* Certificate data */
3877 int i; /* Looping var */
3878 http_credential_t *credential; /* Credential data */
3879 # endif /* HAVE_SECCERTIFICATECOPYDATA */
3880 # elif defined(HAVE_SSPISSL)
3881 TCHAR username[256]; /* Username returned from GetUserName() */
3882 TCHAR commonName[256];/* Common name for certificate */
3883 DWORD dwSize; /* 32 bit size */
3884 # endif /* HAVE_LIBSSL */
3885
3886
3887 DEBUG_printf(("7http_setup_ssl(http=%p)", http));
3888
3889 /*
3890 * Always allow self-signed certificates for the local loopback address...
3891 */
3892
3893 if (httpAddrLocalhost(http->hostaddr))
3894 any_root = 1;
3895 else
3896 any_root = cg->any_root;
3897
3898 # ifdef HAVE_LIBSSL
3899 (void)any_root;
3900
3901 context = SSL_CTX_new(SSLv23_client_method());
3902
3903 SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
3904
3905 bio = BIO_new(_httpBIOMethods());
3906 BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
3907
3908 http->tls = SSL_new(context);
3909 SSL_set_bio(http->tls, bio, bio);
3910
3911 if (SSL_connect(http->tls) != 1)
3912 {
3913 unsigned long error; /* Error code */
3914
3915 while ((error = ERR_get_error()) != 0)
3916 {
3917 message = ERR_error_string(error, NULL);
3918 DEBUG_printf(("8http_setup_ssl: %s", message));
3919 }
3920
3921 SSL_CTX_free(context);
3922 SSL_free(http->tls);
3923 http->tls = NULL;
3924
3925 # ifdef WIN32
3926 http->error = WSAGetLastError();
3927 # else
3928 http->error = errno;
3929 # endif /* WIN32 */
3930 http->status = HTTP_ERROR;
3931
3932 if (!message)
3933 message = _("Unable to establish a secure connection to host.");
3934
3935 _cupsSetError(IPP_PKI_ERROR, message, 1);
3936
3937 return (-1);
3938 }
3939
3940 # elif defined(HAVE_GNUTLS)
3941 (void)any_root;
3942
3943 credentials = (gnutls_certificate_client_credentials *)
3944 malloc(sizeof(gnutls_certificate_client_credentials));
3945 if (credentials == NULL)
3946 {
3947 DEBUG_printf(("8http_setup_ssl: Unable to allocate credentials: %s",
3948 strerror(errno)));
3949 http->error = errno;
3950 http->status = HTTP_ERROR;
3951 _cupsSetHTTPError(HTTP_ERROR);
3952
3953 return (-1);
3954 }
3955
3956 gnutls_certificate_allocate_credentials(credentials);
3957
3958 gnutls_init(&http->tls, GNUTLS_CLIENT);
3959 gnutls_set_default_priority(http->tls);
3960 gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, http->hostname, strlen(http->hostname));
3961 gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials);
3962 gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr)http);
3963 gnutls_transport_set_pull_function(http->tls, _httpReadGNUTLS);
3964 gnutls_transport_set_push_function(http->tls, _httpWriteGNUTLS);
3965
3966 while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS)
3967 {
3968 DEBUG_printf(("8http_setup_ssl: gnutls_handshake returned %d (%s)",
3969 status, gnutls_strerror(status)));
3970
3971 if (gnutls_error_is_fatal(status))
3972 {
3973 http->error = EIO;
3974 http->status = HTTP_ERROR;
3975
3976 _cupsSetError(IPP_PKI_ERROR, gnutls_strerror(status), 0);
3977
3978 gnutls_deinit(http->tls);
3979 gnutls_certificate_free_credentials(*credentials);
3980 free(credentials);
3981 http->tls = NULL;
3982
3983 return (-1);
3984 }
3985 }
3986
3987 http->tls_credentials = credentials;
3988
3989 # elif defined(HAVE_CDSASSL)
3990 if ((error = SSLNewContext(false, &http->tls)))
3991 {
3992 http->error = errno;
3993 http->status = HTTP_ERROR;
3994 _cupsSetHTTPError(HTTP_ERROR);
3995
3996 return (-1);
3997 }
3998
3999 error = SSLSetConnection(http->tls, http);
4000 DEBUG_printf(("4http_setup_ssl: SSLSetConnection, error=%d", (int)error));
4001
4002 if (!error)
4003 {
4004 error = SSLSetIOFuncs(http->tls, _httpReadCDSA, _httpWriteCDSA);
4005 DEBUG_printf(("4http_setup_ssl: SSLSetIOFuncs, error=%d", (int)error));
4006 }
4007
4008 if (!error)
4009 {
4010 error = SSLSetAllowsAnyRoot(http->tls, any_root);
4011 DEBUG_printf(("4http_setup_ssl: SSLSetAllowsAnyRoot(%d), error=%d",
4012 any_root, (int)error));
4013 }
4014
4015 if (!error)
4016 {
4017 error = SSLSetAllowsExpiredCerts(http->tls, cg->expired_certs);
4018 DEBUG_printf(("4http_setup_ssl: SSLSetAllowsExpiredCerts(%d), error=%d",
4019 cg->expired_certs, (int)error));
4020 }
4021
4022 if (!error)
4023 {
4024 error = SSLSetAllowsExpiredRoots(http->tls, cg->expired_root);
4025 DEBUG_printf(("4http_setup_ssl: SSLSetAllowsExpiredRoots(%d), error=%d",
4026 cg->expired_root, (int)error));
4027 }
4028
4029 # ifdef HAVE_SSLSETPROTOCOLVERSIONMAX
4030 if (!error)
4031 {
4032 error = SSLSetProtocolVersionMax(http->tls, kTLSProtocol1);
4033 DEBUG_printf(("4http_setup_ssl: SSLSetProtocolVersionMax(kTLSProtocol1), "
4034 "error=%d", (int)error));
4035 }
4036 # endif /* HAVE_SSLSETPROTOCOLVERSIONMAX */
4037
4038 /*
4039 * In general, don't verify certificates since things like the common name
4040 * often do not match...
4041 */
4042
4043 if (!error)
4044 {
4045 error = SSLSetEnableCertVerify(http->tls, false);
4046 DEBUG_printf(("4http_setup_ssl: SSLSetEnableCertVerify, error=%d",
4047 (int)error));
4048 }
4049
4050 # ifdef HAVE_SECCERTIFICATECOPYDATA
4051 if (!error)
4052 {
4053 if (cg->client_cert_cb)
4054 {
4055 error = SSLSetSessionOption(http->tls,
4056 kSSLSessionOptionBreakOnCertRequested, true);
4057 DEBUG_printf(("4http_setup_ssl: kSSLSessionOptionBreakOnCertRequested, "
4058 "error=%d", (int)error));
4059 }
4060 else
4061 {
4062 error = http_set_credentials(http);
4063 DEBUG_printf(("4http_setup_ssl: http_set_credentials, error=%d",
4064 (int)error));
4065 }
4066 }
4067
4068 /*
4069 * If there's a server certificate callback installed let it evaluate the
4070 * certificate(s) during the handshake...
4071 */
4072
4073 if (!error && cg->server_cert_cb != NULL)
4074 {
4075 error = SSLSetSessionOption(http->tls,
4076 kSSLSessionOptionBreakOnServerAuth, true);
4077 DEBUG_printf(("4http_setup_ssl: kSSLSessionOptionBreakOnServerAuth, "
4078 "error=%d", (int)error));
4079 }
4080 # endif /* HAVE_SECCERTIFICATECOPYDATA */
4081
4082 /*
4083 * Let the server know which hostname/domain we are trying to connect to
4084 * in case it wants to serve up a certificate with a matching common name.
4085 */
4086
4087 if (!error)
4088 {
4089 hostname = httpAddrLocalhost(http->hostaddr) ? "localhost" : http->hostname;
4090 error = SSLSetPeerDomainName(http->tls, hostname, strlen(hostname));
4091
4092 DEBUG_printf(("4http_setup_ssl: SSLSetPeerDomainName, error=%d",
4093 (int)error));
4094 }
4095
4096 if (!error)
4097 {
4098 int done = 0; /* Are we done yet? */
4099
4100 while (!error && !done)
4101 {
4102 error = SSLHandshake(http->tls);
4103
4104 DEBUG_printf(("4http_setup_ssl: SSLHandshake returned %d.", (int)error));
4105
4106 switch (error)
4107 {
4108 case noErr :
4109 done = 1;
4110 break;
4111
4112 case errSSLWouldBlock :
4113 usleep(1000);
4114 break;
4115
4116 # ifdef HAVE_SECCERTIFICATECOPYDATA
4117 case errSSLServerAuthCompleted :
4118 error = 0;
4119 if (cg->server_cert_cb)
4120 {
4121 error = httpCopyCredentials(http, &credentials);
4122 if (!error)
4123 {
4124 error = (cg->server_cert_cb)(http, http->tls, credentials,
4125 cg->server_cert_data);
4126 httpFreeCredentials(credentials);
4127 }
4128
4129 DEBUG_printf(("4http_setup_ssl: Server certificate callback "
4130 "returned %d.", (int)error));
4131 }
4132 break;
4133
4134 case errSSLClientCertRequested :
4135 error = 0;
4136
4137 if (cg->client_cert_cb)
4138 {
4139 names = NULL;
4140 if (!(error = SSLCopyDistinguishedNames(http->tls, &dn_array)) &&
4141 dn_array)
4142 {
4143 if ((names = cupsArrayNew(NULL, NULL)) != NULL)
4144 {
4145 for (i = 0, count = CFArrayGetCount(dn_array); i < count; i++)
4146 {
4147 data = (CFDataRef)CFArrayGetValueAtIndex(dn_array, i);
4148
4149 if ((credential = malloc(sizeof(*credential))))
4150 {
4151 credential->datalen = CFDataGetLength(data);
4152 if ((credential->data = malloc(credential->datalen)))
4153 {
4154 memcpy((void *)credential->data, CFDataGetBytePtr(data),
4155 credential->datalen);
4156 cupsArrayAdd(names, credential);
4157 }
4158 }
4159 }
4160 }
4161
4162 CFRelease(dn_array);
4163 }
4164
4165 if (!error)
4166 {
4167 error = (cg->client_cert_cb)(http, http->tls, names,
4168 cg->client_cert_data);
4169
4170 DEBUG_printf(("4http_setup_ssl: Client certificate callback "
4171 "returned %d.", (int)error));
4172 }
4173
4174 httpFreeCredentials(names);
4175 }
4176 break;
4177 # endif /* HAVE_SECCERTIFICATECOPYDATA */
4178
4179 case errSSLUnknownRootCert :
4180 message = _("Unable to establish a secure connection to host "
4181 "(untrusted certificate).");
4182 break;
4183
4184 case errSSLNoRootCert :
4185 message = _("Unable to establish a secure connection to host "
4186 "(self-signed certificate).");
4187 break;
4188
4189 case errSSLCertExpired :
4190 message = _("Unable to establish a secure connection to host "
4191 "(expired certificate).");
4192 break;
4193
4194 case errSSLCertNotYetValid :
4195 message = _("Unable to establish a secure connection to host "
4196 "(certificate not yet valid).");
4197 break;
4198
4199 case errSSLHostNameMismatch :
4200 message = _("Unable to establish a secure connection to host "
4201 "(host name mismatch).");
4202 break;
4203
4204 case errSSLXCertChainInvalid :
4205 message = _("Unable to establish a secure connection to host "
4206 "(certificate chain invalid).");
4207 break;
4208
4209 case errSSLConnectionRefused :
4210 message = _("Unable to establish a secure connection to host "
4211 "(peer dropped connection before responding).");
4212 break;
4213
4214 default :
4215 break;
4216 }
4217 }
4218 }
4219
4220 if (error)
4221 {
4222 http->error = error;
4223 http->status = HTTP_ERROR;
4224 errno = ECONNREFUSED;
4225
4226 SSLDisposeContext(http->tls);
4227 http->tls = NULL;
4228
4229 /*
4230 * If an error string wasn't set by the callbacks use a generic one...
4231 */
4232
4233 if (!message)
4234 #ifdef HAVE_CSSMERRORSTRING
4235 message = cssmErrorString(error);
4236 #else
4237 message = _("Unable to establish a secure connection to host.");
4238 #endif /* HAVE_CSSMERRORSTRING */
4239
4240 _cupsSetError(IPP_PKI_ERROR, message, 1);
4241
4242 return (-1);
4243 }
4244
4245 # elif defined(HAVE_SSPISSL)
4246 http->tls = _sspiAlloc();
4247
4248 if (!http->tls)
4249 {
4250 _cupsSetHTTPError(HTTP_ERROR);
4251 return (-1);
4252 }
4253
4254 http->tls->sock = http->fd;
4255 dwSize = sizeof(username) / sizeof(TCHAR);
4256 GetUserName(username, &dwSize);
4257 _sntprintf_s(commonName, sizeof(commonName) / sizeof(TCHAR),
4258 sizeof(commonName) / sizeof(TCHAR), TEXT("CN=%s"), username);
4259
4260 if (!_sspiGetCredentials(http->tls_credentials, L"ClientContainer",
4261 commonName, FALSE))
4262 {
4263 _sspiFree(http->tls_credentials);
4264 http->tls_credentials = NULL;
4265
4266 http->error = EIO;
4267 http->status = HTTP_ERROR;
4268
4269 _cupsSetError(IPP_PKI_ERROR,
4270 _("Unable to establish a secure connection to host."), 1);
4271
4272 return (-1);
4273 }
4274
4275 _sspiSetAllowsAnyRoot(http->tls_credentials, any_root);
4276 _sspiSetAllowsExpiredCerts(http->tls_credentials, TRUE);
4277
4278 if (!_sspiConnect(http->tls_credentials, http->hostname))
4279 {
4280 _sspiFree(http->tls_credentials);
4281 http->tls_credentials = NULL;
4282
4283 http->error = EIO;
4284 http->status = HTTP_ERROR;
4285
4286 _cupsSetError(IPP_PKI_ERROR,
4287 _("Unable to establish a secure connection to host."), 1);
4288
4289 return (-1);
4290 }
4291 # endif /* HAVE_CDSASSL */
4292
4293 return (0);
4294 }
4295
4296
4297 /*
4298 * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
4299 */
4300
4301 static void
4302 http_shutdown_ssl(http_t *http) /* I - Connection to server */
4303 {
4304 # ifdef HAVE_LIBSSL
4305 SSL_CTX *context; /* Context for encryption */
4306
4307 context = SSL_get_SSL_CTX(http->tls);
4308
4309 SSL_shutdown(http->tls);
4310 SSL_CTX_free(context);
4311 SSL_free(http->tls);
4312
4313 # elif defined(HAVE_GNUTLS)
4314 gnutls_certificate_client_credentials *credentials;
4315 /* TLS credentials */
4316
4317 credentials = (gnutls_certificate_client_credentials *)(http->tls_credentials);
4318
4319 gnutls_bye(http->tls, GNUTLS_SHUT_RDWR);
4320 gnutls_deinit(http->tls);
4321 gnutls_certificate_free_credentials(*credentials);
4322 free(credentials);
4323
4324 # elif defined(HAVE_CDSASSL)
4325 while (SSLClose(http->tls) == errSSLWouldBlock)
4326 usleep(1000);
4327
4328 SSLDisposeContext(http->tls);
4329
4330 if (http->tls_credentials)
4331 CFRelease(http->tls_credentials);
4332
4333 # elif defined(HAVE_SSPISSL)
4334 _sspiFree(http->tls_credentials);
4335 # endif /* HAVE_LIBSSL */
4336
4337 http->tls = NULL;
4338 http->tls_credentials = NULL;
4339 }
4340 #endif /* HAVE_SSL */
4341
4342
4343 #ifdef HAVE_SSL
4344 /*
4345 * 'http_upgrade()' - Force upgrade to TLS encryption.
4346 */
4347
4348 static int /* O - Status of connection */
4349 http_upgrade(http_t *http) /* I - Connection to server */
4350 {
4351 int ret; /* Return value */
4352 http_t myhttp; /* Local copy of HTTP data */
4353
4354
4355 DEBUG_printf(("7http_upgrade(%p)", http));
4356
4357 /*
4358 * Flush the connection to make sure any previous "Upgrade" message
4359 * has been read.
4360 */
4361
4362 httpFlush(http);
4363
4364 /*
4365 * Copy the HTTP data to a local variable so we can do the OPTIONS
4366 * request without interfering with the existing request data...
4367 */
4368
4369 memcpy(&myhttp, http, sizeof(myhttp));
4370
4371 /*
4372 * Send an OPTIONS request to the server, requiring SSL or TLS
4373 * encryption on the link...
4374 */
4375
4376 http->field_authorization = NULL; /* Don't free the auth string */
4377
4378 httpClearFields(http);
4379 httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
4380 httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2, TLS/1.1, TLS/1.0, SSL/3.0");
4381
4382 if ((ret = httpOptions(http, "*")) == 0)
4383 {
4384 /*
4385 * Wait for the secure connection...
4386 */
4387
4388 while (httpUpdate(http) == HTTP_CONTINUE);
4389 }
4390
4391 /*
4392 * Restore the HTTP request data...
4393 */
4394
4395 memcpy(http->fields, myhttp.fields, sizeof(http->fields));
4396 http->data_encoding = myhttp.data_encoding;
4397 http->data_remaining = myhttp.data_remaining;
4398 http->_data_remaining = myhttp._data_remaining;
4399 http->expect = myhttp.expect;
4400 http->field_authorization = myhttp.field_authorization;
4401 http->digest_tries = myhttp.digest_tries;
4402
4403 /*
4404 * See if we actually went secure...
4405 */
4406
4407 if (!http->tls)
4408 {
4409 /*
4410 * Server does not support HTTP upgrade...
4411 */
4412
4413 DEBUG_puts("8http_upgrade: Server does not support HTTP upgrade!");
4414
4415 # ifdef WIN32
4416 closesocket(http->fd);
4417 # else
4418 close(http->fd);
4419 # endif
4420
4421 http->fd = -1;
4422
4423 return (-1);
4424 }
4425 else
4426 return (ret);
4427 }
4428 #endif /* HAVE_SSL */
4429
4430
4431 /*
4432 * 'http_write()' - Write a buffer to a HTTP connection.
4433 */
4434
4435 static int /* O - Number of bytes written */
4436 http_write(http_t *http, /* I - Connection to server */
4437 const char *buffer, /* I - Buffer for data */
4438 int length) /* I - Number of bytes to write */
4439 {
4440 int tbytes, /* Total bytes sent */
4441 bytes; /* Bytes sent */
4442
4443
4444 DEBUG_printf(("2http_write(http=%p, buffer=%p, length=%d)", http, buffer,
4445 length));
4446 http->error = 0;
4447 tbytes = 0;
4448
4449 while (length > 0)
4450 {
4451 if (http->timeout_cb)
4452 {
4453 #ifdef HAVE_POLL
4454 struct pollfd pfd; /* Polled file descriptor */
4455 #else
4456 fd_set output_set; /* Output ready for write? */
4457 struct timeval timeout; /* Timeout value */
4458 #endif /* HAVE_POLL */
4459 int nfds; /* Result from select()/poll() */
4460
4461 do
4462 {
4463 #ifdef HAVE_POLL
4464 pfd.fd = http->fd;
4465 pfd.events = POLLOUT;
4466
4467 while ((nfds = poll(&pfd, 1, http->wait_value)) < 0 &&
4468 (errno == EINTR || errno == EAGAIN));
4469
4470 #else
4471 do
4472 {
4473 FD_ZERO(&output_set);
4474 FD_SET(http->fd, &output_set);
4475
4476 timeout.tv_sec = http->wait_value / 1000;
4477 timeout.tv_usec = 1000 * (http->wait_value % 1000);
4478
4479 nfds = select(http->fd + 1, NULL, &output_set, NULL, &timeout);
4480 }
4481 # ifdef WIN32
4482 while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
4483 WSAGetLastError() == WSAEWOULDBLOCK));
4484 # else
4485 while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
4486 # endif /* WIN32 */
4487 #endif /* HAVE_POLL */
4488
4489 if (nfds < 0)
4490 {
4491 http->error = errno;
4492 return (-1);
4493 }
4494 else if (nfds == 0 && !(*http->timeout_cb)(http, http->timeout_data))
4495 {
4496 #ifdef WIN32
4497 http->error = WSAEWOULDBLOCK;
4498 #else
4499 http->error = EWOULDBLOCK;
4500 #endif /* WIN32 */
4501 return (-1);
4502 }
4503 }
4504 while (nfds <= 0);
4505 }
4506
4507 #ifdef HAVE_SSL
4508 if (http->tls)
4509 bytes = http_write_ssl(http, buffer, length);
4510 else
4511 #endif /* HAVE_SSL */
4512 bytes = send(http->fd, buffer, length, 0);
4513
4514 if (bytes < 0)
4515 {
4516 #ifdef WIN32
4517 if (WSAGetLastError() == WSAEINTR)
4518 continue;
4519 else if (WSAGetLastError() == WSAEWOULDBLOCK)
4520 {
4521 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
4522 continue;
4523
4524 http->error = WSAGetLastError();
4525 }
4526 else if (WSAGetLastError() != http->error &&
4527 WSAGetLastError() != WSAECONNRESET)
4528 {
4529 http->error = WSAGetLastError();
4530 continue;
4531 }
4532
4533 #else
4534 if (errno == EINTR)
4535 continue;
4536 else if (errno == EWOULDBLOCK || errno == EAGAIN)
4537 {
4538 if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
4539 continue;
4540 else if (!http->timeout_cb && errno == EAGAIN)
4541 continue;
4542
4543 http->error = errno;
4544 }
4545 else if (errno != http->error && errno != ECONNRESET)
4546 {
4547 http->error = errno;
4548 continue;
4549 }
4550 #endif /* WIN32 */
4551
4552 DEBUG_printf(("3http_write: error writing data (%s).",
4553 strerror(http->error)));
4554
4555 return (-1);
4556 }
4557
4558 buffer += bytes;
4559 tbytes += bytes;
4560 length -= bytes;
4561 }
4562
4563 #ifdef DEBUG
4564 http_debug_hex("http_write", buffer - tbytes, tbytes);
4565 #endif /* DEBUG */
4566
4567 DEBUG_printf(("3http_write: Returning %d.", tbytes));
4568
4569 return (tbytes);
4570 }
4571
4572
4573 /*
4574 * 'http_write_chunk()' - Write a chunked buffer.
4575 */
4576
4577 static int /* O - Number bytes written */
4578 http_write_chunk(http_t *http, /* I - Connection to server */
4579 const char *buffer, /* I - Buffer to write */
4580 int length) /* I - Length of buffer */
4581 {
4582 char header[255]; /* Chunk header */
4583 int bytes; /* Bytes written */
4584
4585
4586 DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=%d)",
4587 http, buffer, length));
4588
4589 /*
4590 * Write the chunk header, data, and trailer.
4591 */
4592
4593 sprintf(header, "%x\r\n", length);
4594 if (http_write(http, header, (int)strlen(header)) < 0)
4595 {
4596 DEBUG_puts("8http_write_chunk: http_write of length failed!");
4597 return (-1);
4598 }
4599
4600 if ((bytes = http_write(http, buffer, length)) < 0)
4601 {
4602 DEBUG_puts("8http_write_chunk: http_write of buffer failed!");
4603 return (-1);
4604 }
4605
4606 if (http_write(http, "\r\n", 2) < 0)
4607 {
4608 DEBUG_puts("8http_write_chunk: http_write of CR LF failed!");
4609 return (-1);
4610 }
4611
4612 return (bytes);
4613 }
4614
4615
4616 #ifdef HAVE_SSL
4617 /*
4618 * 'http_write_ssl()' - Write to a SSL/TLS connection.
4619 */
4620
4621 static int /* O - Bytes written */
4622 http_write_ssl(http_t *http, /* I - Connection to server */
4623 const char *buf, /* I - Buffer holding data */
4624 int len) /* I - Length of buffer */
4625 {
4626 ssize_t result; /* Return value */
4627
4628
4629 DEBUG_printf(("2http_write_ssl(http=%p, buf=%p, len=%d)", http, buf, len));
4630
4631 # if defined(HAVE_LIBSSL)
4632 result = SSL_write((SSL *)(http->tls), buf, len);
4633
4634 # elif defined(HAVE_GNUTLS)
4635 result = gnutls_record_send(http->tls, buf, len);
4636
4637 if (result < 0 && !errno)
4638 {
4639 /*
4640 * Convert GNU TLS error to errno value...
4641 */
4642
4643 switch (result)
4644 {
4645 case GNUTLS_E_INTERRUPTED :
4646 errno = EINTR;
4647 break;
4648
4649 case GNUTLS_E_AGAIN :
4650 errno = EAGAIN;
4651 break;
4652
4653 default :
4654 errno = EPIPE;
4655 break;
4656 }
4657
4658 result = -1;
4659 }
4660
4661 # elif defined(HAVE_CDSASSL)
4662 OSStatus error; /* Error info */
4663 size_t processed; /* Number of bytes processed */
4664
4665
4666 error = SSLWrite(http->tls, buf, len, &processed);
4667
4668 switch (error)
4669 {
4670 case 0 :
4671 result = (int)processed;
4672 break;
4673
4674 case errSSLWouldBlock :
4675 if (processed)
4676 result = (int)processed;
4677 else
4678 {
4679 result = -1;
4680 errno = EINTR;
4681 }
4682 break;
4683
4684 case errSSLClosedGraceful :
4685 default :
4686 if (processed)
4687 result = (int)processed;
4688 else
4689 {
4690 result = -1;
4691 errno = EPIPE;
4692 }
4693 break;
4694 }
4695 # elif defined(HAVE_SSPISSL)
4696 return _sspiWrite((_sspi_struct_t *)http->tls, (void *)buf, len);
4697 # endif /* HAVE_LIBSSL */
4698
4699 DEBUG_printf(("3http_write_ssl: Returning %d.", (int)result));
4700
4701 return ((int)result);
4702 }
4703 #endif /* HAVE_SSL */
4704
4705
4706 /*
4707 * End of "$Id: http.c 7850 2008-08-20 00:07:25Z mike $".
4708 */