From b3461bab1df4221abf74d7c159cf5c719b1b9744 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Jul 2007 21:46:26 +0000 Subject: Implemented the parts of Patrick Monnerat's OS/400 patch that introduces support for the OS/400 Secure Sockets Layer library --- lib/Makefile.inc | 28 ++-- lib/qssl.c | 496 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/qssl.h | 52 ++++++ lib/sslgen.c | 70 ++++++++ 4 files changed, 632 insertions(+), 14 deletions(-) create mode 100644 lib/qssl.c create mode 100644 lib/qssl.h (limited to 'lib') diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 714b15f8a..759c923d5 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -1,23 +1,23 @@ # ./lib/Makefile.inc - + CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \ ldap.c ssluse.c version.c getenv.c escape.c mprintf.c telnet.c \ netrc.c getinfo.c transfer.c strequal.c easy.c security.c krb4.c \ - krb5.c \ - memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c multi.c \ - content_encoding.c share.c http_digest.c md5.c http_negotiate.c \ - http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \ - hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \ - select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c nss.c + krb5.c memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c \ + multi.c content_encoding.c share.c http_digest.c md5.c \ + http_negotiate.c http_ntlm.c inet_pton.c strtoofft.c strerror.c \ + hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \ + inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \ + strdup.c socks.c ssh.c nss.c qssl.c HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \ progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \ if2ip.h speedcheck.h urldata.h ldap.h ssluse.h escape.h telnet.h \ - getinfo.h strequal.h krb4.h memdebug.h inet_ntoa_r.h \ - http_chunks.h strtok.h connect.h llist.h hash.h content_encoding.h \ - share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \ - inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \ - setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \ - gtls.h tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h \ - nssg.h + getinfo.h strequal.h krb4.h memdebug.h inet_ntoa_r.h http_chunks.h \ + strtok.h connect.h llist.h hash.h content_encoding.h share.h md5.h \ + http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h inet_pton.h \ + strtoofft.h strerror.h inet_ntop.h curlx.h memory.h setup.h \ + transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h \ + tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \ + qssl.h diff --git a/lib/qssl.c b/lib/qssl.c new file mode 100644 index 000000000..9e2aee767 --- /dev/null +++ b/lib/qssl.c @@ -0,0 +1,496 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + ***************************************************************************/ + +#include "setup.h" + +#ifdef USE_QSOSSL +#include +#include +#include + +#include +#include "urldata.h" +#include "sendf.h" +#include "qssl.h" +#include "sslgen.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + + +static bool qsossl_inited = FALSE; + + +int Curl_qsossl_init(void) + +{ + /* Nothing to do here. We must have connection data to initialize ssl, so + * defer. + */ + + return 1; +} + + +void Curl_qsossl_cleanup(void) + +{ + /* Nothing to do. */ +} + + +static CURLcode Curl_qsossl_init_session(struct SessionHandle * data) + +{ + int rc; + char * certname; + SSLInit initstr; + SSLInitApp initappstr; + + /* Initialize the job for SSL according to the current parameters. + * QsoSSL offers two ways to do it: SSL_Init_Application() that uses an + * application identifier to select certificates in the main certificate + * store, and SSL_Init() that uses named keyring files and a password. + * It is not possible to have different keyrings for the CAs and the + * local certificate. We thus use the certificate name to identify the + * keyring if given, else the CA file name. + * If the key file name is given, it is taken as the password for the + * keyring in certificate file. + * We first try to SSL_Init_Application(), then SSL_Init() if it failed. + */ + + certname = data->set.cert; + + if (!certname) { + certname = data->set.ssl.CAfile; + + if (!certname) + return CURLE_OK; /* Use previous setup. */ + } + + memset((char *) &initappstr, 0, sizeof initappstr); + initappstr.applicationID = certname; + initappstr.applicationIDLen = strlen(certname); + initappstr.protocol = SSL_VERSION_CURRENT; + initappstr.sessionType = SSL_REGISTERED_AS_CLIENT; + rc = SSL_Init_Application(&initappstr); + + if (rc == SSL_ERROR_NOT_REGISTERED) { + initstr.keyringFileName = certname; + initstr.keyringPassword = data->set.key; + initstr.cipherSuiteList = NULL; /* Use default. */ + initstr.cipherSuiteListLen = 0; + rc = SSL_Init(&initstr); + } + + switch (rc) { + + case 0: /* No error. */ + break; + + case SSL_ERROR_IO: + failf(data, "SSL_Init() I/O error: %s\n", strerror(errno)); + return CURLE_SSL_CONNECT_ERROR; + + case SSL_ERROR_BAD_CIPHER_SUITE: + return CURLE_SSL_CIPHER; + + case SSL_ERROR_KEYPASSWORD_EXPIRED: + case SSL_ERROR_NOT_REGISTERED: + return CURLE_SSL_CONNECT_ERROR; + + case SSL_ERROR_NO_KEYRING: + return CURLE_SSL_CACERT; + + case SSL_ERROR_CERT_EXPIRED: + return CURLE_SSL_CERTPROBLEM; + + default: + failf(data, "SSL_Init(): %s\n", SSL_Strerror(rc, NULL)); + return CURLE_SSL_CONNECT_ERROR; + } + + return CURLE_OK; +} + + +static CURLcode Curl_qsossl_create(struct connectdata * conn, int sockindex) + +{ + SSLHandle * h; + struct ssl_connect_data * connssl = &conn->ssl[sockindex]; + + h = SSL_Create(conn->sock[sockindex], SSL_ENCRYPT); + + if (!h) { + failf(conn->data, "SSL_Create() I/O error: %s\n", strerror(errno)); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->handle = h; + return CURLE_OK; +} + + +static int Curl_qsossl_trap_cert(SSLHandle * h) + +{ + return 1; /* Accept certificate. */ +} + + +static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex) + +{ + int rc; + struct SessionHandle * data = conn->data; + struct ssl_connect_data * connssl = &conn->ssl[sockindex]; + SSLHandle * h = connssl->handle; + long timeout_ms; + + h->exitPgm = NULL; + + if (!data->set.ssl.verifyhost) + h->exitPgm = Curl_qsossl_trap_cert; + + if (data->set.connecttimeout) { + timeout_ms = data->set.connecttimeout; + + if (data->set.timeout) + if (timeout_ms > data->set.timeout) + timeout_ms = data->set.timeout; + } + else if (data->set.timeout) + timeout_ms = data->set.timeout; + else + timeout_ms = DEFAULT_CONNECT_TIMEOUT; + + /* SSL_Handshake() timeout resolution is second, so round up. */ + + h->timeout = (timeout_ms + 1000 - 1) / 1000; + + /* Set-up protocol. */ + + switch(data->set.ssl.version) { + + default: + case CURL_SSLVERSION_DEFAULT: + h->protocol = SSL_VERSION_CURRENT; + break; + + case CURL_SSLVERSION_TLSv1: + h->protocol = TLS_VERSION_1; + break; + + case CURL_SSLVERSION_SSLv2: + h->protocol = SSL_VERSION_2; + break; + + case CURL_SSLVERSION_SSLv3: + h->protocol = SSL_VERSION_3; + break; + } + + rc = SSL_Handshake(h, SSL_HANDSHAKE_AS_CLIENT); + + switch (rc) { + + case 0: /* No error. */ + break; + + case SSL_ERROR_BAD_CERTIFICATE: + case SSL_ERROR_BAD_CERT_SIG: + case SSL_ERROR_NOT_TRUSTED_ROOT: + return CURLE_SSL_PEER_CERTIFICATE; + + case SSL_ERROR_BAD_CIPHER_SUITE: + case SSL_ERROR_NO_CIPHERS: + return CURLE_SSL_CIPHER; + + case SSL_ERROR_CERTIFICATE_REJECTED: + case SSL_ERROR_CERT_EXPIRED: + case SSL_ERROR_NO_CERTIFICATE: + return CURLE_SSL_CERTPROBLEM; + + case SSL_ERROR_IO: + failf(data, "SSL_Handshake(): %s\n", SSL_Strerror(rc, NULL)); + return CURLE_SSL_CONNECT_ERROR; + + default: + failf(data, "SSL_Init(): %s\n", SSL_Strerror(rc, NULL)); + return CURLE_SSL_CONNECT_ERROR; + } + + return CURLE_OK; +} + + +CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex) + +{ + struct SessionHandle * data = conn->data; + struct ssl_connect_data * connssl = &conn->ssl[sockindex]; + int rc; + + rc = Curl_qsossl_init_session(data); + + if (rc == CURLE_OK) { + rc = Curl_qsossl_create(conn, sockindex); + + if (rc == CURLE_OK) + rc = Curl_qsossl_handshake(conn, sockindex); + else { + SSL_Destroy(connssl->handle); + connssl->handle = NULL; + connssl->use = FALSE; + } + } + + return rc; +} + + +static int Curl_qsossl_close_one(struct ssl_connect_data * conn, + struct SessionHandle * data) + +{ + int rc; + + if (!conn->handle) + return 0; + + rc = SSL_Destroy(conn->handle); + + if(rc) { + if (rc == SSL_ERROR_IO) { + failf(data, "SSL_Destroy() I/O error: %s\n", strerror(errno)); + return -1; + } + + /* An SSL error. */ + failf(data, "SSL_Destroy() returned error %d\n", SSL_Strerror(rc, NULL)); + return -1; + } + + conn->use = FALSE; /* get back to ordinary socket usage */ + conn->handle = NULL; + return 0; +} + + +void Curl_qsossl_close(struct connectdata * conn) + +{ + struct SessionHandle * data = conn->data; + struct ssl_connect_data * connssl = conn->ssl; + + if(connssl->use) + (void) Curl_qsossl_close_one(connssl, data); + + connssl++; + + if(connssl->use) + (void) Curl_qsossl_close_one(connssl, data); +} + + +int Curl_qsossl_close_all(struct SessionHandle * data) + +{ + /* Unimplemented. */ + (void) data; + return 0; +} + + +int Curl_qsossl_shutdown(struct connectdata * conn, int sockindex) + +{ + struct ssl_connect_data * connssl = &conn->ssl[sockindex]; + struct SessionHandle *data = conn->data; + ssize_t nread; + int what; + int rc; + char buf[120]; + + if (!connssl->handle) + return 0; + + if (data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) + return 0; + + if (Curl_qsossl_close_one(connssl, data)) + return -1; + + rc = 0; + + what = Curl_socket_ready(conn->sock[sockindex], + CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); + + for (;;) { + if (what < 0) { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + rc = -1; + break; + } + + if (!what) { /* timeout */ + failf(data, "SSL shutdown timeout"); + break; + } + + /* Something to read, let's do it and hope that it is the close + notify alert from the server. No way to SSL_Read now, so use read(). */ + + nread = read(conn->sock[sockindex], buf, sizeof(buf)); + + if (nread < 0) { + failf(data, "read: %s\n", strerror(errno)); + rc = -1; + } + + if (nread <= 0) + break; + + what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0); + } + + return rc; +} + + +ssize_t Curl_qsossl_send(struct connectdata * conn, int sockindex, void * mem, + size_t len) + +{ + /* SSL_Write() is said to return 'int' while write() and send() returns + 'size_t' */ + int rc; + + rc = SSL_Write(conn->ssl[sockindex].handle, mem, (int) len); + + if(rc < 0) { + switch(rc) { + + case SSL_ERROR_BAD_STATE: + /* The operation did not complete; the same SSL I/O function + should be called again later. This is basicly an EWOULDBLOCK + equivalent. */ + return 0; + + case SSL_ERROR_IO: + switch (errno) { + case EWOULDBLOCK: + case EINTR: + return 0; + } + + failf(conn->data, "SSL_Write() I/O error: %s\n", strerror(errno)); + return -1; + } + + /* An SSL error. */ + failf(conn->data, "SSL_Write() returned error %d\n", + SSL_Strerror(rc, NULL)); + return -1; + } + + return (ssize_t) rc; /* number of bytes */ +} + + +ssize_t Curl_qsossl_recv(struct connectdata * conn, int num, char * buf, + size_t buffersize, bool * wouldblock) + +{ + char error_buffer[120]; /* OpenSSL documents that this must be at + least 120 bytes long. */ + unsigned long sslerror; + int nread; + + nread = SSL_Read(conn->ssl[num].handle, buf, (int) buffersize); + *wouldblock = FALSE; + + if(nread < 0) { + /* failed SSL_read */ + + switch (nread) { + + case SSL_ERROR_BAD_STATE: + /* there's data pending, re-invoke SSL_Read(). */ + *wouldblock = TRUE; + return -1; /* basically EWOULDBLOCK */ + + case SSL_ERROR_IO: + switch (errno) { + case EWOULDBLOCK: + *wouldblock = TRUE; + return -1; + } + + failf(conn->data, "SSL_Read() I/O error: %s\n", strerror(errno)); + return -1; + + default: + failf(conn->data, "SSL read error: %s\n", SSL_Strerror(nread, NULL)); + return -1; + } + } + return (ssize_t) nread; +} + + +size_t Curl_qsossl_version(char * buffer, size_t size) + +{ + strncpy(buffer, "IBM OS/400 SSL", size); + return strlen(buffer); +} + + +int Curl_qsossl_check_cxn(struct connectdata * cxn) + +{ + int err; + int errlen; + + /* The only thing that can be tested here is at the socket level. */ + + if (!cxn->ssl[FIRSTSOCKET].handle) + return 0; /* connection has been closed */ + + err = 0; + errlen = sizeof err; + + if (getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR, + (unsigned char *) &err, &errlen) || + errlen != sizeof err || err) + return 0; /* connection has been closed */ + + return -1; /* connection status unknown */ +} + +#endif /* USE_QSOSSL */ diff --git a/lib/qssl.h b/lib/qssl.h new file mode 100644 index 000000000..61ff80adf --- /dev/null +++ b/lib/qssl.h @@ -0,0 +1,52 @@ +#ifndef __QSSL_H +#define __QSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + ***************************************************************************/ + +/* + * This header should only be needed to get included by sslgen.c and qssl.c + */ + +#include "urldata.h" + +int Curl_qsossl_init(void); +void Curl_qsossl_cleanup(void); +CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex); +void Curl_qsossl_close(struct connectdata * conn); /* close a SSL connection */ +int Curl_qsossl_close_all(struct SessionHandle * data); +int Curl_qsossl_shutdown(struct connectdata * conn, int sockindex); + +ssize_t Curl_qsossl_send(struct connectdata * conn, + int sockindex, + void * mem, + size_t len); +ssize_t Curl_qsossl_recv(struct connectdata * conn, /* connection data */ + int num, /* socketindex */ + char * buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + bool * wouldblock); + +size_t Curl_qsossl_version(char * buffer, size_t size); +int Curl_qsossl_check_cxn(struct connectdata * cxn); + +#endif diff --git a/lib/sslgen.c b/lib/sslgen.c index faabeeb0d..56f626ac2 100644 --- a/lib/sslgen.c +++ b/lib/sslgen.c @@ -52,6 +52,7 @@ #include "ssluse.h" /* OpenSSL versions */ #include "gtls.h" /* GnuTLS versions */ #include "nssg.h" /* NSS versions */ +#include "qssl.h" /* QSOSSL versions */ #include "sendf.h" #include "strequal.h" #include "url.h" @@ -171,9 +172,13 @@ int Curl_ssl_init(void) #else #ifdef USE_NSS return Curl_nss_init(); +#else +#ifdef USE_QSOSSL + return Curl_qsossl_init(); #else /* no SSL support */ return 1; +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -190,8 +195,13 @@ void Curl_ssl_cleanup(void) #else #ifdef USE_GNUTLS Curl_gtls_cleanup(); +#else #ifdef USE_NSS Curl_nss_cleanup(); +#else +#ifdef USE_QSOSSL + Curl_qsossl_cleanup(); +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -214,6 +224,10 @@ Curl_ssl_connect(struct connectdata *conn, int sockindex) #else #ifdef USE_NSS return Curl_nss_connect(conn, sockindex); +#else +#ifdef USE_QSOSSL + return Curl_qsossl_connect(conn, sockindex); +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -239,11 +253,16 @@ Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex, #ifdef USE_NSS *done = TRUE; /* fallback to BLOCKING */ return Curl_nss_connect(conn, sockindex); +#else +#ifdef USE_QSOSSL + *done = TRUE; /* fallback to BLOCKING */ + return Curl_qsossl_connect(conn, sockindex); #else /* not implemented! fallback to BLOCKING call. */ *done = TRUE; return Curl_ssl_connect(conn, sockindex); +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_SSLEAY */ } @@ -302,9 +321,13 @@ static int kill_session(struct curl_ssl_session *session) #ifdef USE_GNUTLS Curl_gtls_session_free(session->sessionid); #else +#ifdef USE_QSOSSL + /* No session handling for QsoSSL. */ +#else #ifdef USE_NSS /* NSS has its own session ID cache */ #endif /* USE_NSS */ +#endif /* USE_QSOSSL */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ session->sessionid=NULL; @@ -400,6 +423,10 @@ void Curl_ssl_close_all(struct SessionHandle *data) #else #ifdef USE_NSS Curl_nss_close_all(data); +#else +#ifdef USE_QSOSSL + Curl_qsossl_close_all(data); +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -420,6 +447,9 @@ void Curl_ssl_close(struct connectdata *conn) #ifdef USE_NSS Curl_nss_close(conn); #endif /* USE_NSS */ +#ifdef USE_QSOSSL + Curl_qsossl_close(conn); +#endif /* USE_QSOSSL */ conn->ssl[FIRSTSOCKET].use = FALSE; } } @@ -434,9 +464,14 @@ CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex) #ifdef USE_GNUTLS if(Curl_gtls_shutdown(conn, sockindex)) return CURLE_SSL_SHUTDOWN_FAILED; +#else +#ifdef USE_QSOSSL + if(Curl_qsossl_shutdown(conn, sockindex)) + return CURLE_SSL_SHUTDOWN_FAILED; #else (void)conn; (void)sockindex; +#endif /* USE_QSOSSL */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ } @@ -461,11 +496,18 @@ CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine) (void)data; (void)engine; return CURLE_FAILED_INIT; +#else +#ifdef USE_QSOSSL + /* QSOSSL doesn't set an engine this way */ + (void)data; + (void)engine; + return CURLE_FAILED_INIT; #else /* no SSL layer */ (void)data; (void)engine; return CURLE_FAILED_INIT; +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -487,10 +529,16 @@ CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data) /* A no-op for NSS */ (void)data; return CURLE_FAILED_INIT; +#else +#ifdef USE_QSOSSL + /* A no-op for QSOSSL */ + (void)data; + return CURLE_FAILED_INIT; #else /* No SSL layer */ (void)data; return CURLE_FAILED_INIT; +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -512,9 +560,15 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data) * would just confuse things */ (void)data; return NULL; +#else +#ifdef USE_QSOSSL + /* No engine support in QSOSSL. */ + (void)data; + return NULL; #else (void)data; return NULL; +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -534,12 +588,16 @@ ssize_t Curl_ssl_send(struct connectdata *conn, #else #ifdef USE_NSS return Curl_nss_send(conn, sockindex, mem, len); +#else +#ifdef USE_QSOSSL + return Curl_qsossl_send(conn, sockindex, mem, len); #else (void)conn; (void)sockindex; (void)mem; (void)len; return 0; +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -568,6 +626,10 @@ ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */ #else #ifdef USE_NSS nread = Curl_nss_recv(conn, sockindex, mem, len, &block); +#else +#ifdef USE_QSOSSL + nread = Curl_qsossl_recv(conn, sockindex, mem, len, &block); +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -631,10 +693,14 @@ size_t Curl_ssl_version(char *buffer, size_t size) #else #ifdef USE_NSS return Curl_nss_version(buffer, size); +#else +#ifdef USE_QSOSSL + return Curl_qsossl_version(buffer, size); #else (void)buffer; (void)size; return 0; /* no SSL support */ +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_GNUTLS */ #endif /* USE_SSLEAY */ @@ -656,10 +722,14 @@ int Curl_ssl_check_cxn(struct connectdata *conn) #else #ifdef USE_NSS return Curl_nss_check_cxn(conn); +#else +#ifdef USE_QSOSSL + return Curl_qsossl_check_cxn(conn); #else (void)conn; /* TODO: we lack implementation of this for GnuTLS */ return -1; /* connection status unknown */ +#endif /* USE_QSOSSL */ #endif /* USE_NSS */ #endif /* USE_SSLEAY */ } -- cgit v1.2.3