size_t length) /* I - Number of bytes to read */
{
http_t *http; /* HTTP connection */
+ ssize_t bytes; /* Bytes read */
+
+ DEBUG_printf(("6_httpReadGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data, (int)length));
http = (http_t *)ptr;
}
}
- return (recv(http->fd, data, length, 0));
+ bytes = recv(http->fd, data, length, 0);
+ DEBUG_printf(("6_httpReadGNUTLS: bytes=%d", (int)bytes));
+ return (bytes);
}
#endif /* HAVE_SSL && HAVE_GNUTLS */
const void *data, /* I - Data buffer */
size_t length) /* I - Number of bytes to write */
{
- return (send(((http_t *)ptr)->fd, data, length, 0));
+ ssize_t bytes; /* Bytes written */
+
+
+ DEBUG_printf(("6_httpWriteGNUTLS(ptr=%p, data=%p, length=%d)", ptr, data,
+ (int)length));
+ http_debug_hex("_httpWriteGNUTLS", data, (int)length);
+
+ bytes = send(((http_t *)ptr)->fd, data, length, 0);
+ DEBUG_printf(("_httpWriteGNUTLS: bytes=%d", (int)bytes));
+ return (bytes);
}
#endif /* HAVE_SSL && HAVE_GNUTLS */
* 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
*/
-static int /* O - Status of connection */
+static int /* O - 0 on success, -1 on failure */
http_setup_ssl(http_t *http) /* I - Connection to server */
{
_cups_globals_t *cg = _cupsGlobals();
int any_root; /* Allow any root */
# ifdef HAVE_LIBSSL
- SSL_CTX *context; /* Context for encryption */
- BIO *bio; /* BIO data */
+ SSL_CTX *context; /* Context for encryption */
+ BIO *bio; /* BIO data */
+ const char *message = NULL;/* Error message */
# elif defined(HAVE_GNUTLS)
+ int status; /* Status of handshake */
gnutls_certificate_client_credentials *credentials;
/* TLS credentials */
# elif defined(HAVE_CDSASSL)
- OSStatus error; /* Error code */
- const char *message = NULL; /* Error message */
- char *hostname; /* Hostname */
+ OSStatus error; /* Error code */
+ char *hostname; /* Hostname */
+ 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 */
- CFIndex count; /* Number of credentials */
- CFDataRef data; /* Certificate data */
- int i; /* Looping var */
- http_credential_t
- *credential; /* Credential data */
+ cups_array_t *credentials; /* Credentials array */
+ cups_array_t *names; /* CUPS distinguished names */
+ CFArrayRef dn_array; /* CF distinguished names array */
+ CFIndex count; /* Number of credentials */
+ 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 */
- DWORD dwSize; /* 32 bit size */
+ TCHAR username[256]; /* Username returned from GetUserName() */
+ TCHAR commonName[256];/* Common name for certificate */
+ DWORD dwSize; /* 32 bit size */
# endif /* HAVE_LIBSSL */
any_root = cg->any_root;
# 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 */
BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
http->tls = SSL_new(context);
- SSL_set_bio(http->tls_credentials, bio, bio);
+ SSL_set_bio(http->tls, bio, bio);
if (SSL_connect(http->tls) != 1)
{
-# ifdef DEBUG
unsigned long error; /* Error code */
while ((error = ERR_get_error()) != 0)
- DEBUG_printf(("8http_setup_ssl: %s", ERR_error_string(error, NULL)));
-# endif /* DEBUG */
+ {
+ message = ERR_error_string(error, NULL);
+ DEBUG_printf(("8http_setup_ssl: %s", message));
+ }
SSL_CTX_free(context);
SSL_free(http->tls);
# endif /* WIN32 */
http->status = HTTP_ERROR;
- return (HTTP_ERROR);
+ if (!message)
+ message = _("Unable to establish a secure connection to host.");
+
+ _cupsSetError(IPP_PKI_ERROR, message, 1);
+
+ return (-1);
}
# elif defined(HAVE_GNUTLS)
malloc(sizeof(gnutls_certificate_client_credentials));
if (credentials == NULL)
{
- http->error = errno;
+ DEBUG_printf(("8http_setup_ssl: Unable to allocate credentials: %s",
+ strerror(errno)));
+ http->error = errno;
http->status = HTTP_ERROR;
+ _cupsSetHTTPError(HTTP_ERROR);
return (-1);
}
gnutls_init(&http->tls, GNUTLS_CLIENT);
gnutls_set_default_priority(http->tls);
+ gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, http->hostname, strlen(http->hostname));
gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials);
gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr)http);
gnutls_transport_set_pull_function(http->tls, _httpReadGNUTLS);
gnutls_transport_set_push_function(http->tls, _httpWriteGNUTLS);
- if ((gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS)
+ while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS)
{
- http->error = errno;
- http->status = HTTP_ERROR;
+ DEBUG_printf(("8http_setup_ssl: gnutls_handshake returned %d (%s)",
+ status, gnutls_strerror(status)));
- gnutls_deinit(http->tls);
- gnutls_certificate_free_credentials(*credentials);
- free(credentials);
- http->tls = NULL;
+ if (gnutls_error_is_fatal(status))
+ {
+ http->error = EIO;
+ http->status = HTTP_ERROR;
- return (-1);
+ _cupsSetError(IPP_PKI_ERROR, gnutls_strerror(status), 0);
+
+ gnutls_deinit(http->tls);
+ gnutls_certificate_free_credentials(*credentials);
+ free(credentials);
+ http->tls = NULL;
+
+ return (-1);
+ }
}
http->tls_credentials = credentials;
# elif defined(HAVE_CDSASSL)
if ((error = SSLNewContext(false, &http->tls)))
{
- http->error = error;
+ http->error = errno;
http->status = HTTP_ERROR;
+ _cupsSetHTTPError(HTTP_ERROR);
return (-1);
}
DEBUG_printf(("4http_setup_ssl: SSLSetIOFuncs, error=%d", (int)error));
}
- if (!error)
- {
- error = SSLSetProtocolVersionEnabled(http->tls, kSSLProtocol2, false);
- DEBUG_printf(("4http_setup_ssl: SSLSetProtocolVersionEnabled, error=%d",
- (int)error));
- }
-
if (!error)
{
error = SSLSetAllowsAnyRoot(http->tls, any_root);
http->tls = _sspiAlloc();
if (!http->tls)
+ {
return (-1);
http->tls->sock = http->fd;
{
_sspiFree(http->tls_credentials);
http->tls_credentials = NULL;
+
+ http->error = EIO;
+ http->status = HTTP_ERROR;
+
+ _cupsSetError(IPP_PKI_ERROR,
+ _("Unable to establish a secure connection to host."), 1);
+
return (-1);
}
{
_sspiFree(http->tls_credentials);
http->tls_credentials = NULL;
+
+ http->error = EIO;
+ http->status = HTTP_ERROR;
+
+ _cupsSetError(IPP_PKI_ERROR,
+ _("Unable to establish a secure connection to host."), 1);
+
return (-1);
}
# endif /* HAVE_CDSASSL */
# ifdef HAVE_LIBSSL
SSL_CTX *context; /* Context for encryption */
- context = SSL_get_SSL_CTX(http->tls_credentials);
+ context = SSL_get_SSL_CTX(http->tls);
- SSL_shutdown(http->tls_credentials);
+ SSL_shutdown(http->tls);
SSL_CTX_free(context);
- SSL_free(http->tls_credentials);
+ SSL_free(http->tls);
# elif defined(HAVE_GNUTLS)
gnutls_certificate_client_credentials *credentials;