aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Monnerat <pm@datasphere.ch>2013-10-25 18:37:37 +0200
committerPatrick Monnerat <pm@datasphere.ch>2013-10-25 18:37:37 +0200
commit2cc9246477285d16d21086dfed5cc4adeee0dbc9 (patch)
tree2f360cdb14b749bc6bd28cb7982c7ae07b9b571e
parent650036633ffdc95c8c2181ce85582bbf3939582e (diff)
OS400: sync RPG wrapper, zlib support, fix header file names, ...
IFS compilation support, SSL GSKit backend by default, TLSv1.[12] support in GSKit for OS400 >= V7R1, no more tabs in make scripts.
-rw-r--r--lib/config-os400.h4
-rw-r--r--lib/gskit.c342
-rw-r--r--lib/setup-os400.h7
-rw-r--r--packages/OS400/README.OS4001
-rw-r--r--packages/OS400/ccsidcurl.c7
-rw-r--r--packages/OS400/curl.inc.in29
-rw-r--r--packages/OS400/initscript.sh71
-rw-r--r--packages/OS400/make-include.sh52
-rw-r--r--packages/OS400/make-lib.sh14
-rw-r--r--packages/OS400/make-tests.sh6
-rw-r--r--packages/OS400/os400sys.c157
-rw-r--r--packages/OS400/os400sys.h2
12 files changed, 482 insertions, 210 deletions
diff --git a/lib/config-os400.h b/lib/config-os400.h
index a290fe43d..889627780 100644
--- a/lib/config-os400.h
+++ b/lib/config-os400.h
@@ -529,10 +529,10 @@
#define SEND_TYPE_RETV int
/* Define to use the QsoSSL package. */
-#define USE_QSOSSL
+#undef USE_QSOSSL
/* Define to use the GSKit package. */
-#undef USE_GSKIT
+#define USE_GSKIT
/* Use the system keyring as the default CA bundle. */
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
diff --git a/lib/gskit.c b/lib/gskit.c
index 187c58d7a..d50748e3a 100644
--- a/lib/gskit.c
+++ b/lib/gskit.c
@@ -29,9 +29,38 @@
/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
-#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
+#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
#endif
+#ifndef GSK_TLSV10_CIPHER_SPECS
+#define GSK_TLSV10_CIPHER_SPECS 236
+#endif
+
+#ifndef GSK_TLSV11_CIPHER_SPECS
+#define GSK_TLSV11_CIPHER_SPECS 237
+#endif
+
+#ifndef GSK_TLSV12_CIPHER_SPECS
+#define GSK_TLSV12_CIPHER_SPECS 238
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV11
+#define GSK_PROTOCOL_TLSV11 437
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV12
+#define GSK_PROTOCOL_TLSV12 438
+#endif
+
+#ifndef GSK_FALSE
+#define GSK_FALSE 0
+#endif
+
+#ifndef GSK_TRUE
+#define GSK_TRUE 1
+#endif
+
+
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
@@ -54,30 +83,65 @@
#include "memdebug.h"
+/* SSL version flags. */
+#define CURL_GSKPROTO_SSLV2 0
+#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2)
+#define CURL_GSKPROTO_SSLV3 1
+#define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3)
+#define CURL_GSKPROTO_TLSV10 2
+#define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10)
+#define CURL_GSKPROTO_TLSV11 3
+#define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11)
+#define CURL_GSKPROTO_TLSV12 4
+#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
+#define CURL_GSKPROTO_LAST 5
+
+
/* Supported ciphers. */
typedef struct {
const char * name; /* Cipher name. */
const char * gsktoken; /* Corresponding token for GSKit String. */
- int sslver; /* SSL version. */
+ unsigned int versions; /* SSL version flags. */
} gskit_cipher;
static const gskit_cipher ciphertable[] = {
- { "null-md5", "01", CURL_SSLVERSION_SSLv3 },
- { "null-sha", "02", CURL_SSLVERSION_SSLv3 },
- { "exp-rc4-md5", "03", CURL_SSLVERSION_SSLv3 },
- { "rc4-md5", "04", CURL_SSLVERSION_SSLv3 },
- { "rc4-sha", "05", CURL_SSLVERSION_SSLv3 },
- { "exp-rc2-cbc-md5", "06", CURL_SSLVERSION_SSLv3 },
- { "exp-des-cbc-sha", "09", CURL_SSLVERSION_SSLv3 },
- { "des-cbc3-sha", "0A", CURL_SSLVERSION_SSLv3 },
- { "aes128-sha", "2F", CURL_SSLVERSION_TLSv1 },
- { "aes256-sha", "35", CURL_SSLVERSION_TLSv1 },
- { "rc4-md5", "1", CURL_SSLVERSION_SSLv2 },
- { "exp-rc4-md5", "2", CURL_SSLVERSION_SSLv2 },
- { "rc2-md5", "3", CURL_SSLVERSION_SSLv2 },
- { "exp-rc2-md5", "4", CURL_SSLVERSION_SSLv2 },
- { "des-cbc-md5", "6", CURL_SSLVERSION_SSLv2 },
- { "des-cbc3-md5", "7", CURL_SSLVERSION_SSLv2 },
+ { "null-md5", "01",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "null-sha", "02",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "exp-rc4-md5", "03",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+ { "rc4-md5", "04",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "rc4-sha", "05",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "exp-rc2-cbc-md5", "06",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+ { "exp-des-cbc-sha", "09",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK },
+ { "des-cbc3-sha", "0A",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "aes128-sha", "2F",
+ CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+ CURL_GSKPROTO_TLSV12_MASK },
+ { "aes256-sha", "35",
+ CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+ CURL_GSKPROTO_TLSV12_MASK },
+ { "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK },
+ { "aes128-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
+ { "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
+ { "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK },
+ { "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK },
+ { "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK },
+ { "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK },
+ { "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK },
+ { "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK },
{ (const char *) NULL, (const char *) NULL, 0 }
};
@@ -142,8 +206,8 @@ static CURLcode gskit_status(struct SessionHandle * data, int rc,
}
-static CURLcode set_enum(struct SessionHandle * data,
- gsk_handle h, GSK_ENUM_ID id, GSK_ENUM_VALUE value)
+static CURLcode set_enum(struct SessionHandle * data, gsk_handle h,
+ GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
{
int rc = gsk_attribute_set_enum(h, id, value);
@@ -153,6 +217,9 @@ static CURLcode set_enum(struct SessionHandle * data,
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
break;
+ case GSK_ATTRIBUTE_INVALID_ID:
+ if(unsupported_ok)
+ return CURLE_UNSUPPORTED_PROTOCOL;
default:
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
break;
@@ -161,8 +228,8 @@ static CURLcode set_enum(struct SessionHandle * data,
}
-static CURLcode set_buffer(struct SessionHandle * data,
- gsk_handle h, GSK_BUF_ID id, const char * buffer)
+static CURLcode set_buffer(struct SessionHandle * data, gsk_handle h,
+ GSK_BUF_ID id, const char * buffer, bool unsupported_ok)
{
int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
@@ -172,6 +239,9 @@ static CURLcode set_buffer(struct SessionHandle * data,
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
break;
+ case GSK_ATTRIBUTE_INVALID_ID:
+ if(unsupported_ok)
+ return CURLE_UNSUPPORTED_PROTOCOL;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
break;
@@ -219,17 +289,20 @@ static CURLcode set_callback(struct SessionHandle * data,
}
-static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
+static CURLcode set_ciphers(struct SessionHandle * data,
+ gsk_handle h, unsigned int * protoflags)
{
const char * cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
- char * sslv2ciphers;
- char * sslv3ciphers;
const char * clp;
const gskit_cipher * ctp;
- char * v2p;
- char * v3p;
int i;
+ int l;
+ bool unsupported;
CURLcode cc;
+ struct {
+ char * buf;
+ char * ptr;
+ } ciphers[CURL_GSKPROTO_LAST];
/* Compile cipher list into GSKit-compatible cipher lists. */
@@ -243,42 +316,44 @@ static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
/* We allocate GSKit buffers of the same size as the input string: since
GSKit tokens are always shorter than their cipher names, allocated buffers
will always be large enough to accomodate the result. */
- i = strlen(cipherlist) + 1;
- v2p = malloc(i);
- if(!v2p)
- return CURLE_OUT_OF_MEMORY;
- v3p = malloc(i);
- if(!v3p) {
- free(v2p);
- return CURLE_OUT_OF_MEMORY;
+ l = strlen(cipherlist) + 1;
+ memset((char *) ciphers, 0, sizeof ciphers);
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+ ciphers[i].buf = malloc(l);
+ if(!ciphers[i].buf) {
+ while(i--)
+ free(ciphers[i].buf);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ ciphers[i].ptr = ciphers[i].buf;
+ *ciphers[i].ptr = '\0';
}
- sslv2ciphers = v2p;
- sslv3ciphers = v3p;
/* Process each cipher in input string. */
+ unsupported = FALSE;
+ cc = CURLE_OK;
for(;;) {
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
cipherlist++;
- i = cipherlist - clp;
- if(!i)
+ l = cipherlist - clp;
+ if(!l)
break;
/* Search the cipher in our table. */
for(ctp = ciphertable; ctp->name; ctp++)
- if(strnequal(ctp->name, clp, i) && !ctp->name[i])
+ if(strnequal(ctp->name, clp, l) && !ctp->name[l])
break;
- if(!ctp->name)
- failf(data, "Unknown cipher %.*s: ignored", i, clp);
+ if(!ctp->name) {
+ failf(data, "Unknown cipher %.*s", l, clp);
+ cc = CURLE_SSL_CIPHER;
+ }
else {
- switch (ctp->sslver) {
- case CURL_SSLVERSION_SSLv2:
- strcpy(v2p, ctp->gsktoken);
- v2p += strlen(v2p);
- break;
- default:
- /* GSKit wants TLSv1 ciphers with SSLv3 ciphers. */
- strcpy(v3p, ctp->gsktoken);
- v3p += strlen(v3p);
- break;
+ unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+ if(ctp->versions & (1 << i)) {
+ strcpy(ciphers[i].ptr, ctp->gsktoken);
+ ciphers[i].ptr += strlen(ctp->gsktoken);
+ }
}
}
@@ -286,13 +361,63 @@ static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
while(is_separator(*cipherlist))
cipherlist++;
}
- *v2p = '\0';
- *v3p = '\0';
- cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS, sslv2ciphers);
- if(cc == CURLE_OK)
- cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS, sslv3ciphers);
- free(sslv2ciphers);
- free(sslv3ciphers);
+
+ /* Disable protocols with empty cipher lists. */
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+ if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
+ *protoflags &= ~(1 << i);
+ ciphers[i].buf[0] = '\0';
+ }
+ }
+
+ /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
+ if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
+ cc = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
+ if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
+ cc = CURLE_OK;
+ if(unsupported) {
+ failf(data, "TLSv1.1-only ciphers are not yet supported");
+ cc = CURLE_SSL_CIPHER;
+ }
+ }
+ }
+ if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
+ cc = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
+ if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
+ cc = CURLE_OK;
+ if(unsupported) {
+ failf(data, "TLSv1.2-only ciphers are not yet supported");
+ cc = CURLE_SSL_CIPHER;
+ }
+ }
+ }
+
+ /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
+ the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
+ if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
+ cc = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
+ if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
+ cc = CURLE_OK;
+ strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
+ ciphers[CURL_GSKPROTO_TLSV10].ptr);
+ }
+ }
+
+ /* Set-up other ciphers. */
+ if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
+ cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
+ if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
+ cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
+
+ /* Clean-up. */
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++)
+ free(ciphers[i].buf);
+
return cc;
}
@@ -333,15 +458,15 @@ static CURLcode init_environment(struct SessionHandle * data,
return CURLE_SSL_CONNECT_ERROR;
}
- c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION);
+ c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
if(c == CURLE_OK && appid)
- c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid);
+ c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
if(c == CURLE_OK && file)
- c = set_buffer(data, h, GSK_KEYRING_FILE, file);
+ c = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
if(c == CURLE_OK && label)
- c = set_buffer(data, h, GSK_KEYRING_LABEL, label);
+ c = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
if(c == CURLE_OK && password)
- c = set_buffer(data, h, GSK_KEYRING_PW, password);
+ c = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
if(c == CURLE_OK) {
/* Locate CAs, Client certificate and key according to our settings.
@@ -438,10 +563,8 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
char * keyringfile;
char * keyringpwd;
char * keyringlabel;
- char * v2ciphers;
- char * v3ciphers;
char * sni;
- bool sslv2enable, sslv3enable, tlsv1enable;
+ unsigned int protoflags;
long timeout;
Qso_OverlappedIO_t commarea;
@@ -491,52 +614,39 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
return cc;
/* Determine which SSL/TLS version should be enabled. */
- sslv2enable = sslv3enable = tlsv1enable = false;
+ protoflags = CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
sni = conn->host.name;
switch (data->set.ssl.version) {
case CURL_SSLVERSION_SSLv2:
- sslv2enable = true;
+ protoflags = CURL_GSKPROTO_SSLV2_MASK;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_SSLv3:
- sslv3enable = true;
+ protoflags = CURL_GSKPROTO_SSLV2_MASK;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_TLSv1:
+ protoflags = CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
+ break;
case CURL_SSLVERSION_TLSv1_0:
- tlsv1enable = true;
+ protoflags = CURL_GSKPROTO_TLSV10_MASK;
break;
case CURL_SSLVERSION_TLSv1_1:
- failf(data, "GSKit doesn't support TLS 1.1!");
- cc = CURLE_SSL_CONNECT_ERROR;
+ protoflags = CURL_GSKPROTO_TLSV11_MASK;
break;
case CURL_SSLVERSION_TLSv1_2:
- failf(data, "GSKit doesn't support TLS 1.2!");
- cc = CURLE_SSL_CONNECT_ERROR;
- break;
- default: /* CURL_SSLVERSION_DEFAULT. */
- sslv3enable = true;
- tlsv1enable = true;
+ protoflags = CURL_GSKPROTO_TLSV12_MASK;
break;
}
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) {
- rc = gsk_attribute_set_buffer(connssl->handle,
- GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, 0);
- switch (rc) {
- case GSK_OK:
- case GSK_ATTRIBUTE_INVALID_ID:
- break;
- case GSK_ERROR_IO:
- failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
- cc = CURLE_SSL_CONNECT_ERROR;
- break;
- default:
- failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
- cc = CURLE_SSL_CONNECT_ERROR;
- break;
- }
+ cc = set_buffer(data, connssl->handle,
+ GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
+ if(cc == CURLE_UNSUPPORTED_PROTOCOL)
+ cc = CURLE_OK;
}
/* Set session parameters. */
@@ -553,23 +663,51 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
if(cc == CURLE_OK)
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
if(cc == CURLE_OK)
- cc = set_ciphers(data, connssl->handle);
+ cc = set_ciphers(data, connssl->handle, &protoflags);
+ if(!protoflags) {
+ failf(data, "No SSL protocol/cipher combination enabled");
+ cc = CURLE_SSL_CIPHER;
+ }
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
- sslv2enable? GSK_PROTOCOL_SSLV2_ON:
- GSK_PROTOCOL_SSLV2_OFF);
+ (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
+ GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
- sslv3enable? GSK_PROTOCOL_SSLV3_ON:
- GSK_PROTOCOL_SSLV3_OFF);
+ (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
+ GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
- tlsv1enable? GSK_PROTOCOL_TLSV1_ON:
- GSK_PROTOCOL_TLSV1_OFF);
+ (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
+ GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
+ if(cc == CURLE_OK) {
+ cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
+ (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
+ GSK_TRUE: GSK_FALSE, TRUE);
+ if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
+ cc = CURLE_OK;
+ if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
+ failf(data, "TLS 1.1 not yet supported");
+ cc = CURLE_SSL_CIPHER;
+ }
+ }
+ }
+ if(cc == CURLE_OK) {
+ cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
+ (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
+ GSK_TRUE: GSK_FALSE, TRUE);
+ if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
+ cc = CURLE_OK;
+ if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
+ failf(data, "TLS 1.2 not yet supported");
+ cc = CURLE_SSL_CIPHER;
+ }
+ }
+ }
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
- GSK_SERVER_AUTH_PASSTHRU);
+ GSK_SERVER_AUTH_PASSTHRU, FALSE);
if(cc == CURLE_OK) {
/* Start handshake. Try asynchronous first. */
diff --git a/lib/setup-os400.h b/lib/setup-os400.h
index 319efec92..37dc05b2b 100644
--- a/lib/setup-os400.h
+++ b/lib/setup-os400.h
@@ -226,5 +226,12 @@ extern int Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
#define sendto Curl_os400_sendto
#define recvfrom Curl_os400_recvfrom
+#ifdef HAVE_LIBZ
+#define zlibVersion Curl_os400_zlibVersion
+#define inflateInit_ Curl_os400_inflateInit_
+#define inflateInit2_ Curl_os400_inflateInit2_
+#define inflate Curl_os400_inflate
+#define inflateEnd Curl_os400_inflateEnd
+#endif
#endif /* HEADER_CURL_SETUP_OS400_H */
diff --git a/packages/OS400/README.OS400 b/packages/OS400/README.OS400
index 73e81f8c3..4a39738a9 100644
--- a/packages/OS400/README.OS400
+++ b/packages/OS400/README.OS400
@@ -118,6 +118,7 @@ options:
CURLOPT_USERAGENT
CURLOPT_USERNAME
CURLOPT_USERPWD
+ CURLOPT_XOAUTH2_BEARER
Else it is the same as for curl_easy_setopt().
Note that CURLOPT_ERRORBUFFER is not in the list above, since it gives the
address of an (empty) character buffer, not the address of a string.
diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c
index a37f79027..9049d9e49 100644
--- a/packages/OS400/ccsidcurl.c
+++ b/packages/OS400/ccsidcurl.c
@@ -1111,11 +1111,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
if(testwarn) {
testwarn = 0;
-#ifdef USE_TLS_SRP
- if((int) STRING_LAST != (int) STRING_TLSAUTH_PASSWORD + 1)
-#else
- if((int) STRING_LAST != (int) STRING_MAIL_AUTH + 1)
-#endif
+ if((int) STRING_LAST != (int) STRING_BEARER + 1)
curl_mfprintf(stderr,
"*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n");
}
@@ -1176,6 +1172,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
case CURLOPT_USERAGENT:
case CURLOPT_USERNAME:
case CURLOPT_USERPWD:
+ case CURLOPT_XOAUTH2_BEARER:
s = va_arg(arg, char *);
ccsid = va_arg(arg, unsigned int);
diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in
index b14d84f83..edd516740 100644
--- a/packages/OS400/curl.inc.in
+++ b/packages/OS400/curl.inc.in
@@ -115,6 +115,8 @@
d c X'00004000'
d CURL_VERSION_NTLM_WB...
d c X'00008000'
+ d CURL_VERSION_HTTP2...
+ d c X'00010000'
*
d HTTPPOST_FILENAME...
d c X'00000001'
@@ -212,6 +214,8 @@
d c 1
d CURL_HTTP_VERSION_1_1...
d c 2
+ d CURL_HTTP_VERSION_2_0...
+ d c 3
*
d CURL_NETRC_IGNORED...
d c 0
@@ -1168,6 +1172,14 @@
d c 00218
d CURLOPT_XFERINFOFUNCTION...
d c 20219
+ d CURLOPT_XOAUTH2_BEARER...
+ d c 10220
+ d CURLOPT_DNS_INTERFACE...
+ d c 10221
+ d CURLOPT_DNS_LOCAL_IP4...
+ d c 10222
+ d CURLOPT_DNS_LOCAL_IP6...
+ d c 10223
*
/if not defined(CURL_NO_OLDIES)
d CURLOPT_SSLKEYPASSWD...
@@ -1457,7 +1469,9 @@
d c 5
d CURLM_UNKNOWN_OPTION...
d c 6
- d CURLM_LAST c 7
+ d CURLM_ADDED_ALREADY...
+ d c 7
+ d CURLM_LAST c 8
*
d CURLMSG s 10i 0 based(######ptr######) Enum
d CURLMSG_NONE c 0
@@ -1566,12 +1580,7 @@
d addrlen 10u 0
d addr 16 struct sockaddr
*
- d curl_khkey ds based(######ptr######)
- d qualified
- d key * const char *
- d len 10u 0
- d keytype 10i 0
- *
+ d curl_khtype s 10i 0 based(######ptr######) enum
d CURLKHTYPE_UNKNOWN...
d c 0
d CURLKHTYPE_RSA1...
@@ -1581,6 +1590,12 @@
d CURLKHTYPE_DSS...
d c 3
*
+ d curl_khkey ds based(######ptr######)
+ d qualified
+ d key * const char *
+ d len 10u 0
+ d keytype like(curl_khtype)
+ *
d curl_forms ds based(######ptr######)
d qualified
d option like(CURLformoption)
diff --git a/packages/OS400/initscript.sh b/packages/OS400/initscript.sh
index c07355fc0..64147e393 100644
--- a/packages/OS400/initscript.sh
+++ b/packages/OS400/initscript.sh
@@ -1,6 +1,16 @@
#!/bin/sh
+setenv()
+
+{
+ # Define and export.
+
+ eval ${1}="${2}"
+ export ${1}
+}
+
+
case "${SCRIPTDIR}" in
/*) ;;
*) SCRIPTDIR="`pwd`/${SCRIPTDIR}"
@@ -32,18 +42,23 @@ export SONAME
#
################################################################################
-TARGETLIB='CURL' # Target OS/400 program library
-STATBNDDIR='CURL_A' # Static binding directory.
-DYNBNDDIR='CURL' # Dynamic binding directory.
-SRVPGM="CURL.${SONAME}" # Service program.
-TGTCCSID='500' # Target CCSID of objects
-DEBUG='*ALL' # Debug level
-OPTIMIZE='10' # Optimisation level
-OUTPUT='*NONE' # Compilation output option.
-TGTRLS='V5R3M0' # Target OS release
+setenv TARGETLIB 'CURL' # Target OS/400 program library.
+setenv STATBNDDIR 'CURL_A' # Static binding directory.
+setenv DYNBNDDIR 'CURL' # Dynamic binding directory.
+setenv SRVPGM "CURL.${SONAME}" # Service program.
+setenv TGTCCSID '500' # Target CCSID of objects.
+setenv DEBUG '*ALL' # Debug level.
+setenv OPTIMIZE '10' # Optimisation level
+setenv OUTPUT '*NONE' # Compilation output option.
+setenv TGTRLS 'V5R3M0' # Target OS release.
+setenv IFSDIR '/curl' # Installation IFS directory.
+
+# Define ZLIB availability and locations.
-export TARGETLIB STATBNDDIR DYNBNDDIR SRVPGM TGTCCSID DEBUG OPTIMIZE OUTPUT
-export TGTRLS
+setenv WITH_ZLIB 0 # Define to 1 to enable.
+setenv ZLIB_INCLUDE '/zlib/include' # ZLIB include IFS directory.
+setenv ZLIB_LIB 'ZLIB' # ZLIB library.
+setenv ZLIB_BNDDIR 'ZLIB_A' # ZLIB binding directory.
################################################################################
@@ -133,14 +148,26 @@ make_module()
CMD="${CMD} LOCALETYPE(*LOCALE)"
CMD="${CMD} INCDIR('/qibm/proddata/qadrt/include'"
CMD="${CMD} '${TOPDIR}/include/curl' '${TOPDIR}/include'"
- CMD="${CMD} '${TOPDIR}/packages/OS400' ${INCLUDES})"
+ CMD="${CMD} '${TOPDIR}/packages/OS400'"
+
+ if [ "${WITH_ZLIB}" != "0" ]
+ then CMD="${CMD} '${ZLIB_INCLUDE}'"
+ fi
+
+ CMD="${CMD} ${INCLUDES})"
CMD="${CMD} TGTCCSID(${TGTCCSID}) TGTRLS(${TGTRLS})"
CMD="${CMD} OUTPUT(${OUTPUT})"
CMD="${CMD} OPTIMIZE(${OPTIMIZE})"
CMD="${CMD} DBGVIEW(${DEBUG})"
- if [ "${3}" ]
- then CMD="${CMD} DEFINE(${3})"
+ DEFINES="${3}"
+
+ if [ "${WITH_ZLIB}" != "0" ]
+ then DEFINES="${DEFINES} HAVE_LIBZ HAVE_ZLIB_H"
+ fi
+
+ if [ "${DEFINES}" ]
+ then CMD="${CMD} DEFINE(${DEFINES})"
fi
system "${CMD}"
@@ -154,11 +181,17 @@ make_module()
db2_name()
{
- basename "${1}" |
- tr 'a-z-' 'A-Z_' |
- sed -e 's/\..*//' \
- -e 's/^CURL_*/C/' \
- -e 's/^\(.\).*\(.........\)$/\1\2/'
+ if [ "${2}" = 'nomangle' ]
+ then basename "${1}" |
+ tr 'a-z-' 'A-Z_' |
+ sed -e 's/\..*//' \
+ -e 's/^\(.\).*\(.........\)$/\1\2/'
+ else basename "${1}" |
+ tr 'a-z-' 'A-Z_' |
+ sed -e 's/\..*//' \
+ -e 's/^CURL_*/C/' \
+ -e 's/^\(.\).*\(.........\)$/\1\2/'
+ fi
}
diff --git a/packages/OS400/make-include.sh b/packages/OS400/make-include.sh
index 834ee2fce..ad72cf4a7 100644
--- a/packages/OS400/make-include.sh
+++ b/packages/OS400/make-include.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Installation of the include files in the OS/400 library.
+# Installation of the header files in the OS/400 library.
#
SCRIPTDIR=`dirname "${0}"`
@@ -8,16 +8,16 @@ SCRIPTDIR=`dirname "${0}"`
cd "${TOPDIR}/include"
-# Produce the curlbuild.h include file if not yet in distribution (CVS).
+# Produce the curlbuild.h header file if not yet in distribution (CVS).
if action_needed curl/curlbuild.h
-then if action_needed curl/curlbuild.h curl/curlbuild.h.dist
- then cp -p curl/curlbuild.h.dist curl/curlbuild.h
- fi
+then if action_needed curl/curlbuild.h curl/curlbuild.h.dist
+ then cp -p curl/curlbuild.h.dist curl/curlbuild.h
+ fi
fi
-# Create the OS/400 source program file for the include files.
+# Create the OS/400 source program file for the header files.
SRCPF="${LIBIFSNAME}/H.FILE"
@@ -28,16 +28,25 @@ then CMD="CRTSRCPF FILE(${TARGETLIB}/H) RCDLEN(112)"
fi
+# Create the IFS directory for the header files.
+
+IFSINCLUDE="${IFSDIR}/include/curl"
+
+if action_needed "${IFSINCLUDE}"
+then mkdir -p "${IFSINCLUDE}"
+fi
+
+
# Enumeration values are used as va_arg tagfields, so they MUST be
# integers.
copy_hfile()
{
- destfile="${1}"
- srcfile="${2}"
- shift
- shift
+ destfile="${1}"
+ srcfile="${2}"
+ shift
+ shift
sed -e '1i\
#pragma enum(int)\
' "${@}" -e '$a\
@@ -48,23 +57,34 @@ copy_hfile()
# Copy the header files.
for HFILE in curl/*.h ${SCRIPTDIR}/ccsidcurl.h
-do DEST="${SRCPF}/`db2_name \"${HFILE}\"`.MBR"
+do case "`basename \"${HFILE}\" .h`" in
+ stdcheaders|typecheck-gcc)
+ continue;;
+ esac
+
+ DEST="${SRCPF}/`db2_name \"${HFILE}\" nomangle`.MBR"
+
if action_needed "${DEST}" "${HFILE}"
then copy_hfile "${DEST}" "${HFILE}"
+ IFSDEST="${IFSINCLUDE}/`basename \"${HFILE}\"`"
+ rm -f "${IFSDEST}"
+ ln -s "${DEST}" "${IFSDEST}"
fi
done
-# Copy the ILE/RPG include file, setting-up version number.
+# Copy the ILE/RPG header file, setting-up version number.
- versioned_copy "${SCRIPTDIR}/curl.inc.in" "${SRCPF}/CURL.INC.MBR"
+versioned_copy "${SCRIPTDIR}/curl.inc.in" "${SRCPF}/CURL.INC.MBR"
+rm -f "${IFSINCLUDE}/curl.inc.rpgle"
+ln -s "${SRCPF}/CURL.INC.MBR" "${IFSINCLUDE}/curl.inc.rpgle"
-# Duplicate file H as CURL to support more include path forms.
+# Duplicate file H as CURL to support more include path forms.
if action_needed "${LIBIFSNAME}/CURL.FILE"
-then :
-else system "DLTF FILE(${TARGETLIB}/CURL)"
+then :
+else system "DLTF FILE(${TARGETLIB}/CURL)"
fi
CMD="CRTDUPOBJ OBJ(H) FROMLIB(${TARGETLIB}) OBJTYPE(*FILE) TOLIB(*FROMLIB)"
diff --git a/packages/OS400/make-lib.sh b/packages/OS400/make-lib.sh
index e2a87082d..5e1f2042b 100644
--- a/packages/OS400/make-lib.sh
+++ b/packages/OS400/make-lib.sh
@@ -83,12 +83,12 @@ fi
# Gather the list of symbols to export.
-EXPORTS=`grep '^CURL_EXTERN[ ]' \
+EXPORTS=`grep '^CURL_EXTERN[[:space:]]' \
"${TOPDIR}"/include/curl/*.h \
"${SCRIPTDIR}/ccsidcurl.h" |
- sed -e 's/^.*CURL_EXTERN[ ]\(.*\)(.*$/\1/' \
- -e 's/[ ]*$//' \
- -e 's/^.*[ ][ ]*//' \
+ sed -e 's/^.*CURL_EXTERN[[:space:]]\(.*\)(.*$/\1/' \
+ -e 's/[[:space:]]*$//' \
+ -e 's/^.*[[:space:]][[:space:]]*//' \
-e 's/^\*//' \
-e 's/(\(.*\))/\1/'`
@@ -121,7 +121,11 @@ if [ "${LINK}" ]
then CMD="CRTSRVPGM SRVPGM(${TARGETLIB}/${SRVPGM})"
CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(BNDSRC)"
CMD="${CMD} MODULE(${TARGETLIB}/OS400)"
- CMD="${CMD} BNDDIR(${TARGETLIB}/${STATBNDDIR})"
+ CMD="${CMD} BNDDIR(${TARGETLIB}/${STATBNDDIR}"
+ if [ "${WITH_ZLIB}" != 0 ]
+ then CMD="${CMD} ${ZLIB_LIB}/${ZLIB_BNDDIR}"
+ fi
+ CMD="${CMD})"
CMD="${CMD} BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR)"
CMD="${CMD} TEXT('curl API library')"
CMD="${CMD} TGTRLS(${TGTRLS})"
diff --git a/packages/OS400/make-tests.sh b/packages/OS400/make-tests.sh
index cee3ed95d..9240b7ff6 100644
--- a/packages/OS400/make-tests.sh
+++ b/packages/OS400/make-tests.sh
@@ -28,11 +28,11 @@ eval "`sed -e ': begin' \
-e 's/\\\\\\n/ /' \
-e 'b begin' \
-e '}' \
- -e '/^[A-Za-z_][A-Za-z0-9_]*[ ]*[=]/b keep' \
+ -e '/^[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[=]/b keep' \
-e 'd' \
-e ': keep' \
- -e 's/[ ]*=[ ]*/=/' \
- -e 's/=\\(.*[^ ]\\)[ ]*$/=\\"\\1\\"/' \
+ -e 's/[[:space:]]*=[[:space:]]*/=/' \
+ -e 's/=\\(.*[^[:space:]]\\)[[:space:]]*$/=\\"\\1\\"/' \
-e 's/\\$(\\([^)]*\\))/${\\1}/g' \
< Makefile.inc`"
diff --git a/packages/OS400/os400sys.c b/packages/OS400/os400sys.c
index ab0c4fb29..90160878d 100644
--- a/packages/OS400/os400sys.c
+++ b/packages/OS400/os400sys.c
@@ -38,6 +38,10 @@
#include <qadrt.h>
#include <errno.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
#ifdef USE_QSOSSL
#include <qsossl.h>
#endif
@@ -241,6 +245,28 @@ buffer_undef(localkey_t key, long size)
}
+static char *
+set_thread_string(localkey_t key, const char * s)
+
+{
+ int i;
+ char * cp;
+
+ if(!s)
+ return (char *) NULL;
+
+ i = strlen(s) + 1;
+ cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
+
+ if(cp) {
+ i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
+ cp[i] = '\0';
+ }
+
+ return cp;
+}
+
+
int
Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
char * nodename, curl_socklen_t nodenamelen,
@@ -434,23 +460,8 @@ char *
Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
{
- int i;
- char * cp;
- char * cp2;
-
- cp = SSL_Strerror(sslreturnvalue, serrmsgp);
-
- if (!cp)
- return cp;
-
- i = strlen(cp);
-
- if (!(cp2 = Curl_thread_buffer(LK_SSL_ERROR, MAX_CONV_EXPANSION * i + 1)))
- return cp2;
-
- i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
- cp2[i] = '\0';
- return cp2;
+ return set_thread_string(LK_SSL_ERROR,
+ SSL_Strerror(sslreturnvalue, serrmsgp));
}
#endif /* USE_QSOSSL */
@@ -825,23 +836,7 @@ const char *
Curl_gsk_strerror_a(int gsk_return_value)
{
- int i;
- const char * cp;
- char * cp2;
-
- cp = gsk_strerror(gsk_return_value);
-
- if (!cp)
- return cp;
-
- i = strlen(cp);
-
- if (!(cp2 = Curl_thread_buffer(LK_GSK_ERROR, MAX_CONV_EXPANSION * i + 1)))
- return cp2;
-
- i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
- cp2[i] = '\0';
- return cp2;
+ return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
}
int
@@ -1235,23 +1230,7 @@ char *
Curl_ldap_err2string_a(int error)
{
- int i;
- char * cp;
- char * cp2;
-
- cp = ldap_err2string(error);
-
- if (!cp)
- return cp;
-
- i = strlen(cp);
-
- if (!(cp2 = Curl_thread_buffer(LK_LDAP_ERROR, MAX_CONV_EXPANSION * i + 1)))
- return cp2;
-
- i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
- cp2[i] = '\0';
- return cp2;
+ return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
}
@@ -1492,3 +1471,79 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
*addrlen = laddrlen;
return rcvlen;
}
+
+
+#ifdef HAVE_LIBZ
+const char *
+Curl_os400_zlibVersion(void)
+
+{
+ return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
+}
+
+
+int
+Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
+
+{
+ z_const char * msgb4 = strm->msg;
+ int ret;
+
+ ret = inflateInit(strm);
+
+ if(strm->msg != msgb4)
+ strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+ return ret;
+}
+
+
+int
+Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
+ const char * version, int stream_size)
+
+{
+ z_const char * msgb4 = strm->msg;
+ int ret;
+
+ ret = inflateInit2(strm, windowBits);
+
+ if(strm->msg != msgb4)
+ strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+ return ret;
+}
+
+
+int
+Curl_os400_inflate(z_streamp strm, int flush)
+
+{
+ z_const char * msgb4 = strm->msg;
+ int ret;
+
+ ret = inflate(strm, flush);
+
+ if(strm->msg != msgb4)
+ strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+ return ret;
+}
+
+
+int
+Curl_os400_inflateEnd(z_streamp strm)
+
+{
+ z_const char * msgb4 = strm->msg;
+ int ret;
+
+ ret = inflateEnd(strm);
+
+ if(strm->msg != msgb4)
+ strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+ return ret;
+}
+
+#endif
diff --git a/packages/OS400/os400sys.h b/packages/OS400/os400sys.h
index 234bf5e80..114469222 100644
--- a/packages/OS400/os400sys.h
+++ b/packages/OS400/os400sys.h
@@ -39,6 +39,8 @@ typedef enum {
LK_EASY_STRERROR,
LK_SHARE_STRERROR,
LK_MULTI_STRERROR,
+ LK_ZLIB_VERSION,
+ LK_ZLIB_MSG,
LK_LAST
} localkey_t;