⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssluse.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 3 页
字号:
            matched = TRUE;                  /* Is this a wildcard match? */          else if((altptr[0] == '*') &&                  (domainlen == altlen-1) &&                  curl_strnequal(domain, altptr+1, domainlen))            matched = TRUE;          break;                  case GEN_IPADD: /* IP address comparison */                    /* compare alternative IP address if the data chunk is the same size             our server IP address is */          if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))            matched = TRUE;          break;        }      }    }    GENERAL_NAMES_free(altnames);  }   if(matched)    /* an alternative name matched the server hostname */    infof(data, "\t subjectAltName: %s matched\n", conn->hostname);  else {    bool obtain=FALSE;    if(X509_NAME_get_text_by_NID(X509_get_subject_name(conn->ssl.server_cert),                                 NID_commonName,                                 peer_CN,                                 sizeof(peer_CN)) < 0) {      if(data->set.ssl.verifyhost > 1) {        failf(data,              "SSL: unable to obtain common name from peer certificate");        X509_free(conn->ssl.server_cert);        return CURLE_SSL_PEER_CERTIFICATE;      }      else {        /* Consider verifyhost == 1 as an "OK" for a missing CN field, but we           output a note about the situation */        infof(data, "\t common name: WARNING couldn't obtain\n");      }    }    else      obtain = TRUE;             if(obtain) {      if(!cert_hostcheck(peer_CN, conn->hostname)) {        if(data->set.ssl.verifyhost > 1) {          failf(data, "SSL: certificate subject name '%s' does not match "                "target host name '%s'", peer_CN, conn->hostname);          X509_free(conn->ssl.server_cert);          return CURLE_SSL_PEER_CERTIFICATE;        }        else          infof(data, "\t common name: %s (does not match '%s')\n",                peer_CN, conn->hostname);      }      else        infof(data, "\t common name: %s (matched)\n", peer_CN);    }  }  return CURLE_OK;}#endif/* ====================================================== */CURLcodeCurl_SSLConnect(struct connectdata *conn){  CURLcode retcode = CURLE_OK;#ifdef USE_SSLEAY  struct SessionHandle *data = conn->data;  int err;  int what;  char * str;  SSL_METHOD *req_method;  SSL_SESSION *ssl_sessionid=NULL;  ASN1_TIME *certdate;  /* mark this is being ssl enabled from here on out. */  conn->ssl.use = TRUE;  if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) {    /* Make funny stuff to get random input */    random_the_seed(data);    ssl_seeded = TRUE;  }  /* check to see if we've been told to use an explicit SSL/TLS version */  switch(data->set.ssl.version) {  default:  case CURL_SSLVERSION_DEFAULT:    /* we try to figure out version */    req_method = SSLv23_client_method();    break;  case CURL_SSLVERSION_TLSv1:    req_method = TLSv1_client_method();    break;  case CURL_SSLVERSION_SSLv2:    req_method = SSLv2_client_method();    break;  case CURL_SSLVERSION_SSLv3:    req_method = SSLv3_client_method();    break;  }      conn->ssl.ctx = SSL_CTX_new(req_method);  if(!conn->ssl.ctx) {    failf(data, "SSL: couldn't create a context!");    return CURLE_OUT_OF_MEMORY;  }  /* OpenSSL contains code to work-around lots of bugs and flaws in various     SSL-implementations. SSL_CTX_set_options() is used to enabled those     work-arounds. The man page for this option states that SSL_OP_ALL enables     ll the work-arounds and that "It is usually safe to use SSL_OP_ALL to     enable the bug workaround options if compatibility with somewhat broken     implementations is desired."  */  SSL_CTX_set_options(conn->ssl.ctx, SSL_OP_ALL);      if(data->set.cert) {    if(!cert_stuff(conn,                   data->set.cert,                   data->set.cert_type,                   data->set.key,                   data->set.key_type)) {      /* failf() is already done in cert_stuff() */      return CURLE_SSL_CERTPROBLEM;    }  }  if(data->set.ssl.cipher_list) {    if(!SSL_CTX_set_cipher_list(conn->ssl.ctx,                                data->set.ssl.cipher_list)) {      failf(data, "failed setting cipher list");      return CURLE_SSL_CIPHER;    }  }  if (data->set.ssl.CAfile || data->set.ssl.CApath) {    /* tell SSL where to find CA certificates that are used to verify       the servers certificate. */    if (!SSL_CTX_load_verify_locations(conn->ssl.ctx, data->set.ssl.CAfile,                                       data->set.ssl.CApath)) {      if (data->set.ssl.verifypeer) { 	/* Fail if we insist on successfully verifying the server. */        failf(data,"error setting certificate verify locations:\n"              "  CAfile: %s\n  CApath: %s\n",              data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",              data->set.ssl.CApath ? data->set.ssl.CApath : "none");        return CURLE_SSL_CACERT;      }      else {        /* Just continue with a warning if no strict  certificate verification           is required. */        infof(data,"error setting certificate verify locations,"              " continuing anyway:\n");        infof(data, "  CAfile: %s\n",              data->set.ssl.CAfile ? data->set.ssl.CAfile : "none");        infof(data, "  CApath: %s\n",              data->set.ssl.CApath ? data->set.ssl.CApath : "none");      }    }    else {      /* Everything is fine. */      infof(data,"successfully set certificate verify locations:\n");      infof(data, "  CAfile: %s\n",            data->set.ssl.CAfile ? data->set.ssl.CAfile : "none");      infof(data, "  CApath: %s\n",            data->set.ssl.CApath ? data->set.ssl.CApath : "none");    }  }  /* SSL always tries to verify the peer, this only says whether it should   * fail to connect if the verification fails, or if it should continue   * anyway. In the latter case the result of the verification is checked with   * SSL_get_verify_result() below. */  SSL_CTX_set_verify(conn->ssl.ctx,                     data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,                     cert_verify_callback);  /* give application a chance to interfere with SSL set up. */  if(data->set.ssl.fsslctx) {    retcode = (*data->set.ssl.fsslctx)(data, conn->ssl.ctx,                                       data->set.ssl.fsslctxp);    if(retcode) {      failf(data,"error signaled by ssl ctx callback");      return retcode;    }  }  /* Lets make an SSL structure */  conn->ssl.handle = SSL_new (conn->ssl.ctx);  SSL_set_connect_state (conn->ssl.handle);  conn->ssl.server_cert = 0x0;  if(!conn->bits.reuse) {    /* We're not re-using a connection, check if there's a cached ID we       can/should use here! */    if(!Get_SSL_Session(conn, &ssl_sessionid)) {      /* we got a session id, use it! */      SSL_set_session(conn->ssl.handle, ssl_sessionid);      /* Informational message */      infof (data, "SSL re-using session ID\n");    }  }  /* pass the raw socket into the SSL layers */  SSL_set_fd(conn->ssl.handle, conn->firstsocket);  do {    fd_set writefd;    fd_set readfd;    struct timeval interval;    long timeout_ms;    /* Find out if any timeout is set. If not, use 300 seconds.       Otherwise, figure out the most strict timeout of the two possible one       and then how much time that has elapsed to know how much time we       allow for the connect call */    if(data->set.timeout || data->set.connecttimeout) {      double has_passed;      /* Evaluate in milliseconds how much time that has passed */      has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);#ifndef min#define min(a, b)   ((a) < (b) ? (a) : (b))#endif      /* get the most strict timeout of the ones converted to milliseconds */      if(data->set.timeout &&         (data->set.timeout>data->set.connecttimeout))        timeout_ms = data->set.timeout*1000;      else        timeout_ms = data->set.connecttimeout*1000;            /* subtract the passed time */      timeout_ms -= (long)has_passed;            if(timeout_ms < 0) {        /* a precaution, no need to continue if time already is up */        failf(data, "SSL connection timeout");        return CURLE_OPERATION_TIMEOUTED;      }    }    else      /* no particular time-out has been set */      timeout_ms=300000; /* milliseconds, default to five minutes */    FD_ZERO(&writefd);    FD_ZERO(&readfd);    err = SSL_connect(conn->ssl.handle);    /* 1  is fine       0  is "not successful but was shut down controlled"       <0 is "handshake was not successful, because a fatal error occurred" */    if(1 != err) {      int detail = SSL_get_error(conn->ssl.handle, err);      if(SSL_ERROR_WANT_READ == detail)        FD_SET(conn->firstsocket, &readfd);      else if(SSL_ERROR_WANT_WRITE == detail)        FD_SET(conn->firstsocket, &writefd);      else {        /* untreated error */        char error_buffer[120]; /* OpenSSL documents that this must be at least                                   120 bytes long. */        detail = ERR_get_error(); /* Gets the earliest error code from the                                     thread's error queue and removes the                                     entry. */        switch(detail) {        case 0x1407E086:          /* 1407E086:             SSL routines:             SSL2_SET_CERTIFICATE:             certificate verify failed */        case 0x14090086:          /* 14090086:             SSL routines:             SSL3_GET_SERVER_CERTIFICATE:             certificate verify failed */          failf(data,                "SSL certificate problem, verify that the CA cert is OK");          return CURLE_SSL_CACERT;        default:          /* detail is already set to the SSL error above */          failf(data, "SSL: %s", ERR_error_string(detail, error_buffer));          /* OpenSSL 0.9.6 and later has a function named             ERRO_error_string_n() that takes the size of the buffer as a third             argument, and we should possibly switch to using that one in the             future. */          return CURLE_SSL_CONNECT_ERROR;        }      }    }    else      /* we have been connected fine, get out of the connect loop */      break;    interval.tv_sec = timeout_ms/1000;    timeout_ms -= interval.tv_sec*1000;    interval.tv_usec = timeout_ms*1000;    what = select(conn->firstsocket+1, &readfd, &writefd, NULL, &interval);    if(what > 0)      /* reabable or writable, go loop yourself */      continue;    else if(0 == what) {      /* timeout */      failf(data, "SSL connection timeout");      return CURLE_OPERATION_TIMEOUTED;    }    else      break; /* get out of loop */  } while(1);  /* Informational message */  infof (data, "SSL connection using %s\n",         SSL_get_cipher(conn->ssl.handle));  if(!ssl_sessionid) {    /* Since this is not a cached session ID, then we want to stach this one       in the cache! */    Store_SSL_Session(conn);  }    /* Get server's certificate (note: beware of dynamic allocation) - opt */  /* major serious hack alert -- we should check certificates   * to authenticate the server; otherwise we risk man-in-the-middle   * attack   */  conn->ssl.server_cert = SSL_get_peer_certificate(conn->ssl.handle);  if(!conn->ssl.server_cert) {    failf(data, "SSL: couldn't get peer certificate!");    return CURLE_SSL_PEER_CERTIFICATE;  }  infof (data, "Server certificate:\n");    str = X509_NAME_oneline(X509_get_subject_name(conn->ssl.server_cert),                          NULL, 0);  if(!str) {    failf(data, "SSL: couldn't get X509-subject!");    X509_free(conn->ssl.server_cert);    return CURLE_SSL_CONNECT_ERROR;  }  infof(data, "\t subject: %s\n", str);  CRYPTO_free(str);  certdate = X509_get_notBefore(conn->ssl.server_cert);  Curl_ASN1_UTCTIME_output(conn, "\t start date: ", certdate);  certdate = X509_get_notAfter(conn->ssl.server_cert);  Curl_ASN1_UTCTIME_output(conn, "\t expire date: ", certdate);  if(data->set.ssl.verifyhost) {    retcode = verifyhost(conn);    if(retcode) {      X509_free(conn->ssl.server_cert);      return retcode;    }  }  str = X509_NAME_oneline(X509_get_issuer_name(conn->ssl.server_cert),                          NULL, 0);  if(!str) {    failf(data, "SSL: couldn't get X509-issuer name!");    retcode = CURLE_SSL_CONNECT_ERROR;  }  else {    infof(data, "\t issuer: %s\n", str);    CRYPTO_free(str);    /* We could do all sorts of certificate verification stuff here before       deallocating the certificate. */        data->set.ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);    if(data->set.ssl.certverifyresult != X509_V_OK) {      if(data->set.ssl.verifypeer) {        /* We probably never reach this, because SSL_connect() will fail           and we return earlyer if verifypeer is set? */        failf(data, "SSL certificate verify result: %d",              data->set.ssl.certverifyresult);        retcode = CURLE_SSL_PEER_CERTIFICATE;      }      else        infof(data, "SSL certificate verify result: %d, continuing anyway.\n",              data->set.ssl.certverifyresult);    }    else      infof(data, "SSL certificate verify ok.\n");  }  X509_free(conn->ssl.server_cert);#else /* USE_SSLEAY */  /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */  (void) conn;#endif  return retcode;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -