Annotation of embedaddon/curl/lib/vtls/mesalink.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
! 9: * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
! 10: *
! 11: * This software is licensed as described in the file COPYING, which
! 12: * you should have received as part of this distribution. The terms
! 13: * are also available at https://curl.haxx.se/docs/copyright.html.
! 14: *
! 15: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
! 16: * copies of the Software, and permit persons to whom the Software is
! 17: * furnished to do so, under the terms of the COPYING file.
! 18: *
! 19: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
! 20: * KIND, either express or implied.
! 21: *
! 22: ***************************************************************************/
! 23:
! 24: /*
! 25: * Source file for all MesaLink-specific code for the TLS/SSL layer. No code
! 26: * but vtls.c should ever call or use these functions.
! 27: *
! 28: */
! 29:
! 30: /*
! 31: * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
! 32: * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
! 33: *
! 34: * Thanks for code and inspiration!
! 35: */
! 36:
! 37: #include "curl_setup.h"
! 38:
! 39: #ifdef USE_MESALINK
! 40:
! 41: #include <mesalink/options.h>
! 42: #include <mesalink/version.h>
! 43:
! 44: #include "urldata.h"
! 45: #include "sendf.h"
! 46: #include "inet_pton.h"
! 47: #include "vtls.h"
! 48: #include "parsedate.h"
! 49: #include "connect.h" /* for the connect timeout */
! 50: #include "select.h"
! 51: #include "strcase.h"
! 52: #include "x509asn1.h"
! 53: #include "curl_printf.h"
! 54:
! 55: #include "mesalink.h"
! 56: #include <mesalink/openssl/ssl.h>
! 57: #include <mesalink/openssl/err.h>
! 58:
! 59: /* The last #include files should be: */
! 60: #include "curl_memory.h"
! 61: #include "memdebug.h"
! 62:
! 63: #define MESALINK_MAX_ERROR_SZ 80
! 64:
! 65: struct ssl_backend_data
! 66: {
! 67: SSL_CTX *ctx;
! 68: SSL *handle;
! 69: };
! 70:
! 71: #define BACKEND connssl->backend
! 72:
! 73: static Curl_recv mesalink_recv;
! 74: static Curl_send mesalink_send;
! 75:
! 76: static int do_file_type(const char *type)
! 77: {
! 78: if(!type || !type[0])
! 79: return SSL_FILETYPE_PEM;
! 80: if(strcasecompare(type, "PEM"))
! 81: return SSL_FILETYPE_PEM;
! 82: if(strcasecompare(type, "DER"))
! 83: return SSL_FILETYPE_ASN1;
! 84: return -1;
! 85: }
! 86:
! 87: /*
! 88: * This function loads all the client/CA certificates and CRLs. Setup the TLS
! 89: * layer and do all necessary magic.
! 90: */
! 91: static CURLcode
! 92: mesalink_connect_step1(struct connectdata *conn, int sockindex)
! 93: {
! 94: char *ciphers;
! 95: struct Curl_easy *data = conn->data;
! 96: struct ssl_connect_data *connssl = &conn->ssl[sockindex];
! 97: struct in_addr addr4;
! 98: #ifdef ENABLE_IPV6
! 99: struct in6_addr addr6;
! 100: #endif
! 101: const char *const hostname =
! 102: SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name;
! 103: size_t hostname_len = strlen(hostname);
! 104:
! 105: SSL_METHOD *req_method = NULL;
! 106: curl_socket_t sockfd = conn->sock[sockindex];
! 107:
! 108: if(connssl->state == ssl_connection_complete)
! 109: return CURLE_OK;
! 110:
! 111: if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
! 112: failf(data, "MesaLink does not support to set maximum SSL/TLS version");
! 113: return CURLE_SSL_CONNECT_ERROR;
! 114: }
! 115:
! 116: switch(SSL_CONN_CONFIG(version)) {
! 117: case CURL_SSLVERSION_SSLv3:
! 118: case CURL_SSLVERSION_TLSv1:
! 119: case CURL_SSLVERSION_TLSv1_0:
! 120: case CURL_SSLVERSION_TLSv1_1:
! 121: failf(data, "MesaLink does not support SSL 3.0, TLS 1.0, or TLS 1.1");
! 122: return CURLE_NOT_BUILT_IN;
! 123: case CURL_SSLVERSION_DEFAULT:
! 124: case CURL_SSLVERSION_TLSv1_2:
! 125: req_method = TLSv1_2_client_method();
! 126: break;
! 127: case CURL_SSLVERSION_TLSv1_3:
! 128: req_method = TLSv1_3_client_method();
! 129: break;
! 130: case CURL_SSLVERSION_SSLv2:
! 131: failf(data, "MesaLink does not support SSLv2");
! 132: return CURLE_SSL_CONNECT_ERROR;
! 133: default:
! 134: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
! 135: return CURLE_SSL_CONNECT_ERROR;
! 136: }
! 137:
! 138: if(!req_method) {
! 139: failf(data, "SSL: couldn't create a method!");
! 140: return CURLE_OUT_OF_MEMORY;
! 141: }
! 142:
! 143: if(BACKEND->ctx)
! 144: SSL_CTX_free(BACKEND->ctx);
! 145: BACKEND->ctx = SSL_CTX_new(req_method);
! 146:
! 147: if(!BACKEND->ctx) {
! 148: failf(data, "SSL: couldn't create a context!");
! 149: return CURLE_OUT_OF_MEMORY;
! 150: }
! 151:
! 152: SSL_CTX_set_verify(
! 153: BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ?
! 154: SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
! 155:
! 156: if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) {
! 157: if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile),
! 158: SSL_CONN_CONFIG(CApath))) {
! 159: if(SSL_CONN_CONFIG(verifypeer)) {
! 160: failf(data,
! 161: "error setting certificate verify locations:\n"
! 162: " CAfile: %s\n CApath: %s",
! 163: SSL_CONN_CONFIG(CAfile) ?
! 164: SSL_CONN_CONFIG(CAfile) : "none",
! 165: SSL_CONN_CONFIG(CApath) ?
! 166: SSL_CONN_CONFIG(CApath) : "none");
! 167: return CURLE_SSL_CACERT_BADFILE;
! 168: }
! 169: infof(data,
! 170: "error setting certificate verify locations,"
! 171: " continuing anyway:\n");
! 172: }
! 173: else {
! 174: infof(data, "successfully set certificate verify locations:\n");
! 175: }
! 176: infof(data,
! 177: " CAfile: %s\n"
! 178: " CApath: %s\n",
! 179: SSL_CONN_CONFIG(CAfile)?
! 180: SSL_CONN_CONFIG(CAfile): "none",
! 181: SSL_CONN_CONFIG(CApath)?
! 182: SSL_CONN_CONFIG(CApath): "none");
! 183: }
! 184:
! 185: if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
! 186: int file_type = do_file_type(SSL_SET_OPTION(cert_type));
! 187:
! 188: if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx, SSL_SET_OPTION(cert),
! 189: file_type) != 1) {
! 190: failf(data, "unable to use client certificate (no key or wrong pass"
! 191: " phrase?)");
! 192: return CURLE_SSL_CONNECT_ERROR;
! 193: }
! 194:
! 195: file_type = do_file_type(SSL_SET_OPTION(key_type));
! 196: if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
! 197: file_type) != 1) {
! 198: failf(data, "unable to set private key");
! 199: return CURLE_SSL_CONNECT_ERROR;
! 200: }
! 201: infof(data,
! 202: "client cert: %s\n",
! 203: SSL_CONN_CONFIG(clientcert)?
! 204: SSL_CONN_CONFIG(clientcert): "none");
! 205: }
! 206:
! 207: ciphers = SSL_CONN_CONFIG(cipher_list);
! 208: if(ciphers) {
! 209: #ifdef MESALINK_HAVE_CIPHER
! 210: if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
! 211: failf(data, "failed setting cipher list: %s", ciphers);
! 212: return CURLE_SSL_CIPHER;
! 213: }
! 214: #endif
! 215: infof(data, "Cipher selection: %s\n", ciphers);
! 216: }
! 217:
! 218: if(BACKEND->handle)
! 219: SSL_free(BACKEND->handle);
! 220: BACKEND->handle = SSL_new(BACKEND->ctx);
! 221: if(!BACKEND->handle) {
! 222: failf(data, "SSL: couldn't create a context (handle)!");
! 223: return CURLE_OUT_OF_MEMORY;
! 224: }
! 225:
! 226: if((hostname_len < USHRT_MAX) &&
! 227: (0 == Curl_inet_pton(AF_INET, hostname, &addr4))
! 228: #ifdef ENABLE_IPV6
! 229: && (0 == Curl_inet_pton(AF_INET6, hostname, &addr6))
! 230: #endif
! 231: ) {
! 232: /* hostname is not a valid IP address */
! 233: if(SSL_set_tlsext_host_name(BACKEND->handle, hostname) != SSL_SUCCESS) {
! 234: failf(data,
! 235: "WARNING: failed to configure server name indication (SNI) "
! 236: "TLS extension\n");
! 237: return CURLE_SSL_CONNECT_ERROR;
! 238: }
! 239: }
! 240: else {
! 241: #ifdef CURLDEBUG
! 242: /* Check if the hostname is 127.0.0.1 or [::1];
! 243: * otherwise reject because MesaLink always wants a valid DNS Name
! 244: * specified in RFC 5280 Section 7.2 */
! 245: if(strncmp(hostname, "127.0.0.1", 9) == 0
! 246: #ifdef ENABLE_IPV6
! 247: || strncmp(hostname, "[::1]", 5) == 0
! 248: #endif
! 249: ) {
! 250: SSL_set_tlsext_host_name(BACKEND->handle, "localhost");
! 251: }
! 252: else
! 253: #endif
! 254: {
! 255: failf(data,
! 256: "ERROR: MesaLink does not accept an IP address as a hostname\n");
! 257: return CURLE_SSL_CONNECT_ERROR;
! 258: }
! 259: }
! 260:
! 261: #ifdef MESALINK_HAVE_SESSION
! 262: if(SSL_SET_OPTION(primary.sessionid)) {
! 263: void *ssl_sessionid = NULL;
! 264:
! 265: Curl_ssl_sessionid_lock(conn);
! 266: if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
! 267: /* we got a session id, use it! */
! 268: if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
! 269: Curl_ssl_sessionid_unlock(conn);
! 270: failf(
! 271: data,
! 272: "SSL: SSL_set_session failed: %s",
! 273: ERR_error_string(SSL_get_error(BACKEND->handle, 0), error_buffer));
! 274: return CURLE_SSL_CONNECT_ERROR;
! 275: }
! 276: /* Informational message */
! 277: infof(data, "SSL re-using session ID\n");
! 278: }
! 279: Curl_ssl_sessionid_unlock(conn);
! 280: }
! 281: #endif /* MESALINK_HAVE_SESSION */
! 282:
! 283: if(SSL_set_fd(BACKEND->handle, (int)sockfd) != SSL_SUCCESS) {
! 284: failf(data, "SSL: SSL_set_fd failed");
! 285: return CURLE_SSL_CONNECT_ERROR;
! 286: }
! 287:
! 288: connssl->connecting_state = ssl_connect_2;
! 289: return CURLE_OK;
! 290: }
! 291:
! 292: static CURLcode
! 293: mesalink_connect_step2(struct connectdata *conn, int sockindex)
! 294: {
! 295: int ret = -1;
! 296: struct Curl_easy *data = conn->data;
! 297: struct ssl_connect_data *connssl = &conn->ssl[sockindex];
! 298:
! 299: conn->recv[sockindex] = mesalink_recv;
! 300: conn->send[sockindex] = mesalink_send;
! 301:
! 302: ret = SSL_connect(BACKEND->handle);
! 303: if(ret != SSL_SUCCESS) {
! 304: int detail = SSL_get_error(BACKEND->handle, ret);
! 305:
! 306: if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) {
! 307: connssl->connecting_state = ssl_connect_2_reading;
! 308: return CURLE_OK;
! 309: }
! 310: else {
! 311: char error_buffer[MESALINK_MAX_ERROR_SZ];
! 312: failf(data,
! 313: "SSL_connect failed with error %d: %s",
! 314: detail,
! 315: ERR_error_string_n(detail, error_buffer, sizeof(error_buffer)));
! 316: ERR_print_errors_fp(stderr);
! 317: if(detail && SSL_CONN_CONFIG(verifypeer)) {
! 318: detail &= ~0xFF;
! 319: if(detail == TLS_ERROR_WEBPKI_ERRORS) {
! 320: failf(data, "Cert verify failed");
! 321: return CURLE_PEER_FAILED_VERIFICATION;
! 322: }
! 323: }
! 324: return CURLE_SSL_CONNECT_ERROR;
! 325: }
! 326: }
! 327:
! 328: connssl->connecting_state = ssl_connect_3;
! 329: infof(data,
! 330: "SSL connection using %s / %s\n",
! 331: SSL_get_version(BACKEND->handle),
! 332: SSL_get_cipher_name(BACKEND->handle));
! 333:
! 334: return CURLE_OK;
! 335: }
! 336:
! 337: static CURLcode
! 338: mesalink_connect_step3(struct connectdata *conn, int sockindex)
! 339: {
! 340: CURLcode result = CURLE_OK;
! 341: struct ssl_connect_data *connssl = &conn->ssl[sockindex];
! 342:
! 343: DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
! 344:
! 345: #ifdef MESALINK_HAVE_SESSION
! 346: if(SSL_SET_OPTION(primary.sessionid)) {
! 347: bool incache;
! 348: SSL_SESSION *our_ssl_sessionid;
! 349: void *old_ssl_sessionid = NULL;
! 350:
! 351: our_ssl_sessionid = SSL_get_session(BACKEND->handle);
! 352:
! 353: Curl_ssl_sessionid_lock(conn);
! 354: incache =
! 355: !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex));
! 356: if(incache) {
! 357: if(old_ssl_sessionid != our_ssl_sessionid) {
! 358: infof(data, "old SSL session ID is stale, removing\n");
! 359: Curl_ssl_delsessionid(conn, old_ssl_sessionid);
! 360: incache = FALSE;
! 361: }
! 362: }
! 363:
! 364: if(!incache) {
! 365: result = Curl_ssl_addsessionid(
! 366: conn, our_ssl_sessionid, 0 /* unknown size */, sockindex);
! 367: if(result) {
! 368: Curl_ssl_sessionid_unlock(conn);
! 369: failf(data, "failed to store ssl session");
! 370: return result;
! 371: }
! 372: }
! 373: Curl_ssl_sessionid_unlock(conn);
! 374: }
! 375: #endif /* MESALINK_HAVE_SESSION */
! 376:
! 377: connssl->connecting_state = ssl_connect_done;
! 378:
! 379: return result;
! 380: }
! 381:
! 382: static ssize_t
! 383: mesalink_send(struct connectdata *conn, int sockindex, const void *mem,
! 384: size_t len, CURLcode *curlcode)
! 385: {
! 386: struct ssl_connect_data *connssl = &conn->ssl[sockindex];
! 387: char error_buffer[MESALINK_MAX_ERROR_SZ];
! 388: int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
! 389: int rc = SSL_write(BACKEND->handle, mem, memlen);
! 390:
! 391: if(rc < 0) {
! 392: int err = SSL_get_error(BACKEND->handle, rc);
! 393: switch(err) {
! 394: case SSL_ERROR_WANT_READ:
! 395: case SSL_ERROR_WANT_WRITE:
! 396: /* there's data pending, re-invoke SSL_write() */
! 397: *curlcode = CURLE_AGAIN;
! 398: return -1;
! 399: default:
! 400: failf(conn->data,
! 401: "SSL write: %s, errno %d",
! 402: ERR_error_string_n(err, error_buffer, sizeof(error_buffer)),
! 403: SOCKERRNO);
! 404: *curlcode = CURLE_SEND_ERROR;
! 405: return -1;
! 406: }
! 407: }
! 408: return rc;
! 409: }
! 410:
! 411: static void
! 412: Curl_mesalink_close(struct connectdata *conn, int sockindex)
! 413: {
! 414: struct ssl_connect_data *connssl = &conn->ssl[sockindex];
! 415:
! 416: if(BACKEND->handle) {
! 417: (void)SSL_shutdown(BACKEND->handle);
! 418: SSL_free(BACKEND->handle);
! 419: BACKEND->handle = NULL;
! 420: }
! 421: if(BACKEND->ctx) {
! 422: SSL_CTX_free(BACKEND->ctx);
! 423: BACKEND->ctx = NULL;
! 424: }
! 425: }
! 426:
! 427: static ssize_t
! 428: mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize,
! 429: CURLcode *curlcode)
! 430: {
! 431: struct ssl_connect_data *connssl = &conn->ssl[num];
! 432: char error_buffer[MESALINK_MAX_ERROR_SZ];
! 433: int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
! 434: int nread = SSL_read(BACKEND->handle, buf, buffsize);
! 435:
! 436: if(nread <= 0) {
! 437: int err = SSL_get_error(BACKEND->handle, nread);
! 438:
! 439: switch(err) {
! 440: case SSL_ERROR_ZERO_RETURN: /* no more data */
! 441: case IO_ERROR_CONNECTION_ABORTED:
! 442: break;
! 443: case SSL_ERROR_WANT_READ:
! 444: case SSL_ERROR_WANT_WRITE:
! 445: /* there's data pending, re-invoke SSL_read() */
! 446: *curlcode = CURLE_AGAIN;
! 447: return -1;
! 448: default:
! 449: failf(conn->data,
! 450: "SSL read: %s, errno %d",
! 451: ERR_error_string_n(err, error_buffer, sizeof(error_buffer)),
! 452: SOCKERRNO);
! 453: *curlcode = CURLE_RECV_ERROR;
! 454: return -1;
! 455: }
! 456: }
! 457: return nread;
! 458: }
! 459:
! 460: static size_t
! 461: Curl_mesalink_version(char *buffer, size_t size)
! 462: {
! 463: return msnprintf(buffer, size, "MesaLink/%s", MESALINK_VERSION_STRING);
! 464: }
! 465:
! 466: static int
! 467: Curl_mesalink_init(void)
! 468: {
! 469: return (SSL_library_init() == SSL_SUCCESS);
! 470: }
! 471:
! 472: /*
! 473: * This function is called to shut down the SSL layer but keep the
! 474: * socket open (CCC - Clear Command Channel)
! 475: */
! 476: static int
! 477: Curl_mesalink_shutdown(struct connectdata *conn, int sockindex)
! 478: {
! 479: int retval = 0;
! 480: struct ssl_connect_data *connssl = &conn->ssl[sockindex];
! 481:
! 482: if(BACKEND->handle) {
! 483: SSL_free(BACKEND->handle);
! 484: BACKEND->handle = NULL;
! 485: }
! 486: return retval;
! 487: }
! 488:
! 489: static CURLcode
! 490: mesalink_connect_common(struct connectdata *conn, int sockindex,
! 491: bool nonblocking, bool *done)
! 492: {
! 493: CURLcode result;
! 494: struct Curl_easy *data = conn->data;
! 495: struct ssl_connect_data *connssl = &conn->ssl[sockindex];
! 496: curl_socket_t sockfd = conn->sock[sockindex];
! 497: timediff_t timeout_ms;
! 498: int what;
! 499:
! 500: /* check if the connection has already been established */
! 501: if(ssl_connection_complete == connssl->state) {
! 502: *done = TRUE;
! 503: return CURLE_OK;
! 504: }
! 505:
! 506: if(ssl_connect_1 == connssl->connecting_state) {
! 507: /* Find out how much more time we're allowed */
! 508: timeout_ms = Curl_timeleft(data, NULL, TRUE);
! 509:
! 510: if(timeout_ms < 0) {
! 511: /* no need to continue if time already is up */
! 512: failf(data, "SSL connection timeout");
! 513: return CURLE_OPERATION_TIMEDOUT;
! 514: }
! 515:
! 516: result = mesalink_connect_step1(conn, sockindex);
! 517: if(result)
! 518: return result;
! 519: }
! 520:
! 521: while(ssl_connect_2 == connssl->connecting_state ||
! 522: ssl_connect_2_reading == connssl->connecting_state ||
! 523: ssl_connect_2_writing == connssl->connecting_state) {
! 524:
! 525: /* check allowed time left */
! 526: timeout_ms = Curl_timeleft(data, NULL, TRUE);
! 527:
! 528: if(timeout_ms < 0) {
! 529: /* no need to continue if time already is up */
! 530: failf(data, "SSL connection timeout");
! 531: return CURLE_OPERATION_TIMEDOUT;
! 532: }
! 533:
! 534: /* if ssl is expecting something, check if it's available. */
! 535: if(connssl->connecting_state == ssl_connect_2_reading ||
! 536: connssl->connecting_state == ssl_connect_2_writing) {
! 537:
! 538: curl_socket_t writefd =
! 539: ssl_connect_2_writing == connssl->connecting_state ? sockfd
! 540: : CURL_SOCKET_BAD;
! 541: curl_socket_t readfd = ssl_connect_2_reading == connssl->connecting_state
! 542: ? sockfd
! 543: : CURL_SOCKET_BAD;
! 544:
! 545: what = Curl_socket_check(
! 546: readfd, CURL_SOCKET_BAD, writefd,
! 547: nonblocking ? 0 : (time_t)timeout_ms);
! 548: if(what < 0) {
! 549: /* fatal error */
! 550: failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
! 551: return CURLE_SSL_CONNECT_ERROR;
! 552: }
! 553: else if(0 == what) {
! 554: if(nonblocking) {
! 555: *done = FALSE;
! 556: return CURLE_OK;
! 557: }
! 558: else {
! 559: /* timeout */
! 560: failf(data, "SSL connection timeout");
! 561: return CURLE_OPERATION_TIMEDOUT;
! 562: }
! 563: }
! 564: /* socket is readable or writable */
! 565: }
! 566:
! 567: /* Run transaction, and return to the caller if it failed or if
! 568: * this connection is part of a multi handle and this loop would
! 569: * execute again. This permits the owner of a multi handle to
! 570: * abort a connection attempt before step2 has completed while
! 571: * ensuring that a client using select() or epoll() will always
! 572: * have a valid fdset to wait on.
! 573: */
! 574: result = mesalink_connect_step2(conn, sockindex);
! 575:
! 576: if(result ||
! 577: (nonblocking && (ssl_connect_2 == connssl->connecting_state ||
! 578: ssl_connect_2_reading == connssl->connecting_state ||
! 579: ssl_connect_2_writing == connssl->connecting_state))) {
! 580: return result;
! 581: }
! 582: } /* repeat step2 until all transactions are done. */
! 583:
! 584: if(ssl_connect_3 == connssl->connecting_state) {
! 585: result = mesalink_connect_step3(conn, sockindex);
! 586: if(result)
! 587: return result;
! 588: }
! 589:
! 590: if(ssl_connect_done == connssl->connecting_state) {
! 591: connssl->state = ssl_connection_complete;
! 592: conn->recv[sockindex] = mesalink_recv;
! 593: conn->send[sockindex] = mesalink_send;
! 594: *done = TRUE;
! 595: }
! 596: else
! 597: *done = FALSE;
! 598:
! 599: /* Reset our connect state machine */
! 600: connssl->connecting_state = ssl_connect_1;
! 601:
! 602: return CURLE_OK;
! 603: }
! 604:
! 605: static CURLcode
! 606: Curl_mesalink_connect_nonblocking(struct connectdata *conn, int sockindex,
! 607: bool *done)
! 608: {
! 609: return mesalink_connect_common(conn, sockindex, TRUE, done);
! 610: }
! 611:
! 612: static CURLcode
! 613: Curl_mesalink_connect(struct connectdata *conn, int sockindex)
! 614: {
! 615: CURLcode result;
! 616: bool done = FALSE;
! 617:
! 618: result = mesalink_connect_common(conn, sockindex, FALSE, &done);
! 619: if(result)
! 620: return result;
! 621:
! 622: DEBUGASSERT(done);
! 623:
! 624: return CURLE_OK;
! 625: }
! 626:
! 627: static void *
! 628: Curl_mesalink_get_internals(struct ssl_connect_data *connssl,
! 629: CURLINFO info UNUSED_PARAM)
! 630: {
! 631: (void)info;
! 632: return BACKEND->handle;
! 633: }
! 634:
! 635: const struct Curl_ssl Curl_ssl_mesalink = {
! 636: { CURLSSLBACKEND_MESALINK, "MesaLink" }, /* info */
! 637:
! 638: SSLSUPP_SSL_CTX,
! 639:
! 640: sizeof(struct ssl_backend_data),
! 641:
! 642: Curl_mesalink_init, /* init */
! 643: Curl_none_cleanup, /* cleanup */
! 644: Curl_mesalink_version, /* version */
! 645: Curl_none_check_cxn, /* check_cxn */
! 646: Curl_mesalink_shutdown, /* shutdown */
! 647: Curl_none_data_pending, /* data_pending */
! 648: Curl_none_random, /* random */
! 649: Curl_none_cert_status_request, /* cert_status_request */
! 650: Curl_mesalink_connect, /* connect */
! 651: Curl_mesalink_connect_nonblocking, /* connect_nonblocking */
! 652: Curl_mesalink_get_internals, /* get_internals */
! 653: Curl_mesalink_close, /* close_one */
! 654: Curl_none_close_all, /* close_all */
! 655: Curl_none_session_free, /* session_free */
! 656: Curl_none_set_engine, /* set_engine */
! 657: Curl_none_set_engine_default, /* set_engine_default */
! 658: Curl_none_engines_list, /* engines_list */
! 659: Curl_none_false_start, /* false_start */
! 660: Curl_none_md5sum, /* md5sum */
! 661: NULL /* sha256sum */
! 662: };
! 663:
! 664: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>