diff options
| author | Patrick Monnerat <pm@datasphere.ch> | 2013-10-25 18:37:37 +0200 | 
|---|---|---|
| committer | Patrick Monnerat <pm@datasphere.ch> | 2013-10-25 18:37:37 +0200 | 
| commit | 2cc9246477285d16d21086dfed5cc4adeee0dbc9 (patch) | |
| tree | 2f360cdb14b749bc6bd28cb7982c7ae07b9b571e | |
| parent | 650036633ffdc95c8c2181ce85582bbf3939582e (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.h | 4 | ||||
| -rw-r--r-- | lib/gskit.c | 342 | ||||
| -rw-r--r-- | lib/setup-os400.h | 7 | ||||
| -rw-r--r-- | packages/OS400/README.OS400 | 1 | ||||
| -rw-r--r-- | packages/OS400/ccsidcurl.c | 7 | ||||
| -rw-r--r-- | packages/OS400/curl.inc.in | 29 | ||||
| -rw-r--r-- | packages/OS400/initscript.sh | 71 | ||||
| -rw-r--r-- | packages/OS400/make-include.sh | 52 | ||||
| -rw-r--r-- | packages/OS400/make-lib.sh | 14 | ||||
| -rw-r--r-- | packages/OS400/make-tests.sh | 6 | ||||
| -rw-r--r-- | packages/OS400/os400sys.c | 157 | ||||
| -rw-r--r-- | packages/OS400/os400sys.h | 2 | 
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;  | 
