]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/http.c
Merge changes from CUPS 1.6svn-r9939.
[thirdparty/cups.git] / cups / http.c
index 037efd32e45477ab1347a61268f1e2207f2be33b..8aab65a1d7c6487ccecf6f77aeca5e6747e53bc3 100644 (file)
@@ -2186,7 +2186,10 @@ _httpReadGNUTLS(
     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;
 
@@ -2206,7 +2209,9 @@ _httpReadGNUTLS(
     }
   }
 
-  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 */
 
@@ -3189,7 +3194,16 @@ _httpWriteGNUTLS(
     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 */
 
@@ -3760,7 +3774,7 @@ http_set_credentials(http_t *http)        /* I - Connection to server */
  * '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();
@@ -3768,29 +3782,30 @@ http_setup_ssl(http_t *http)            /* I - Connection to server */
   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 */
 
 
@@ -3806,6 +3821,8 @@ http_setup_ssl(http_t *http)              /* I - Connection to server */
     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 */
@@ -3814,16 +3831,17 @@ http_setup_ssl(http_t *http)            /* I - Connection to server */
   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);
@@ -3836,7 +3854,12 @@ http_setup_ssl(http_t *http)             /* I - Connection to server */
 #    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)
@@ -3844,8 +3867,11 @@ http_setup_ssl(http_t *http)             /* I - Connection to server */
                     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);
   }
@@ -3854,22 +3880,31 @@ http_setup_ssl(http_t *http)            /* I - Connection to server */
 
   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;
@@ -3877,8 +3912,9 @@ http_setup_ssl(http_t *http)              /* I - Connection to server */
 #  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);
   }
@@ -3892,13 +3928,6 @@ http_setup_ssl(http_t *http)             /* I - Connection to server */
     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);
@@ -4130,6 +4159,7 @@ http_setup_ssl(http_t *http)              /* I - Connection to server */
   http->tls = _sspiAlloc();
 
   if (!http->tls)
+  {
     return (-1);
 
   http->tls->sock = http->fd;
@@ -4143,6 +4173,13 @@ http_setup_ssl(http_t *http)             /* I - Connection to server */
   {
     _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);
   }
 
@@ -4153,6 +4190,13 @@ http_setup_ssl(http_t *http)             /* I - Connection to server */
   {
     _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 */
@@ -4173,11 +4217,11 @@ http_shutdown_ssl(http_t *http)         /* I - Connection to server */
 #  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;