Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Denial of Service in SSL negotiation #2091

Closed
michaelrsweet opened this issue Nov 10, 2006 · 10 comments
Closed

Denial of Service in SSL negotiation #2091

michaelrsweet opened this issue Nov 10, 2006 · 10 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 1.2.2
CUPS.org User: nathanw

(This is marked operating-system specific because it's only tested on FreeBSD 6.1, but I see no reason it shouldn't apply to other operating systems)

In encrypt_client(), SSL_accept() is called on a blocking socket. If nothing further occurs, the scheduler hangs until the socket is closed. (This also happens with GnuTLS) As a result, if you open a connection to the server on a port where SSL auto-detection is attempted, and the first character transmitted is anything not in "DGHOPT", the scheduler will hang waiting for SSL initialization until the socket is closed.

To reproduce this, one can do the following:
$ nc server 443
g

Until the connection is closed, no other requests will be served and the listen queue will grow without bound. I've been seeing this happen at random for the past few weeks on my server (presumably from port scanners), and it brings CUPS to a screeching halt until I reset it by hand.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: nathanw

I also wanted to note that this occurs in CUPS 1.1.23 if you connect on an SSL port (where sending any single byte at all causes the connection to hang), so it's really an issue in the SSL initiation code, not the auto-detection logic. CUPS 1.2's SSL auto-detection (and automatic enabling of SSL) just provides more ports on which this can happen.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: nathanw

I've also verified this behavior with CUPS 1.2.4 on the current release of Ubuntu Linux, so this appears to affect all versions of CUPS on all operating systems.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Thanks for the report. I'm not sure how we are going to address this issue - I need to do some research on the GNU TLS and OpenSSL libraries to see if they support a timeout mechanism. If not, we'll have to change the wrapping of the transport stuff to do the timeouts for us.

I'll also check with Apple to see if CDSA is similarly affected.

Unfortunately, we can't know how much data is required outside of those libraries, and using non-blocking mode on the socket will just cause a quick failure... :(

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Try the attached patch; it sets the OpenSSL timeout parameter and adds pull/push functions for GNU TLS to provide a 10-second timeout for SSL reads.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: nathanw

The patch causes cupsd to segfault on connect. I tried reducing it to just adding the SSL_set_timeout() command in client.c, and adding or removing that line causes the crash (I haven't tried it with GnuTLS -- I'll give that a shot later). Here's the backtrace:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x557000 (LWP 100615)]
0x00000008009a9e6a in sk_find () from /lib/libcrypto.so.4
(gdb) bt
#0 0x00000008009a9e6a in sk_find () from /lib/libcrypto.so.4
#1 0x00000008007afa41 in ssl3_choose_cipher () from /usr/lib/libssl.so.4
#2 0x00000008007a66a7 in ssl3_accept () from /usr/lib/libssl.so.4
#3 0x00000008007a1c36 in ssl23_get_client_hello () from /usr/lib/libssl.so.4
#4 0x00000008007a24fd in ssl23_accept () from /usr/lib/libssl.so.4
#5 0x000000000040e1be in encrypt_client (con=0x598000) at client.c:2559
#6 0x000000000040f74a in cupsdReadClient (con=0x598000) at client.c:732
#7 0x000000000041ba98 in main (argc=5589504, argv=0xffffffff) at main.c:901

This patch, while it would solve my problem of accidental DoS attacks, seems like it would still allow a malicious attacker to retry at 10 second intervals.

