summaryrefslogtreecommitdiff
path: root/cups/http.c
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-12-12 20:54:21 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-12-12 20:54:21 +0000
commitc1420c8744235de1249c34b956b7c11ccafd659d (patch)
tree27879336dd313e589eb2004964f2af416520daff /cups/http.c
parentc41769ffd04ad45bb2c95691ad3999674896a2ed (diff)
Merge changes from CUPS 1.7svn-r10755.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@4074 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'cups/http.c')
-rw-r--r--cups/http.c231
1 files changed, 145 insertions, 86 deletions
diff --git a/cups/http.c b/cups/http.c
index d5099b272..12e7338ad 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -176,9 +176,9 @@ static int http_write_chunk(http_t *http, const char *buffer,
int length);
#ifdef HAVE_SSL
static int http_read_ssl(http_t *http, char *buf, int len);
-# if defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
+# ifdef HAVE_CDSASSL
static int http_set_credentials(http_t *http);
-# endif /* HAVE_CDSASSL ** HAVE_SECCERTIFICATECOPYDATA */
+# endif /* HAVE_CDSASSL */
#endif /* HAVE_SSL */
static off_t http_set_length(http_t *http);
static void http_set_timeout(int fd, double timeout);
@@ -671,10 +671,10 @@ httpCopyCredentials(
{
# ifdef HAVE_LIBSSL
# elif defined(HAVE_GNUTLS)
-# elif defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
+# elif defined(HAVE_CDSASSL)
OSStatus error; /* Error code */
+ SecTrustRef peerTrust; /* Peer trust reference */
CFIndex count; /* Number of credentials */
- CFArrayRef peerCerts; /* Peer certificates */
SecCertificateRef secCert; /* Certificate reference */
CFDataRef data; /* Certificate data */
int i; /* Looping var */
@@ -694,14 +694,16 @@ httpCopyCredentials(
# elif defined(HAVE_GNUTLS)
return (-1);
-# elif defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
- if (!(error = SSLCopyPeerCertificates(http->tls, &peerCerts)) && peerCerts)
+# elif defined(HAVE_CDSASSL)
+ if (!(error = SSLCopyPeerTrust(http->tls, &peerTrust)) && peerTrust)
{
if ((*credentials = cupsArrayNew(NULL, NULL)) != NULL)
{
- for (i = 0, count = CFArrayGetCount(peerCerts); i < count; i++)
+ count = SecTrustGetCertificateCount(peerTrust);
+
+ for (i = 0; i < count; i ++)
{
- secCert = (SecCertificateRef)CFArrayGetValueAtIndex(peerCerts, i);
+ secCert = SecTrustGetCertificateAtIndex(peerTrust, i);
if ((data = SecCertificateCopyData(secCert)))
{
httpAddCredential(*credentials, CFDataGetBytePtr(data),
@@ -711,7 +713,7 @@ httpCopyCredentials(
}
}
- CFRelease(peerCerts);
+ CFRelease(peerTrust);
}
return (error);
@@ -832,7 +834,7 @@ _httpCreateCredentials(
# elif defined(HAVE_GNUTLS)
return (NULL);
-# elif defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
+# elif defined(HAVE_CDSASSL)
CFMutableArrayRef peerCerts; /* Peer credentials reference */
SecCertificateRef secCert; /* Certificate reference */
CFDataRef data; /* Credential data reference */
@@ -969,6 +971,13 @@ httpFlush(http_t *http) /* I - Connection to server */
http_states[http->state + 1]));
/*
+ * Nothing to do if we are in the "waiting" state...
+ */
+
+ if (http->state == HTTP_STATE_WAITING)
+ return;
+
+ /*
* Temporarily set non-blocking mode so we don't get stuck in httpRead()...
*/
@@ -1981,7 +1990,9 @@ httpPeek(http_t *http, /* I - Connection to server */
return (0);
}
- else if (length > (size_t)http->data_remaining)
+ else if ((http->data_encoding == HTTP_ENCODING_LENGTH ||
+ http->coding == _HTTP_CODING_IDENTITY) &&
+ length > (size_t)http->data_remaining)
length = (size_t)http->data_remaining;
if (http->used == 0)
@@ -2069,6 +2080,47 @@ httpPeek(http_t *http, /* I - Connection to server */
http->used = bytes;
}
+#ifdef HAVE_LIBZ
+ if (http->coding)
+ {
+ int zerr; /* Decompressor error */
+ off_t comp_avail; /* Maximum bytes for decompression */
+ z_stream stream; /* Copy of decompressor stream */
+
+ if (http->used > http->data_remaining)
+ comp_avail = http->data_remaining;
+ else
+ comp_avail = http->used;
+
+ DEBUG_printf(("2httpPeek: length=%d, avail_in=%d", (int)length,
+ (int)comp_avail));
+
+ if (inflateCopy(&stream, &(http->stream)) != Z_OK)
+ {
+ DEBUG_puts("2httpPeek: Unable to copy decompressor stream.");
+ http->error = ENOMEM;
+ return (-1);
+ }
+
+ stream.next_in = (Bytef *)http->buffer;
+ stream.avail_in = comp_avail;
+ stream.next_out = (Bytef *)buffer;
+ stream.avail_out = length;
+
+ zerr = inflate(&stream, Z_SYNC_FLUSH);
+ inflateEnd(&stream);
+
+ if (zerr < Z_OK)
+ {
+ DEBUG_printf(("2httpPeek: zerr=%d", zerr));
+ http->error = EIO;
+ return (-1);
+ }
+
+ bytes = length - http->stream.avail_out;
+ }
+ else
+#endif /* HAVE_LIBZ */
if (http->used > 0)
{
if (length > (size_t)http->used)
@@ -2111,6 +2163,10 @@ httpPeek(http_t *http, /* I - Connection to server */
return (bytes);
}
+/* For OS X 10.8 and earlier */
+ssize_t _httpPeek(http_t *http, char *buffer, size_t length)
+{ return (httpPeek(http, buffer, length)); }
+
/*
* 'httpPost()' - Send a POST request to the server.
@@ -3124,6 +3180,56 @@ httpSetCookie(http_t *http, /* I - Connection */
/*
+ * 'httpSetDefaultField()' - Set the default value of an HTTP header.
+ *
+ * Currently only HTTP_FIELD_ACCEPT_ENCODING, HTTP_FIELD_SERVER, and
+ * HTTP_FIELD_USER_AGENT can be set.
+ *
+ * @since CUPS 1.7@
+ */
+
+void
+httpSetDefaultField(http_t *http, /* I - Connection to server */
+ http_field_t field, /* I - Field index */
+ const char *value)/* I - Value */
+{
+ DEBUG_printf(("httpSetDefaultField(http=%p, field=%d(%s), value=\"%s\")",
+ http, field, http_fields[field], value));
+
+ if (!http)
+ return;
+
+ switch (field)
+ {
+ case HTTP_FIELD_ACCEPT_ENCODING :
+ if (http->default_accept_encoding)
+ _cupsStrFree(http->default_accept_encoding);
+
+ http->default_accept_encoding = value ? _cupsStrAlloc(value) : NULL;
+ break;
+
+ case HTTP_FIELD_SERVER :
+ if (http->default_server)
+ _cupsStrFree(http->default_server);
+
+ http->default_server = value ? _cupsStrAlloc(value) : NULL;
+ break;
+
+ case HTTP_FIELD_USER_AGENT :
+ if (http->default_user_agent)
+ _cupsStrFree(http->default_user_agent);
+
+ http->default_user_agent = value ? _cupsStrAlloc(value) : NULL;
+ break;
+
+ default :
+ DEBUG_puts("1httpSetDefaultField: Ignored.");
+ break;
+ }
+}
+
+
+/*
* 'httpSetExpect()' - Set the Expect: header in a request.
*
* Currently only @code HTTP_STATUS_CONTINUE@ is supported for the "expect"
@@ -4061,15 +4167,20 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */
#endif /* HAVE_SSL */
if (!http->server)
- httpSetField(http, HTTP_FIELD_SERVER, CUPS_MINIMAL);
+ httpSetField(http, HTTP_FIELD_SERVER,
+ http->default_server ? http->default_server : CUPS_MINIMAL);
-#ifdef HAVE_LIBZ
/*
* Set the Accept-Encoding field if it isn't already...
*/
if (!http->accept_encoding)
- httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, "gzip, deflate, identity");
+ httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING,
+ http->default_accept_encoding ? http->default_accept_encoding :
+#ifdef HAVE_LIBZ
+ "gzip, deflate, identity");
+#else
+ "identity");
#endif /* HAVE_LIBZ */
/*
@@ -4681,16 +4792,17 @@ http_send(http_t *http, /* I - Connection to server */
*/
if (!http->fields[HTTP_FIELD_USER_AGENT][0])
- httpSetField(http, HTTP_FIELD_USER_AGENT, CUPS_MINIMAL);
+ httpSetField(http, HTTP_FIELD_USER_AGENT,
+ http->default_user_agent ? http->default_user_agent :
+ CUPS_MINIMAL);
-#ifdef HAVE_LIBZ
/*
* Set the Accept-Encoding field if it isn't already...
*/
- if (!http->accept_encoding)
- httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, "gzip, deflate, identity");
-#endif /* HAVE_LIBZ */
+ if (!http->accept_encoding && http->default_accept_encoding)
+ httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING,
+ http->default_accept_encoding);
/*
* Encode the URI as needed...
@@ -4813,7 +4925,7 @@ http_send(http_t *http, /* I - Connection to server */
#ifdef HAVE_SSL
-# if defined(HAVE_CDSASSL) && defined(HAVE_SECCERTIFICATECOPYDATA)
+# if defined(HAVE_CDSASSL)
/*
* 'http_set_credentials()' - Set the SSL/TLS credentials.
*/
@@ -4836,7 +4948,6 @@ http_set_credentials(http_t *http) /* I - Connection to server */
if ((credentials = http->tls_credentials) == NULL)
credentials = cg->tls_credentials;
-# if HAVE_SECPOLICYCREATESSL
/*
* Otherwise root around in the user's keychain to see if one can be found...
*/
@@ -4891,7 +5002,6 @@ http_set_credentials(http_t *http) /* I - Connection to server */
if (dn_array)
CFRelease(dn_array);
}
-# endif /* HAVE_SECPOLICYCREATESSL */
if (credentials)
{
@@ -4904,7 +5014,7 @@ http_set_credentials(http_t *http) /* I - Connection to server */
return (error);
}
-# endif /* HAVE_CDSASSL && HAVE_SECCERTIFICATECOPYDATA */
+# endif /* HAVE_CDSASSL */
#endif /* HAVE_SSL */
@@ -5016,7 +5126,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
{
_cups_globals_t *cg = _cupsGlobals();
/* Pointer to library globals */
- int any_root; /* Allow any root */
char hostname[256], /* Hostname */
*hostptr; /* Pointer into hostname */
@@ -5031,7 +5140,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
# elif defined(HAVE_CDSASSL)
OSStatus error; /* Error code */
const char *message = NULL;/* Error message */
-# ifdef HAVE_SECCERTIFICATECOPYDATA
cups_array_t *credentials; /* Credentials array */
cups_array_t *names; /* CUPS distinguished names */
CFArrayRef dn_array; /* CF distinguished names array */
@@ -5039,7 +5147,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
CFDataRef data; /* Certificate data */
int i; /* Looping var */
http_credential_t *credential; /* Credential data */
-# endif /* HAVE_SECCERTIFICATECOPYDATA */
# elif defined(HAVE_SSPISSL)
TCHAR username[256]; /* Username returned from GetUserName() */
TCHAR commonName[256];/* Common name for certificate */
@@ -5050,23 +5157,19 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
DEBUG_printf(("7http_setup_ssl(http=%p)", http));
/*
- * Always allow self-signed certificates for the local loopback address...
+ * Get the hostname to use for SSL...
*/
if (httpAddrLocalhost(http->hostaddr))
{
- any_root = 1;
strlcpy(hostname, "localhost", sizeof(hostname));
}
else
{
/*
- * Otherwise use the system-wide setting and make sure the hostname we have
- * does not end in a trailing dot.
+ * Otherwise make sure the hostname we have does not end in a trailing dot.
*/
- any_root = cg->any_root;
-
strlcpy(hostname, http->hostname, sizeof(hostname));
if ((hostptr = hostname + strlen(hostname) - 1) >= hostname &&
*hostptr == '.')
@@ -5074,8 +5177,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
}
# ifdef HAVE_LIBSSL
- (void)any_root;
-
context = SSL_CTX_new(SSLv23_client_method());
SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
@@ -5120,8 +5221,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
}
# elif defined(HAVE_GNUTLS)
- (void)any_root;
-
credentials = (gnutls_certificate_client_credentials *)
malloc(sizeof(gnutls_certificate_client_credentials));
if (credentials == NULL)
@@ -5170,9 +5269,11 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
http->tls_credentials = credentials;
# elif defined(HAVE_CDSASSL)
- if ((error = SSLNewContext(false, &http->tls)))
+ if ((http->tls = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide,
+ kSSLStreamType)) == NULL)
{
- http->error = errno;
+ DEBUG_puts("4http_setup_ssl: SSLCreateContext failed.");
+ http->error = errno = ENOMEM;
http->status = HTTP_ERROR;
_cupsSetHTTPError(HTTP_ERROR);
@@ -5190,38 +5291,12 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
if (!error)
{
- error = SSLSetAllowsAnyRoot(http->tls, any_root);
- DEBUG_printf(("4http_setup_ssl: SSLSetAllowsAnyRoot(%d), error=%d",
- any_root, (int)error));
- }
-
- if (!error)
- {
- error = SSLSetAllowsExpiredCerts(http->tls, cg->expired_certs);
- DEBUG_printf(("4http_setup_ssl: SSLSetAllowsExpiredCerts(%d), error=%d",
- cg->expired_certs, (int)error));
- }
-
- if (!error)
- {
- error = SSLSetAllowsExpiredRoots(http->tls, cg->expired_root);
- DEBUG_printf(("4http_setup_ssl: SSLSetAllowsExpiredRoots(%d), error=%d",
- cg->expired_root, (int)error));
- }
-
- /*
- * In general, don't verify certificates since things like the common name
- * often do not match...
- */
-
- if (!error)
- {
- error = SSLSetEnableCertVerify(http->tls, false);
- DEBUG_printf(("4http_setup_ssl: SSLSetEnableCertVerify, error=%d",
+ error = SSLSetSessionOption(http->tls, kSSLSessionOptionBreakOnServerAuth,
+ true);
+ DEBUG_printf(("4http_setup_ssl: SSLSetSessionOption, error=%d",
(int)error));
}
-# ifdef HAVE_SECCERTIFICATECOPYDATA
if (!error)
{
if (cg->client_cert_cb)
@@ -5240,20 +5315,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
}
/*
- * If there's a server certificate callback installed let it evaluate the
- * certificate(s) during the handshake...
- */
-
- if (!error && cg->server_cert_cb != NULL)
- {
- error = SSLSetSessionOption(http->tls,
- kSSLSessionOptionBreakOnServerAuth, true);
- DEBUG_printf(("4http_setup_ssl: kSSLSessionOptionBreakOnServerAuth, "
- "error=%d", (int)error));
- }
-# endif /* HAVE_SECCERTIFICATECOPYDATA */
-
- /*
* Let the server know which hostname/domain we are trying to connect to
* in case it wants to serve up a certificate with a matching common name.
*/
@@ -5287,7 +5348,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
usleep(1000); /* in 1 millisecond */
break;
-# ifdef HAVE_SECCERTIFICATECOPYDATA
case errSSLServerAuthCompleted :
error = 0;
if (cg->server_cert_cb)
@@ -5350,7 +5410,6 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
httpFreeCredentials(names);
}
break;
-# endif /* HAVE_SECCERTIFICATECOPYDATA */
case errSSLUnknownRootCert :
message = _("Unable to establish a secure connection to host "
@@ -5399,7 +5458,7 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
http->status = HTTP_ERROR;
errno = ECONNREFUSED;
- SSLDisposeContext(http->tls);
+ CFRelease(http->tls);
http->tls = NULL;
/*
@@ -5448,7 +5507,7 @@ http_setup_ssl(http_t *http) /* I - Connection to server */
return (-1);
}
- _sspiSetAllowsAnyRoot(http->tls_credentials, any_root);
+ _sspiSetAllowsAnyRoot(http->tls_credentials, TRUE);
_sspiSetAllowsExpiredCerts(http->tls_credentials, TRUE);
if (!_sspiConnect(http->tls_credentials, hostname))
@@ -5501,7 +5560,7 @@ http_shutdown_ssl(http_t *http) /* I - Connection to server */
while (SSLClose(http->tls) == errSSLWouldBlock)
usleep(1000);
- SSLDisposeContext(http->tls);
+ CFRelease(http->tls);
if (http->tls_credentials)
CFRelease(http->tls_credentials);