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

📄 ssluse.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* Setup all the global SSL stuff */  SSLeay_add_ssl_algorithms();#else  /* SSL disabled, do nothing */#endif}/* Global cleanup */void Curl_SSL_cleanup(void){#ifdef USE_SSLEAY  if(init_ssl) {    /* only cleanup if we did a previous init */    /* Free the SSL error strings */    ERR_free_strings();      /* EVP_cleanup() removes all ciphers and digests from the       table. */    EVP_cleanup();#ifdef HAVE_ENGINE_cleanup    ENGINE_cleanup();#endif#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA    /* this function was not present in 0.9.6b, but was added sometimes       later */    CRYPTO_cleanup_all_ex_data();#endif    init_ssl=0; /* not inited any more */  }#else  /* SSL disabled, do nothing */#endif}#ifdef USE_SSLEAY/* * This function is called when an SSL connection is closed. */void Curl_SSL_Close(struct connectdata *conn){  if(conn->ssl.use) {    /*      ERR_remove_state() frees the error queue associated with      thread pid.  If pid == 0, the current thread will have its      error queue removed.      Since error queue data structures are allocated      automatically for new threads, they must be freed when      threads are terminated in oder to avoid memory leaks.    */    ERR_remove_state(0);    if(conn->ssl.handle) {      (void)SSL_shutdown(conn->ssl.handle);      SSL_set_connect_state(conn->ssl.handle);      SSL_free (conn->ssl.handle);      conn->ssl.handle = NULL;    }    if(conn->ssl.ctx) {      SSL_CTX_free (conn->ssl.ctx);      conn->ssl.ctx = NULL;    }    conn->ssl.use = FALSE; /* get back to ordinary socket usage */  }}/* * This sets up a session cache to the specified size. */CURLcode Curl_SSL_InitSessions(struct SessionHandle *data, long amount){  struct curl_ssl_session *session;  if(data->state.session)    /* this is just a precaution to prevent multiple inits */    return CURLE_OK;  session = (struct curl_ssl_session *)    malloc(amount * sizeof(struct curl_ssl_session));  if(!session)    return CURLE_OUT_OF_MEMORY;  /* "blank out" the newly allocated memory */  memset(session, 0, amount * sizeof(struct curl_ssl_session));  /* store the info in the SSL section */  data->set.ssl.numsessions = amount;  data->state.session = session;  data->state.sessionage = 1; /* this is brand new */  return CURLE_OK;}/* * Check if there's a session ID for the given connection in the cache, * and if there's one suitable, it is returned. */static int Get_SSL_Session(struct connectdata *conn,                           SSL_SESSION **ssl_sessionid){  struct curl_ssl_session *check;  struct SessionHandle *data = conn->data;  long i;  for(i=0; i< data->set.ssl.numsessions; i++) {    check = &data->state.session[i];    if(!check->sessionid)      /* not session ID means blank entry */      continue;    if(curl_strequal(conn->name, check->name) &&       (conn->remote_port == check->remote_port) &&       Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {      /* yes, we have a session ID! */      data->state.sessionage++;            /* increase general age */      check->age = data->state.sessionage; /* set this as used in this age */      *ssl_sessionid = check->sessionid;      return FALSE;    }  }  *ssl_sessionid = (SSL_SESSION *)NULL;  return TRUE;}/* * Kill a single session ID entry in the cache. */static int Kill_Single_Session(struct curl_ssl_session *session){  if(session->sessionid) {    /* defensive check */    /* free the ID */    SSL_SESSION_free(session->sessionid);    session->sessionid=NULL;    session->age = 0; /* fresh */    Curl_free_ssl_config(&session->ssl_config);    free(session->name);    session->name = NULL; /* no name */    return 0; /* ok */  }  else    return 1;}/* * This function is called when the 'data' struct is going away. Close * down everything and free all resources! */int Curl_SSL_Close_All(struct SessionHandle *data){  int i;  if(data->state.session) {        for(i=0; i< data->set.ssl.numsessions; i++)      /* the single-killer function handles empty table slots */      Kill_Single_Session(&data->state.session[i]);        /* free the cache data */    free(data->state.session);  }#ifdef HAVE_OPENSSL_ENGINE_H  if(data->engine)  {    ENGINE_free(data->engine);    data->engine = NULL;  }#endif  return 0;}/* * Extract the session id and store it in the session cache. */static int Store_SSL_Session(struct connectdata *conn){  SSL_SESSION *ssl_sessionid;  int i;  struct SessionHandle *data=conn->data; /* the mother of all structs */  struct curl_ssl_session *store = &data->state.session[0];  int oldest_age=data->state.session[0].age; /* zero if unused */  /* ask OpenSSL, say please */#ifdef HAVE_SSL_GET1_SESSION  ssl_sessionid = SSL_get1_session(conn->ssl.handle);  /* SSL_get1_session() will increment the reference     count and the session will stay in memory until explicitly freed with     SSL_SESSION_free(3), regardless of its state.      This function was introduced in openssl 0.9.5a. */#else  ssl_sessionid = SSL_get_session(conn->ssl.handle);  /* if SSL_get1_session() is unavailable, use SSL_get_session().     This is an inferior option because the session can be flushed     at any time by openssl. It is included only so curl compiles     under versions of openssl < 0.9.5a.          WARNING: How curl behaves if it's session is flushed is     untested.   */#endif  /* Now we should add the session ID and the host name to the cache, (remove     the oldest if necessary) */  /* find an empty slot for us, or find the oldest */  for(i=1; (i<data->set.ssl.numsessions) &&        data->state.session[i].sessionid; i++) {    if(data->state.session[i].age < oldest_age) {      oldest_age = data->state.session[i].age;      store = &data->state.session[i];    }  }  if(i == data->set.ssl.numsessions)    /* cache is full, we must "kill" the oldest entry! */    Kill_Single_Session(store);  else    store = &data->state.session[i]; /* use this slot */    /* now init the session struct wisely */  store->sessionid = ssl_sessionid;  store->age = data->state.sessionage;      /* set current age */  store->name = strdup(conn->name);       /* clone host name */  store->remote_port = conn->remote_port; /* port number */  Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config);  return 0;}static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,                                    const char *prefix,                                    ASN1_UTCTIME *tm){  char *asn1_string;  int gmt=FALSE;  int i;  int year=0,month=0,day=0,hour=0,minute=0,second=0;  struct SessionHandle *data = conn->data;  if(!data->set.verbose)    return 0;  i=tm->length;  asn1_string=(char *)tm->data;  if(i < 10)    return 1;  if(asn1_string[i-1] == 'Z')    gmt=TRUE;  for (i=0; i<10; i++)    if((asn1_string[i] > '9') || (asn1_string[i] < '0'))      return 2;  year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');  if(year < 50)    year+=100;  month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');  if((month > 12) || (month < 1))    return 3;  day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');  hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');  minute=  (asn1_string[8]-'0')*10+(asn1_string[9]-'0');  if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&     (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))    second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');    infof(data,        "%s%04d-%02d-%02d %02d:%02d:%02d %s\n",        prefix, year+1900, month, day, hour, minute, second, (gmt?"GMT":""));  return 0;}#endif  /* ====================================================== */#ifdef USE_SSLEAYstatic intcert_hostcheck(const char *certname, const char *hostname){  char *tmp;  const char *certdomain;    if(!certname ||     strlen(certname)<3 ||     !hostname ||     !strlen(hostname)) /* sanity check */    return 0;  if(curl_strequal(certname, hostname)) /* trivial case */    return 1;  certdomain = certname + 1;  if((certname[0] != '*') || (certdomain[0] != '.'))    return 0; /* not a wildcard certificate, check failed */    if(!strchr(certdomain+1, '.'))    return 0; /* the certificate must have at least another dot in its name */  /* find 'certdomain' within 'hostname' */  tmp = strstr(hostname, certdomain);  if(tmp) {    /* ok the certname's domain matches the hostname, let's check that it's a       tail-match */    if(curl_strequal(tmp, certdomain))      /* looks like a match. Just check we havent swallowed a '.' */      return tmp == strchr(hostname, '.');    else      return 0;  }  return 0;}/* Quote from RFC2818 section 3.1 "Server Identity"   If a subjectAltName extension of type dNSName is present, that MUST   be used as the identity. Otherwise, the (most specific) Common Name   field in the Subject field of the certificate MUST be used. Although   the use of the Common Name is existing practice, it is deprecated and   Certification Authorities are encouraged to use the dNSName instead.   Matching is performed using the matching rules specified by   [RFC2459].  If more than one identity of a given type is present in   the certificate (e.g., more than one dNSName name, a match in any one   of the set is considered acceptable.) Names may contain the wildcard   character * which is considered to match any single domain name   component or component fragment. E.g., *.a.com matches foo.a.com but   not bar.foo.a.com. f*.com matches foo.com but not bar.com.   In some cases, the URI is specified as an IP address rather than a   hostname. In this case, the iPAddress subjectAltName must be present   in the certificate and must exactly match the IP in the URI.*/static CURLcode verifyhost(struct connectdata *conn){  char peer_CN[257];  bool matched = FALSE; /* no alternative match yet */  int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */  int addrlen;  struct SessionHandle *data = conn->data;  STACK_OF(GENERAL_NAME) *altnames;#ifdef ENABLE_IPV6  struct in6_addr addr;#else  struct in_addr addr;#endif #ifdef ENABLE_IPV6  if(conn->bits.ipv6_ip &&      Curl_inet_pton(AF_INET6, conn->hostname, &addr)) {    target = GEN_IPADD;    addrlen = sizeof(struct in6_addr);  }  else#endif    if(Curl_inet_pton(AF_INET, conn->hostname, &addr)) {      target = GEN_IPADD;      addrlen = sizeof(struct in_addr);    }    /* get a "list" of alternative names */  altnames = X509_get_ext_d2i(conn->ssl.server_cert, NID_subject_alt_name,                              NULL, NULL);    if(altnames) {    int hostlen;    int domainlen;    char *domain;    int numalts;    int i;            if(GEN_DNS == target) {      hostlen = strlen(conn->hostname);      domain = strchr(conn->hostname, '.');      if(domain)        domainlen = strlen(domain);    }    /* get amount of alternatives, RFC2459 claims there MUST be at least       one, but we don't depend on it... */    numalts = sk_GENERAL_NAME_num(altnames);    /* loop through all alternatives while none has matched */    for (i=0; (i<numalts) && !matched; i++) {      /* get a handle to alternative name number i */      const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);      /* only check alternatives of the same type the target is */      if(check->type == target) {        /* get data and length */        const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);        const int altlen = ASN1_STRING_length(check->d.ia5);        switch(target) {        case GEN_DNS: /* name comparison */          /* Is this an exact match? */          if((hostlen == altlen) &&             curl_strnequal(conn->hostname, altptr, hostlen))

⌨️ 快捷键说明

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