Is it possible to put the SSL BIO into non-blocking mode just for the duration of encrypt_client(), then try to leave the socket in whatever state it was in case of an error indicating it needs more data? We still have the problem that an attacker could trigger an in-session renegotiation, then leave it hanging, which would make SSL_read() block somewhere else in the daemon, but it at least would make this problem harder to trigger.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Basically, the current OpenSSL code for timeouts is completely broken, and the SSL_set_timeout was mapping to SSL_SESSION_set_timeout without getting the session pointer associated with the SSL structure, so in the end it clobbered some of the SSL structure data... :(

We can't use non-blocking sockets because the corresponding interfaces are not 100% state-driven, so there is no way to do an async negotiation, etc. without erroring out due to even a tiny break in the data.

As for the 10-second timeout, this is also used for HTTP and IPP partial-read timeouts, and there really isn't anything we can do to avoid it. The key is that a 10 second timeout prevents a complete DoS, and the admin can quickly determine where the attack is coming from and respond accordingly. FWIW, 10 seconds is a compromise between "safety" and support for slow links - the timeout used to be 1 second but didn't work well over WAN links...

See the attached patch (you need to apply both patches) which implements OpenSSL BIO methods layered on top of the http_t interface. I've tested this on FC5 - let me know how things work on your systems.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

and here is a patch for the CDSA code...

@michaelrsweet
Copy link
Collaborator Author

"str2091.patch":

Index: cups/http.c

--- cups/http.c (revision 6078)
+++ cups/http.c (working copy)
@@ -60,7 +60,8 @@

  • httpPut() - Send a PUT request to the server.

  • httpRead() - Read data from a HTTP connection.

  • httpRead2() - Read data from a HTTP connection.

  • * _httpReadCDSA() - Read function for CDSA decryption code.

  • * _httpReadCDSA() - Read function for the CDSA library.

  • * _httpReadGNUTLS() - Read function for the GNU TLS library.

  • httpReconnect() - Reconnect to a HTTP server...

  • httpSetCookie() - Set the cookie value(s)...

  • httpSetExpect() - Set the Expect: header in a request.
    @@ -71,7 +72,8 @@

  • httpWait() - Wait for data available on a connection.

  • httpWrite() - Write data to a HTTP connection.

  • httpWrite2() - Write data to a HTTP connection.

  • * _httpWriteCDSA() - Write function for CDSA encryption code.

  • * _httpWriteCDSA() - Write function for the CDSA library.

  • * _httpWriteGNUTLS() - Write function for the GNU TLS library.

  • http_field() - Return the field index for a field name.

  • http_read_ssl() - Read from a SSL/TLS connection.

  • http_send() - Send a request with all fields and the trailing
    @@ -118,7 +120,7 @@
    static http_field_t http_field(const char *name);
    static int http_send(http_t *http, http_state_t request,
    const char *uri);
    -static int http_wait(http_t *http, int msec);
    +static int http_wait(http_t *http, int msec, int usessl);
    static int http_write(http_t *http, const char *buffer,
    int length);
    static int http_write_chunk(http_t *http, const char *buffer,
    @@ -869,7 +871,7 @@

  • No newline; see if there is more data to be read...
    */

  •  if (!http->blocking && !http_wait(http, 10000))
    
  •  if (!http->blocking && !http_wait(http, 10000, 1))
    

    {
    DEBUG_puts("httpGets: Timed out!");
    http->error = ETIMEDOUT;
    @@ -1391,7 +1393,7 @@

    #if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
    /*

  • * '_httpReadCDSA()' - Read function for CDSA decryption code.

    • '_httpReadCDSA()' - Read function for the CDSA library.
      */

    OSStatus /* O - -1 on error, 0 on success /
    @@ -1435,7 +1437,41 @@
    #endif /
    HAVE_SSL && HAVE_CDSASSL */

+#if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
/*

  • * '_httpReadGNUTLS()' - Read function for the GNU TLS library.
  • /
    +
    +ssize_t /
    O - Number of bytes read or -1 on error */
    +_httpReadGNUTLS(
  • gnutls_transport_ptr ptr, /* I - HTTP connection */
  • void data, / I - Buffer */
  • size_t length) /* I - Number of bytes to read */
    +{
  • http_t http; / HTTP connection */
  • http = (http_t *)ptr;
  • if (!http->blocking)
  • {
  • /*
  • * Make sure we have data before we read...
  • */
  • if (!http_wait(http, 10000, 0))
  • {
  •  http->error = ETIMEDOUT;
    
  •  return (-1);
    
  • }
  • }
  • return (recv(http->fd, data, length, 0));
    +}
    +#endif /* HAVE_SSL && HAVE_GNUTLS _/

+/_

  • 'httpReconnect()' - Reconnect to a HTTP server.
    */

@@ -1830,7 +1866,7 @@

  • If not, check the SSL/TLS buffers and do a select() on the connection...
    */
  • return (http_wait(http, msec));
  • return (http_wait(http, msec, 1));
    }

@@ -1977,7 +2013,7 @@

#if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
/*

  • * '_httpWriteCDSA()' - Write function for CDSA encryption code.

    • '_httpWriteCDSA()' - Write function for the CDSA library.
      */

    OSStatus /* O - -1 on error, 0 on success /
    @@ -2019,7 +2055,23 @@
    #endif /
    HAVE_SSL && HAVE_CDSASSL */

+#if defined(HAVE_SSL) && defined(HAVE_GNUTLS)
/*

  • * '_httpWriteGNUTLS()' - Write function for the GNU TLS library.
  • /
    +
    +ssize_t /
    O - Number of bytes written or -1 on error */
    +_httpWriteGNUTLS(
  • gnutls_transport_ptr ptr, /* I - HTTP connection */
  • const void data, / I - Data buffer */
  • size_t length) /* I - Number of bytes to write */
    +{
  • return (send(((http_t )ptr)->fd, data, length, 0));
    +}
    +#endif /
    HAVE_SSL && HAVE_GNUTLS _/

+/_

  • 'http_field()' - Return the field index for a field name.
    */

@@ -2268,6 +2320,10 @@
conn = SSL_new(context);

SSL_set_fd(conn, http->fd);
+

  • if (!http->blocking)
  • SSL_set_timeout(conn, 10); /* 10-second data timeout */

if (SSL_connect(conn) != 1)
{

ifdef DEBUG

@@ -2316,8 +2372,9 @@
gnutls_init(&(conn->session), GNUTLS_CLIENT);
gnutls_set_default_priority(conn->session);
gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);

  • gnutls_transport_set_ptr(conn->session,
  •                       (gnutls_transport_ptr)((long)http->fd));
    
  • gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)http);
  • gnutls_transport_set_pull_function(conn->session, _httpReadGNUTLS);
  • gnutls_transport_set_push_function(conn->session, _httpWriteGNUTLS);

if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
{
@@ -2544,7 +2601,8 @@

static int /* O - 1 if data is available, 0 otherwise /
http_wait(http_t *http, /
I - HTTP connection */

  •      int    msec)         /\* I - Milliseconds to wait */
    
  •      int    msec,         /\* I - Milliseconds to wait */
    
  • int    usessl)        /* I - Use SSL context? */
    

    {
    #ifndef WIN32
    struct rlimit limit; /* Runtime limit */
    @@ -2564,7 +2622,7 @@
    */

    #ifdef HAVE_SSL

  • if (http->tls)

  • if (http->tls && usessl)
    {

ifdef HAVE_LIBSSL

 if (SSL_pending((SSL _)(http->tls)))

Index: cups/http-private.h

--- cups/http-private.h (revision 6078)
+++ cups/http-private.h (working copy)
@@ -91,6 +91,11 @@
void *credentials; /_ GNU TLS credentials object */
} http_tls_t;

+extern ssize_t _httpReadGNUTLS(gnutls_transport_ptr ptr, void *data,

  •                   size_t length);
    

    +extern ssize_t _httpWriteGNUTLS(gnutls_transport_ptr ptr, const void *data,

  •                    size_t length);
    

    elif defined(HAVE_CDSASSL)

    /*

    • Darwin's Security framework provides its own SSL/TLS context structure

      Index: scheduler/client.c

      --- scheduler/client.c (revision 6078)
      +++ scheduler/client.c (working copy)
      @@ -426,7 +426,8 @@

      con->http.encryption = HTTP_ENCRYPT_ALWAYS;

  • encrypt_client(con);

  • if (!encrypt_client(con))

  •  cupsdCloseClient(con);
    

    }
    else
    con->auto_ssl = 1;
    @@ -745,7 +746,9 @@
    "cupsdReadClient: Saw first byte %02X, auto-negotiating SSL/TLS session...",
    buf[0] & 255);

  •  encrypt_client(con);
    
  •  if (!encrypt_client(con))
    
  •    return (cupsdCloseClient(con));
    
    • return (1);
      }
      }
      @@ -1056,7 +1059,8 @@
      if (cupsdFlushHeader(con) < 0)
      return (cupsdCloseClient(con));
  •    encrypt_client(con);
    
  •    if (!encrypt_client(con))
    
  • return (cupsdCloseClient(con));
    

    #else
    if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED))
    return (cupsdCloseClient(con));
    @@ -1103,7 +1107,8 @@
    if (cupsdFlushHeader(con) < 0)
    return (cupsdCloseClient(con));

  •    encrypt_client(con);
    
  •    if (!encrypt_client(con))
    
  • return (cupsdCloseClient(con));
    

    #else
    if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED))
    return (cupsdCloseClient(con));
    @@ -2617,6 +2622,8 @@
    conn = SSL_new(context);

    SSL_set_fd(conn, con->http.fd);

  • SSL_set_timeout(conn, 10); /* 10-second data timeout */

if (SSL_accept(conn) != 1)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -2689,8 +2696,9 @@
gnutls_init(&(conn->session), GNUTLS_SERVER);
gnutls_set_default_priority(conn->session);
gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);

  • gnutls_transport_set_ptr(conn->session,
  •                       (gnutls_transport_ptr)((long)con->http.fd));
    
  • gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)HTTP(con));
  • gnutls_transport_set_pull_function(conn->session, _httpReadGNUTLS);
  • gnutls_transport_set_push_function(conn->session, _httpWriteGNUTLS);

