Ejemplo n.º 1
0
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
{
  struct Curl_easy *data = conn->data;
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  gsk_handle envir;
  CURLcode result;
  int rc;
  char *keyringfile;
  char *keyringpwd;
  char *keyringlabel;
  char *sni;
  unsigned int protoflags;
  long timeout;
  Qso_OverlappedIO_t commarea;

  /* Create SSL environment, start (preferably asynchronous) handshake. */

  connssl->handle = (gsk_handle) NULL;
  connssl->iocport = -1;

  /* GSKit supports two ways of specifying an SSL context: either by
   *  application identifier (that should have been defined at the system
   *  level) or by keyring file, password and certificate label.
   * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
   *  application identifier of the certificate label.
   * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
   * It is not possible to have different keyrings for the CAs and the
   *  local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
   *  the keyring file.
   * If no key password is given and the keyring is the system keyring,
   *  application identifier mode is tried first, as recommended in IBM doc.
   */

  keyringfile = data->set.str[STRING_SSL_CAFILE];
  keyringpwd = data->set.str[STRING_KEY_PASSWD];
  keyringlabel = data->set.str[STRING_CERT];
  envir = (gsk_handle) NULL;

  if(keyringlabel && *keyringlabel && !keyringpwd &&
      !strcmp(keyringfile, CURL_CA_BUNDLE)) {
    /* Try application identifier mode. */
    init_environment(data, &envir, keyringlabel, (const char *) NULL,
                     (const char *) NULL, (const char *) NULL);
  }

  if(!envir) {
    /* Use keyring mode. */
    result = init_environment(data, &envir, (const char *) NULL,
                              keyringfile, keyringlabel, keyringpwd);
    if(result)
      return result;
  }

  /* Create secure session. */
  result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
                        "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
  gsk_environment_close(&envir);
  if(result)
    return result;

  /* Determine which SSL/TLS version should be enabled. */
  protoflags = 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:
    protoflags = CURL_GSKPROTO_SSLV2_MASK;
    sni = (char *) NULL;
    break;
  case CURL_SSLVERSION_SSLv3:
    protoflags = CURL_GSKPROTO_SSLV3_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:
    protoflags = CURL_GSKPROTO_TLSV10_MASK;
    break;
  case CURL_SSLVERSION_TLSv1_1:
    protoflags = CURL_GSKPROTO_TLSV11_MASK;
    break;
  case CURL_SSLVERSION_TLSv1_2:
    protoflags = CURL_GSKPROTO_TLSV12_MASK;
    break;
  }

  /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
  if(sni) {
    result = set_buffer(data, connssl->handle,
                        GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
    if(result == CURLE_UNSUPPORTED_PROTOCOL)
      result = CURLE_OK;
  }

  /* Set session parameters. */
  if(!result) {
    /* Compute the handshake timeout. Since GSKit granularity is 1 second,
       we round up the required value. */
    timeout = Curl_timeleft(data, NULL, TRUE);
    if(timeout < 0)
      result = CURLE_OPERATION_TIMEDOUT;
    else
      result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
                           (timeout + 999) / 1000);
  }
  if(!result)
    result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
  if(!result)
    result = set_ciphers(data, connssl->handle, &protoflags);
  if(!protoflags) {
    failf(data, "No SSL protocol/cipher combination enabled");
    result = CURLE_SSL_CIPHER;
  }
  if(!result)
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
                      (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
                      GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
  if(!result)
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
                      (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
                      GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
  if(!result)
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
                      (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
                      GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
  if(!result) {
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
                      (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
                      GSK_TRUE: GSK_FALSE, TRUE);
    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
      result = CURLE_OK;
      if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
        failf(data, "TLS 1.1 not yet supported");
        result = CURLE_SSL_CIPHER;
      }
    }
  }
  if(!result) {
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
                      (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
                      GSK_TRUE: GSK_FALSE, TRUE);
    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
      result = CURLE_OK;
      if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
        failf(data, "TLS 1.2 not yet supported");
        result = CURLE_SSL_CIPHER;
      }
    }
  }
  if(!result)
    result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
                      data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
                      GSK_SERVER_AUTH_PASSTHRU, FALSE);

  if(!result) {
    /* Start handshake. Try asynchronous first. */
    memset(&commarea, 0, sizeof commarea);
    connssl->iocport = QsoCreateIOCompletionPort();
    if(connssl->iocport != -1) {
      result = gskit_status(data,
                            gsk_secure_soc_startInit(connssl->handle,
                                                     connssl->iocport,
                                                     &commarea),
                            "gsk_secure_soc_startInit()",
                            CURLE_SSL_CONNECT_ERROR);
      if(!result) {
        connssl->connecting_state = ssl_connect_2;
        return CURLE_OK;
      }
      else
        close_async_handshake(connssl);
    }
    else if(errno != ENOBUFS)
      result = gskit_status(data, GSK_ERROR_IO,
                            "QsoCreateIOCompletionPort()", 0);
    else {
      /* No more completion port available. Use synchronous IO. */
      result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
                            "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
      if(!result) {
        connssl->connecting_state = ssl_connect_3;
        return CURLE_OK;
      }
    }
  }

  /* Error: rollback. */
  close_one(connssl, data);
  return result;
}
Ejemplo n.º 2
0
static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
{
  struct SessionHandle * data = conn->data;
  struct ssl_connect_data * connssl = &conn->ssl[sockindex];
  gsk_handle envir;
  CURLcode cc;
  int rc;
  char * keyringfile;
  char * keyringpwd;
  char * keyringlabel;
  char * v2ciphers;
  char * v3ciphers;
  char * sni;
  bool sslv2enable, sslv3enable, tlsv1enable;
  long timeout;
  Qso_OverlappedIO_t commarea;

  /* Create SSL environment, start (preferably asynchronous) handshake. */

  connssl->handle = (gsk_handle) NULL;
  connssl->iocport = -1;

  /* GSKit supports two ways of specifying an SSL context: either by
   *  application identifier (that should have been defined at the system
   *  level) or by keyring file, password and certificate label.
   * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
   *  application identifier of the certificate label.
   * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
   * It is not possible to have different keyrings for the CAs and the
   *  local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
   *  the keyring file.
   * If no key password is given and the keyring is the system keyring,
   *  application identifier mode is tried first, as recommended in IBM doc.
   */

  keyringfile = data->set.str[STRING_SSL_CAFILE];
  keyringpwd = data->set.str[STRING_KEY_PASSWD];
  keyringlabel = data->set.str[STRING_CERT];
  envir = (gsk_handle) NULL;

  if(keyringlabel && *keyringlabel && !keyringpwd &&
      !strcmp(keyringfile, CURL_CA_BUNDLE)) {
    /* Try application identifier mode. */
    init_environment(data, &envir, keyringlabel, (const char *) NULL,
                     (const char *) NULL, (const char *) NULL);
  }

  if(!envir) {
    /* Use keyring mode. */
    cc = init_environment(data, &envir, (const char *) NULL,
                          keyringfile, keyringlabel, keyringpwd);
    if(cc != CURLE_OK)
      return cc;
  }

  /* Create secure session. */
  cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
                    "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
  gsk_environment_close(&envir);
  if(cc != CURLE_OK)
    return cc;

  /* Determine which SSL/TLS version should be enabled. */
  sslv2enable = sslv3enable = tlsv1enable = false;
  sni = conn->host.name;
  switch (data->set.ssl.version) {
  case CURL_SSLVERSION_SSLv2:
    sslv2enable = true;
    sni = (char *) NULL;
    break;
  case CURL_SSLVERSION_SSLv3:
    sslv3enable = true;
    sni = (char *) NULL;
    break;
  case CURL_SSLVERSION_TLSv1:
    tlsv1enable = true;
    break;
  default:              /* CURL_SSLVERSION_DEFAULT. */
    sslv3enable = true;
    tlsv1enable = true;
    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;
    }
  }

  /* Set session parameters. */
  if(cc == CURLE_OK) {
    /* Compute the handshake timeout. Since GSKit granularity is 1 second,
       we round up the required value. */
    timeout = Curl_timeleft(data, NULL, TRUE);
    if(timeout < 0)
      cc = CURLE_OPERATION_TIMEDOUT;
    else
      cc = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
                       (timeout + 999) / 1000);
  }
  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);
  if(cc == CURLE_OK)
      cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
                    sslv2enable? GSK_PROTOCOL_SSLV2_ON:
                    GSK_PROTOCOL_SSLV2_OFF);
  if(cc == CURLE_OK)
    cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
                  sslv3enable? GSK_PROTOCOL_SSLV3_ON:
                  GSK_PROTOCOL_SSLV3_OFF);
  if(cc == CURLE_OK)
    cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
                  sslv3enable?  GSK_PROTOCOL_TLSV1_ON:
                  GSK_PROTOCOL_TLSV1_OFF);
  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);

  if(cc == CURLE_OK) {
    /* Start handshake. Try asynchronous first. */
    memset(&commarea, 0, sizeof commarea);
    connssl->iocport = QsoCreateIOCompletionPort();
    if(connssl->iocport != -1) {
      cc = gskit_status(data, gsk_secure_soc_startInit(connssl->handle,
                        connssl->iocport, &commarea),
                        "gsk_secure_soc_startInit()", CURLE_SSL_CONNECT_ERROR);
      if(cc == CURLE_OK) {
        connssl->connecting_state = ssl_connect_2;
        return CURLE_OK;
      }
      else
        close_async_handshake(connssl);
    }
    else if(errno != ENOBUFS)
      cc = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0);
    else {
      /* No more completion port available. Use synchronous IO. */
      cc = gskit_status(data, gsk_secure_soc_init(connssl->handle),
                       "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
      if(cc == CURLE_OK) {
        connssl->connecting_state = ssl_connect_3;
        return CURLE_OK;
      }
    }
  }

  /* Error: rollback. */
  close_one(connssl, data);
  return cc;
}
Ejemplo n.º 3
0
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
{
  struct Curl_easy *data = conn->data;
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  gsk_handle envir;
  CURLcode result;
  int rc;
  const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
  const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
  const char * const keyringlabel = SSL_SET_OPTION(cert);
  const long int ssl_version = SSL_CONN_CONFIG(version);
  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
  const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
    conn->host.name;
  const char *sni;
  unsigned int protoflags;
  long timeout;
  Qso_OverlappedIO_t commarea;
  int sockpair[2];
  static const int sobufsize = CURL_MAX_WRITE_SIZE;

  /* Create SSL environment, start (preferably asynchronous) handshake. */

  connssl->handle = (gsk_handle) NULL;
  connssl->iocport = -1;
  connssl->localfd = -1;
  connssl->remotefd = -1;

  /* GSKit supports two ways of specifying an SSL context: either by
   *  application identifier (that should have been defined at the system
   *  level) or by keyring file, password and certificate label.
   * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
   *  application identifier of the certificate label.
   * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
   * It is not possible to have different keyrings for the CAs and the
   *  local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
   *  the keyring file.
   * If no key password is given and the keyring is the system keyring,
   *  application identifier mode is tried first, as recommended in IBM doc.
   */

  envir = (gsk_handle) NULL;

  if(keyringlabel && *keyringlabel && !keyringpwd &&
      !strcmp(keyringfile, CURL_CA_BUNDLE)) {
    /* Try application identifier mode. */
    init_environment(data, &envir, keyringlabel, (const char *) NULL,
                     (const char *) NULL, (const char *) NULL);
  }

  if(!envir) {
    /* Use keyring mode. */
    result = init_environment(data, &envir, (const char *) NULL,
                              keyringfile, keyringlabel, keyringpwd);
    if(result)
      return result;
  }

  /* Create secure session. */
  result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
                        "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
  gsk_environment_close(&envir);
  if(result)
    return result;

  /* Establish a pipelining socket pair for SSL over SSL. */
  if(conn->proxy_ssl[sockindex].use) {
    if(inetsocketpair(sockpair))
      return CURLE_SSL_CONNECT_ERROR;
    connssl->localfd = sockpair[0];
    connssl->remotefd = sockpair[1];
    setsockopt(connssl->localfd, SOL_SOCKET, SO_RCVBUF,
               (void *) sobufsize, sizeof sobufsize);
    setsockopt(connssl->remotefd, SOL_SOCKET, SO_RCVBUF,
               (void *) sobufsize, sizeof sobufsize);
    setsockopt(connssl->localfd, SOL_SOCKET, SO_SNDBUF,
               (void *) sobufsize, sizeof sobufsize);
    setsockopt(connssl->remotefd, SOL_SOCKET, SO_SNDBUF,
               (void *) sobufsize, sizeof sobufsize);
    curlx_nonblock(connssl->localfd, TRUE);
    curlx_nonblock(connssl->remotefd, TRUE);
  }

  /* Determine which SSL/TLS version should be enabled. */
  sni = hostname;
  switch (ssl_version) {
  case CURL_SSLVERSION_SSLv2:
    protoflags = CURL_GSKPROTO_SSLV2_MASK;
    sni = NULL;
    break;
  case CURL_SSLVERSION_SSLv3:
    protoflags = CURL_GSKPROTO_SSLV3_MASK;
    sni = NULL;
    break;
  case CURL_SSLVERSION_DEFAULT:
  case CURL_SSLVERSION_TLSv1:
    protoflags = CURL_GSKPROTO_TLSV10_MASK |
                 CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
    break;
  case CURL_SSLVERSION_TLSv1_0:
    protoflags = CURL_GSKPROTO_TLSV10_MASK;
    break;
  case CURL_SSLVERSION_TLSv1_1:
    protoflags = CURL_GSKPROTO_TLSV11_MASK;
    break;
  case CURL_SSLVERSION_TLSv1_2:
    protoflags = CURL_GSKPROTO_TLSV12_MASK;
    break;
  case CURL_SSLVERSION_TLSv1_3:
    failf(data, "GSKit: TLS 1.3 is not yet supported");
    return CURLE_SSL_CONNECT_ERROR;
  default:
    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
    return CURLE_SSL_CONNECT_ERROR;
  }

  /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
  if(sni) {
    result = set_buffer(data, connssl->handle,
                        GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
    if(result == CURLE_UNSUPPORTED_PROTOCOL)
      result = CURLE_OK;
  }

  /* Set session parameters. */
  if(!result) {
    /* Compute the handshake timeout. Since GSKit granularity is 1 second,
       we round up the required value. */
    timeout = Curl_timeleft(data, NULL, TRUE);
    if(timeout < 0)
      result = CURLE_OPERATION_TIMEDOUT;
    else
      result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
                           (timeout + 999) / 1000);
  }
  if(!result)
    result = set_numeric(data, connssl->handle, GSK_OS400_READ_TIMEOUT, 1);
  if(!result)
    result = set_numeric(data, connssl->handle, GSK_FD, connssl->localfd >= 0?
                         connssl->localfd: conn->sock[sockindex]);
  if(!result)
    result = set_ciphers(conn, connssl->handle, &protoflags);
  if(!protoflags) {
    failf(data, "No SSL protocol/cipher combination enabled");
    result = CURLE_SSL_CIPHER;
  }
  if(!result)
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
                      (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
                      GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
  if(!result)
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
                      (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
                      GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
  if(!result)
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
                      (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
                      GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
  if(!result) {
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
                      (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
                      GSK_TRUE: GSK_FALSE, TRUE);
    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
      result = CURLE_OK;
      if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
        failf(data, "TLS 1.1 not yet supported");
        result = CURLE_SSL_CIPHER;
      }
    }
  }
  if(!result) {
    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
                      (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
                      GSK_TRUE: GSK_FALSE, TRUE);
    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
      result = CURLE_OK;
      if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
        failf(data, "TLS 1.2 not yet supported");
        result = CURLE_SSL_CIPHER;
      }
    }
  }
  if(!result)
    result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
                      verifypeer? GSK_SERVER_AUTH_FULL:
                      GSK_SERVER_AUTH_PASSTHRU, FALSE);

  if(!result) {
    /* Start handshake. Try asynchronous first. */
    memset(&commarea, 0, sizeof commarea);
    connssl->iocport = QsoCreateIOCompletionPort();
    if(connssl->iocport != -1) {
      result = gskit_status(data,
                            gsk_secure_soc_startInit(connssl->handle,
                                                     connssl->iocport,
                                                     &commarea),
                            "gsk_secure_soc_startInit()",
                            CURLE_SSL_CONNECT_ERROR);
      if(!result) {
        connssl->connecting_state = ssl_connect_2;
        return CURLE_OK;
      }
      else
        close_async_handshake(connssl);
    }
    else if(errno != ENOBUFS)
      result = gskit_status(data, GSK_ERROR_IO,
                            "QsoCreateIOCompletionPort()", 0);
    else if(conn->proxy_ssl[sockindex].use) {
      /* Cannot pipeline while handshaking synchronously. */
      result = CURLE_SSL_CONNECT_ERROR;
    }
    else {
      /* No more completion port available. Use synchronous IO. */
      result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
                            "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
      if(!result) {
        connssl->connecting_state = ssl_connect_3;
        return CURLE_OK;
      }
    }
  }

  /* Error: rollback. */
  close_one(connssl, conn, sockindex);
  return result;
}
Ejemplo n.º 4
0
void main(void)
{
    gsk_handle my_env_handle=NULL; /* secure environment handle */ 
    gsk_handle my_session_handle=NULL; /* secure session handle */ 
    struct sockaddr_in address;
    int buf_len, rc = 0, sd = -1;
    int amtWritten, amtRead;
    char buff1[1024];
    char buff2[1024]; /* hardcoded IP address (change to make address where server program runs) */
#pragma convert(37)
    char addr[16] = "129.142.220.37"; /*********************************************/
#pragma convert(0)
    /* Issue all of the command in a do/while */
    /* loop so that cleanup can happen at end */
    /*********************************************/
    do { /* open a gsk environment */ rc = errno = 0;
        rc = gsk_environment_open(&my_env_handle);
        if (rc != GSK_OK) { printf("gsk_environment_open() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }
        /* set the Application ID to use */
        rc = errno = 0;

#pragma convert(37)
        rc = gsk_attribute_set_buffer(my_env_handle, GSK_OS400_APPLICATION_ID, "PYTHON", 6);
#pragma convert(0)
        if (rc != GSK_OK) { printf("gsk_attribute_set_buffer() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }
        /* set this side as the client (this is the default */
        rc = errno = 0;
        rc = gsk_attribute_set_enum(my_env_handle, GSK_SESSION_TYPE, GSK_CLIENT_SESSION);
        if (rc != GSK_OK) { printf("gsk_attribute_set_enum() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }
        /* by default SSL_V2, SSL_V3, and TLS_V1 are enabled */
        /* We will disable SSL_V2 for this example. */
        /*rc = errno = 0;
        rc = gsk_attribute_set_enum(my_env_handle, GSK_PROTOCOL_SSLV2, GSK_PROTOCOL_SSLV2_OFF);
        if (rc != GSK_OK) { printf("gsk_attribute_set_enum() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }*/
        /* set the cipher suite to use. By default our default list */
        /* of ciphers is enabled. For this example we will just use one */
        /*rc = errno = 0;
        rc = gsk_attribute_set_buffer(my_env_handle, GSK_V3_CIPHER_SPECS, "05", 2);
        if (rc != GSK_OK) { printf("gsk_attribute_set_buffer() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }*/
        /* Initialize the secure environment */
        rc = errno = 0;
        rc = gsk_environment_init(my_env_handle);
        if (rc != GSK_OK) { printf("gsk_environment_init() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }
        /* initialize a socket to be used for listening */
        sd = socket(AF_INET, SOCK_STREAM, 0);
        if (sd < 0) { perror("socket() failed");
            break;
        }
        /* connect to the server using a set port number */
        memset((char *) &address, 0, sizeof(address));
        address.sin_family = AF_INET;
        address.sin_port = 443;
        address.sin_addr.s_addr = inet_addr(addr);
        rc = connect(sd, (struct sockaddr *) &address, sizeof(address));
        if (rc < 0) { perror("connect() failed");
            break;
        }
        /* open a secure session */
        rc = errno = 0;
        rc = gsk_secure_soc_open(my_env_handle, &my_session_handle);
        if (rc != GSK_OK) { printf("gsk_secure_soc_open() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }
        /* associate our socket with the secure session */
        rc=errno=0;
        rc = gsk_attribute_set_numeric_value(my_session_handle, GSK_FD, sd);
        if (rc != GSK_OK) {
            printf("gsk_attribute_set_numeric_value() failed with rc = %d ", rc);
            printf("and errno = %d.\n", errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }
        /* initiate the SSL handshake */
        rc = errno = 0;
        rc = gsk_secure_soc_init(my_session_handle);
        if (rc != GSK_OK) 
        { 
#pragma convert(37)
            /*printf("gsk_secure_soc_init() failed with rc = %d and errno = %d.\n", rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));*/
#pragma convert(0)
            break;
        }
        /* memset buffer to hex zeros */
        memset((char *) buff1, 0, sizeof(buff1));
        /* send a message to the server using the secure session */
        strcpy(buff1,"Test of gsk_secure_soc_write \n\n");
        /* send the message to the client using the secure session */
        buf_len = strlen(buff1);
        amtWritten = 0;
        rc = gsk_secure_soc_write(my_session_handle, buff1, buf_len, &amtWritten);
        if (amtWritten != buf_len) 
        {
            if (rc != GSK_OK)
            {
                printf("gsk_secure_soc_write() rc = %d and errno = %d.\n",rc,errno);
                printf("rc of %d means %s\n", rc, gsk_strerror(rc));
                break;
            } else {
                printf("gsk_secure_soc_write() did not write all data.\n");
                break;
            }
        }
        /* write results to screen */
        printf("gsk_secure_soc_write() wrote %d bytes...\n", amtWritten);
        printf("%s\n",buff1);
        /* memset buffer to hex zeros */
        memset((char *) buff2, 0x00, sizeof(buff2));
        /* receive a message from the client using the secure session */
        amtRead = 0;
        rc = gsk_secure_soc_read(my_session_handle, buff2, sizeof(buff2), &amtRead);
        if (rc != GSK_OK) { printf("gsk_secure_soc_read() rc = %d and errno = %d.\n",rc,errno);
            printf("rc of %d means %s\n", rc, gsk_strerror(rc));
            break;
        }
        /* write results to screen */
        printf("gsk_secure_soc_read() received %d bytes, here they are ...\n", amtRead);
        printf("%s\n",buff2);
    } while(FALSE);
    /* disable SSL support for the socket */
    if (my_session_handle != NULL) gsk_secure_soc_close(&my_session_handle);
    /* disable the SSL environment */
    if (my_env_handle != NULL) gsk_environment_close(&my_env_handle);
    /* close the connection */
    if (sd > -1) close(sd);
    return;
}