error = gnutls_handshake(conn->session);

@@ -2743,7 +2751,7 @@
if (!conn->certsArray)
{
cupsdLogMessage(CUPSD_LOG_ERROR,

  •           "EncryptClient: Could not find signing key in keychain "
    
  •           "encrypt_client: Could not find signing key in keychain "
        "\"%s\"", ServerCertificate);
    
    error = errSSLBadCert; /* errSSLBadConfiguration is a better choice, but not available on 10.2.x */
    }

@michaelrsweet
Copy link
Collaborator Author

"str2091p2.patch":

Index: cups/http.c

--- cups/http.c (revision 6080)
+++ cups/http.c (working copy)
@@ -25,6 +25,7 @@
*

  • Contents:
    *
    • * _httpBIOMethods() - Get the OpenSSL BIO methods for HTTP connections.
  • httpBlocking() - Set blocking/non-blocking behavior on a connection.
  • httpCheck() - Check to see if there is a pending response from
  •                      the server.
    
    @@ -74,6 +75,12 @@
  • httpWrite2() - Write data to a HTTP connection.
  • _httpWriteCDSA() - Write function for the CDSA library.
  • _httpWriteGNUTLS() - Write function for the GNU TLS library.
  • * http_bio_ctrl() - Control the HTTP connection.
  • * http_bio_free() - Free OpenSSL data.
  • * http_bio_new() - Initialize an OpenSSL BIO structure.
  • * http_bio_puts() - Send a string for OpenSSL.
  • * http_bio_read() - Read data for OpenSSL.
  • * http_bio_write() - Write data for OpenSSL.
  • http_field() - Return the field index for a field name.
  • http_read_ssl() - Read from a SSL/TLS connection.
  • http_send() - Send a request with all fields and the trailing
    @@ -170,7 +177,46 @@
    };

+#if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
/*

  • * BIO methods for OpenSSL...
  • */
    +
    +static int http_bio_write(BIO *h, const char *buf, int num);
    +static int http_bio_read(BIO *h, char *buf, int size);
    +static int http_bio_puts(BIO *h, const char *str);
    +static long http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
    +static int http_bio_new(BIO *h);
    +static int http_bio_free(BIO *data);
    +
    +static BIO_METHOD http_bio_methods =
  •       {
    
  •         BIO_TYPE_SOCKET,
    
  •         "http",
    
  •         http_bio_write,
    
  •         http_bio_read,
    
  •         http_bio_puts,
    
  •         NULL, /\* http_bio_gets, */
    
  •         http_bio_ctrl,
    
  •         http_bio_new,
    
  •         http_bio_free,
    
  •         NULL,
    
  •       };
    
    +/*
  • * '_httpBIOMethods()' - Get the OpenSSL BIO methods for HTTP connections.
  • /
    +
    +BIO_METHOD * /
    O - BIO methods for OpenSSL */
    +_httpBIOMethods(void)
    +{
  • return (&http_bio_methods);
    +}
    +#endif /* HAVE_SSL && HAVE_LIBSSL _/

+/_

  • 'httpBlocking()' - Set blocking/non-blocking behavior on a connection.
    */

@@ -2071,7 +2117,144 @@
#endif /* HAVE_SSL && HAVE_GNUTLS */

+#if defined(HAVE_SSL) && defined(HAVE_LIBSSL)
/*

  • * 'http_bio_ctrl()' - Control the HTTP connection.
  • /
    +
    +static long /
    O - Result/data /
    +http_bio_ctrl(BIO *h, /
    I - BIO data */
  •          int  cmd,            /\* I - Control command */
    
  •     long arg1,        /\* I - First argument */
    
  •     void _arg2)       /_ I - Second argument */
    
    +{
  • switch (cmd)
  • {
  • default :
  •    return (0);
    
  • case BIO_CTRL_RESET :
  •    h->ptr = NULL;
    
  • return (0);
  • case BIO_C_SET_FILE_PTR :
  •    h->ptr  = arg2;
    
  • h->init = 1;
  • return (1);
  • case BIO_C_GET_FILE_PTR :
  •    if (arg2)
    
  • {
  • _((void *_)arg2) = h->ptr;
    
  • return (1);
    
  • }
  • else
  • return (0);
    
  • case BIO_CTRL_DUP :
  • case BIO_CTRL_FLUSH :
  •    return (1);
    
  • }
    +}

+/*

  • * 'http_bio_free()' - Free OpenSSL data.
  • /
    +
    +static int /
    O - 1 on success, 0 on failure /
    +http_bio_free(BIO *h) /
    I - BIO data */
    +{
  • if (!h)
  • return (0);
  • if (h->shutdown)
  • {
  • h->init = 0;
  • h->flags = 0;
  • }
  • return (1);
    +}

+/*

  • * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
  • /
    +
    +static int /
    O - 1 on success, 0 on failure /
    +http_bio_new(BIO *h) /
    I - BIO data */
    +{
  • if (!h)
  • return (0);
  • h->init = 0;
  • h->num = 0;
  • h->ptr = NULL;
  • h->flags = 0;
  • return (1);
    +}

+/*

  • * 'http_bio_puts()' - Send a string for OpenSSL.
  • /
    +
    +static int /
    O - Bytes written /
    +http_bio_puts(BIO *h, /
    I - BIO data */
  •          const char _str)     /_ I - String to write */
    
    +{
  • return (send(((http_t _)h->ptr)->fd, str, strlen(str), 0));
    +}

+/_

  • * 'http_bio_read()' - Read data for OpenSSL.
  • /
    +
    +static int /
    O - Bytes read /
    +http_bio_read(BIO *h, /
    I - BIO data */
  •          char _buf,       /_ I - Buffer */
    
  •     int  size)        /\* I - Number of bytes to read */
    
    +{
  • http_t http; / HTTP connection */
  • http = (http_t *)h->ptr;
  • if (!http->blocking)
  • {
  • /*
  • * Make sure we have data before we read...
  • */
  • if (!http_wait(http, 10000, 0))
  • {
  •  http->error = ETIMEDOUT;
    
  •  return (-1);
    
  • }
  • }
  • return (recv(http->fd, buf, size, 0));
    +}

+/*

  • * 'http_bio_write()' - Write data for OpenSSL.
  • /
    +
    +static int /
    O - Bytes written /
    +http_bio_write(BIO *h, /
    I - BIO data */
  •           const char _buf,        /_ I - Buffer to write */
    
  •      int        num)      /\* I - Number of bytes to write */
    
    +{
  • return (send(((http_t )h->ptr)->fd, buf, num, 0));
    +}
    +#endif /
    HAVE_SSL && HAVE_LIBSSL _/

+/_

  • 'http_field()' - Return the field index for a field name.
    */

@@ -2299,6 +2482,7 @@

ifdef HAVE_LIBSSL

SSL_CTX context; / Context for encryption /
SSL *conn; /
Connection for encryption */

  • BIO bio; / BIO data */

elif defined(HAVE_GNUTLS)

http_tls_t conn; / TLS session object */
gnutls_certificate_client_credentials *credentials;
@@ -2317,13 +2501,12 @@

SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */

  • bio = BIO_new(_httpBIOMethods());
  • BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);

conn = SSL_new(context);

  • SSL_set_bio(conn, bio, bio);

- SSL_set_fd(conn, http->fd);

  • if (!http->blocking)

- SSL_set_timeout(conn, 10); /* 10-second data timeout */

if (SSL_connect(conn) != 1)
{

ifdef DEBUG

Index: cups/http-private.h

--- cups/http-private.h (revision 6080)
+++ cups/http-private.h (working copy)
@@ -70,7 +70,8 @@

if defined HAVE_LIBSSL

/*

  • The OpenSSL library provides its own SSL/TLS context structure for its

    • * IO and protocol management...
    • * IO and protocol management. However, we need to provide our own BIO
    • * (basic IO) implementation to do timeouts...
      */

    include <openssl/err.h>

    @@ -79,6 +80,8 @@

    typedef SSL http_tls_t;

+extern BIO_METHOD __httpBIOMethods(void);
+

elif defined HAVE_GNUTLS

/_

  • The GNU TLS library is more of a "bare metal" SSL/TLS library...
    Index: scheduler/client.c

    --- scheduler/client.c (revision 6080)
    +++ scheduler/client.c (working copy)
    @@ -2592,6 +2592,7 @@

    ifdef HAVE_LIBSSL

    SSL_CTX context; / Context for encryption /
    SSL *conn; /
    Connection for encryption */
    • BIO bio; / BIO data /
      unsigned long error; /
      Error code */

@@ -2619,11 +2620,12 @@
SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM);
SSL_CTX_use_certificate_file(context, ServerCertificate, SSL_FILETYPE_PEM);

  • bio = BIO_new(_httpBIOMethods());
  • BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)HTTP(con));

conn = SSL_new(context);

  • SSL_set_bio(conn, bio, bio);
  • SSL_set_fd(conn, con->http.fd);

- SSL_set_timeout(conn, 10); /* 10-second data timeout */

if (SSL_accept(conn) != 1)
{
cupsdLogMessage(CUPSD_LOG_ERROR,

@michaelrsweet
Copy link
Collaborator Author

"str2091p3.patch":

Index: cups/http.c

--- cups/http.c (revision 6107)
+++ cups/http.c (working copy)
@@ -1492,19 +1492,36 @@
void data, / I - Data buffer /
size_t *dataLength) /
IO - Number of bytes */
{

  • OSStatus result; /* Return value */
  • ssize_t bytes; /* Number of bytes read */
  • cdsa_conn_ref_t u; /* Connection reference union */
  • OSStatus result; /* Return value */
  • ssize_t bytes; /* Number of bytes read */
  • http_t http; / HTTP connection */
  • u.connection = connection;
  • http = (http_t *)connection;
  • if (!http->blocking)
  • {
  • /*
  • * Make sure we have data before we read...
  • */
  • if (!http_wait(http, 10000, 0))
  • {
  •  http->error = ETIMEDOUT;
    
  •  return (-1);
    
  • }
  • }

do

  • bytes = recv(u.sock, data, *dataLength, 0);
  • {
  • bytes = recv(http->fd, data, *dataLength, 0);
  • }
    while (bytes == -1 && errno == EINTR);

if (bytes == *dataLength)

  • {
    result = 0;
  • }
    else if (bytes > 0)
    {
    *dataLength = bytes;
    @@ -1522,7 +1539,7 @@
    result = errSSLClosedAbort;
    }
  • return result;
  • return (result);
    }
    #endif /* HAVE_SSL && HAVE_CDSASSL */

@@ -2125,19 +2142,23 @@
const void data, / I - Data buffer /
size_t *dataLength) /
IO - Number of bytes */
{

  • OSStatus result; /* Return value */
  • ssize_t bytes; /* Number of bytes read */
  • cdsa_conn_ref_t u; /* Connection reference union */
  • OSStatus result; /* Return value */
  • ssize_t bytes; /* Number of bytes read */
  • http_t http; / HTTP connection */
  • u.connection = connection;
  • http = (http_t *)connection;

do

  • bytes = write(u.sock, data, *dataLength);
  • {
  • bytes = write(http->fd, data, *dataLength);
  • }
    while (bytes == -1 && errno == EINTR);

if (bytes == *dataLength)

  • {
    result = 0;
  • }
    else if (bytes >= 0)
    {
    *dataLength = bytes;
    @@ -2153,7 +2174,7 @@
    result = errSSLClosedAbort;
    }
  • return result;
  • return (result);
    }
    #endif /* HAVE_SSL && HAVE_CDSASSL */

@@ -2562,7 +2583,6 @@

elif defined(HAVE_CDSASSL)

OSStatus error; /* Error code /
http_tls_t *conn; /
CDSA connection information */

  • cdsa_conn_ref_t u; /* Connection reference union _/

endif /_ HAVE_LIBSSL */

@@ -2660,9 +2680,7 @@

  • Use a union to resolve warnings about int/pointer size mismatches...
    */
  • u.connection = NULL;
  • u.sock = http->fd;
  • error = SSLSetConnection(conn->session, u.connection);
  • error = SSLSetConnection(conn->session, http);

if (!error)
error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);

Index: cups/http-private.h

--- cups/http-private.h (revision 6107)
+++ cups/http-private.h (working copy)
@@ -132,15 +132,6 @@
CFArrayRef certsArray; /* Certificates array */
} http_tls_t;

-typedef union _cdsa_conn_ref_u /**** CDSA Connection reference union

  •                ***\* used to resolve 64-bit casting
    
  •                ***\* warnings.
    
  •                ****/
    
    -{
  • SSLConnectionRef connection; /* SSL connection pointer */
  • int sock; /* Socket _/
    -} cdsa_conn_ref_t;

extern OSStatus _httpReadCDSA(SSLConnectionRef connection, void *data,
size_t *dataLength);
extern OSStatus _httpWriteCDSA(SSLConnectionRef connection, const void *data,
Index: scheduler/client.c

--- scheduler/client.c (revision 6107)
+++ scheduler/client.c (working copy)
@@ -2767,7 +2767,6 @@

elif defined(HAVE_CDSASSL)

OSStatus error; /_ Error code /
http_tls_t *conn; /
CDSA connection information */

  • cdsa_conn_ref_t u; /* Connection reference union */

if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
@@ -2805,16 +2804,8 @@
error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false);

if (!error)

  • {
  • /*
  • * Use a union to resolve warnings about int/pointer size mismatches...
  • */
  • error = SSLSetConnection(conn->session, HTTP(con));
  • u.connection = NULL;
  • u.sock = con->http.fd;
  • error = SSLSetConnection(conn->session, u.connection);

- }

if (!error)
error = SSLSetAllowsExpiredCerts(conn->session, true);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant