myssl_openssl.c

来自「网络爬虫程序」· C语言 代码 · 共 788 行 · 第 1/2 页

C
788
字号
      ok = 0;  }  switch (ctx->error)  {  case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:    X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);    DEBUG_SSL("Issuer: %s\n", buf);    break;  case X509_V_ERR_CERT_NOT_YET_VALID:  case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:    DEBUG_SSL("Error: SSL certificate not yet valid!\n");    break;  case X509_V_ERR_CERT_HAS_EXPIRED:  case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:    DEBUG_SSL("Error: SSL certificate has expired!\n");    break;  }  DEBUG_SSL("Verify status:%d\n", ok);  return ok;}void my_ssl_init_once(void){}void my_ssl_init_start(void){}void my_ssl_init(void){  unsigned char rnd_stack_data[64], *p = NULL;  int rv = 0;#ifdef HAVE_RAND_EGD  if(!RAND_status())  {    char random_dev[PATH_MAX + 1];    const char *p;    if(priv_cfg.egd_socket)    {      strncpy(random_dev, priv_cfg.egd_socket, PATH_MAX);      random_dev[PATH_MAX] = '\0';    }    else    {#ifdef EGD_SOCKET_NAME      strncpy(random_dev, EGD_SOCKET_NAME, PATH_MAX);      random_dev[PATH_MAX] = '\0';#else      /* we do not have /dev/random so need to seed         entropy pool from an external source */      p = RAND_file_name(random_dev, PATH_MAX + 1);      if(!p)      {        xprintf(1, gettext("Failed obtaining entropy pathname\n"));        rv = -1;      }#endif    }    if(rv != -1)    {      rv = RAND_egd(random_dev);      if(rv == -1)      {        xprintf(1,          gettext          ("Failed to initialize random seed for OpenSSL via EGD daemon\n"));      }    }  }#endif  if(rv == -1)  {    p = rnd_stack_data;    time((time_t *) p);    RAND_seed(rnd_stack_data, sizeof(rnd_stack_data));    xprintf(1, gettext("Seeding entropy pool INSECURELY!\n"));  }  SSL_load_error_strings();  SSLeay_add_ssl_algorithms();}void my_ssl_cleanup(void){}void my_ssl_connection_close(ssl_connection * con){  if(con->ssl_con)  {    SSL_set_shutdown(con->ssl_con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);    SSL_free(con->ssl_con);  }  if(con->ssl_ctx)    SSL_CTX_free(con->ssl_ctx);  if(con->socket)    bufio_close(con->socket);  con->ssl_con = NULL;  con->ssl_ctx = NULL;  con->socket = NULL;}void my_ssl_connection_destroy(ssl_connection * con){  my_ssl_connection_close(con);  _free(con);}static ssl_connection *my_ssl_connection_new(void){  ssl_connection *con;  con = _malloc(sizeof(ssl_connection));  con->ssl_con = NULL;  con->ssl_ctx = NULL;  con->socket = NULL;  return con;}bufio *my_ssl_do_connect(doc * docp, bufio * socket,  ssl_connection * parent_ssl_con){  SSL_METHOD *method;  BIO *bio;  ssl_connection *con;  int rv;  my_ssl_init();  if(priv_cfg.ssl_proxy)  {    if(http_dumy_proxy_connect(docp,        url_get_site(docp->doc_url), url_get_port(docp->doc_url),        priv_cfg.ssl_proxy, cfg.ssl_proxy_port))    {      docp->errcode = ERR_PROXY_CONNECT;      return FALSE;    }  }  con = my_ssl_connection_new();  switch (cfg.ssl_version)  {  case 2:    method = SSLv2_client_method();    break;  case 3:    method = SSLv3_client_method();    break;#ifdef WITH_SSL_TLS1  case 4:    method = TLSv1_client_method();    break;#endif  default:    method = SSLv23_client_method();    break;  }  con->ssl_ctx = SSL_CTX_new(method);  /* Bugs compatibility */  SSL_CTX_set_options(con->ssl_ctx, SSL_OP_ALL);  /* Modes of SSL_send() */  SSL_CTX_set_mode(con->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);  SSL_CTX_set_mode(con->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);  SSL_CTX_set_timeout(con->ssl_ctx, 3600);  if(cfg.unique_sslid)  {    /* Cache sessions */    DEBUG_SSL("Going to cache session ids!\n");    SSL_CTX_set_session_cache_mode(con->ssl_ctx, SSL_SESS_CACHE_CLIENT);    SSL_CTX_sess_set_cache_size(con->ssl_ctx, 16);    /*     * Session cache management.     */    SSL_CTX_sess_set_new_cb(con->ssl_ctx, ssl_new_session_cb);    SSL_CTX_sess_set_get_cb(con->ssl_ctx, ssl_get_session_cb);    SSL_CTX_sess_set_remove_cb(con->ssl_ctx, ssl_remove_session_cb);  }  if(cfg.condition.verify)  {    SSL_CTX_set_info_callback(con->ssl_ctx, my_ssl_info_callback);    SSL_CTX_set_verify(con->ssl_ctx, SSL_VERIFY_NONE, my_ssl_verify_callback);    SSL_CTX_set_verify_depth(con->ssl_ctx, 10);  }  if(priv_cfg.ssl_cipher_list)    SSL_CTX_set_cipher_list(con->ssl_ctx, priv_cfg.ssl_cipher_list);/* SSL Certification stuff */  if(priv_cfg.ssl_cert_file != NULL)  {    SSL *ssl;    X509 *x509;    DEBUG_SSL("Setting cert file to %s\n", priv_cfg.ssl_cert_file);    if(priv_cfg.ssl_cert_passwd)#ifdef OPENSSL      SSL_CTX_set_default_passwd_cb(con->ssl_ctx,        (pem_password_cb *) my_ssl_passwd_callback);#else      SSL_CTX_set_default_passwd_cb(con->ssl_ctx, my_ssl_passwd_callback);#endif    if(SSL_CTX_use_certificate_file(con->ssl_ctx,        priv_cfg.ssl_cert_file, SSL_FILETYPE_PEM) <= 0)    {      xprintf(1,        gettext("Unable to set certificate file (wrong password?)\n"));      my_ssl_connection_destroy(con);      return FALSE;    }    if(priv_cfg.ssl_key_file == NULL)      priv_cfg.ssl_key_file = tl_strdup(priv_cfg.ssl_cert_file);    if(SSL_CTX_use_PrivateKey_file(con->ssl_ctx,        priv_cfg.ssl_key_file, SSL_FILETYPE_PEM) <= 0)    {      xprintf(1, gettext("Unable to set public key file\n"));      my_ssl_connection_destroy(con);      return NULL;    }    ssl = SSL_new(con->ssl_ctx);    x509 = SSL_get_certificate(ssl);    if(x509 != NULL)      EVP_PKEY_copy_parameters(X509_get_pubkey(x509),        SSL_get_privatekey(ssl));    SSL_free(ssl);    if(!SSL_CTX_check_private_key(con->ssl_ctx))    {      xprintf(1,        gettext("Private key does not match the certificate public key\n"));      my_ssl_connection_destroy(con);      return NULL;    }  }/* End SSL Certification stuff */  con->ssl_con = SSL_new(con->ssl_ctx);  bio = BIO_new_socket(bufio_getfd(socket), BIO_NOCLOSE);  SSL_set_bio(con->ssl_con, bio, bio);  if(cfg.unique_sslid)  {    DEBUG_SSL("assigning caching SSL session ID\n");    ssl_assign_cached_session_by_doc(con->ssl_con, docp);  }  DEBUG_SSL("Connecting\n");  SSL_connect(con->ssl_con);  DEBUG_SSL("Connecting done\n");  while((rv = SSL_in_init(con->ssl_con)) &&    SSL_get_error(con->ssl_con, rv) == SSL_ERROR_WANT_CONNECT)  {    tl_msleep(2);  }  if(rv < 0)  {    SSL_get_error(con->ssl_con, -1);    ERR_print_errors_fp(stderr);    my_ssl_connection_destroy(con);    return NULL;  }  con->socket = socket;  return bufio_new_sslcon(socket, con);}int my_ssl_read(ssl_connection * ssl_con, char *buf, size_t len){  int rv = -1;  bool_t stopread = FALSE;  while(!stopread)  {    rv = SSL_read(ssl_con->ssl_con, buf, (int) len);    if(rv == 0)                 /* Nothing read */    {      stopread = TRUE;      break;    }    switch (SSL_get_error(ssl_con->ssl_con, rv))    {    case SSL_ERROR_WANT_READ:    case SSL_ERROR_WANT_WRITE:      tl_msleep(10);      break;    case SSL_ERROR_SSL:      ERR_print_errors_fp(stdout);      stopread = TRUE;      rv = -1;      break;    case SSL_ERROR_SYSCALL:      if((errno != EWOULDBLOCK) && (errno != EAGAIN))      {        len = 0;        stopread = TRUE;        rv = -1;      }      else        tl_msleep(10);      break;    default:      stopread = TRUE;      break;    }  }  return rv;}int my_ssl_write(ssl_connection * ssl_con, char *buf, size_t len){  int rv = 0;  while(len)  {    rv = SSL_write(ssl_con->ssl_con, buf, (int) len);    switch (SSL_get_error(ssl_con->ssl_con, rv))    {    case SSL_ERROR_NONE:      len -= rv;      buf += rv;      if(rv <= 0)        len = 0;      break;    case SSL_ERROR_WANT_WRITE:    case SSL_ERROR_WANT_READ:      tl_msleep(10);      break;    case SSL_ERROR_SSL:      ERR_print_errors_fp(stdout);      /* MJF: HACK -- ssl doesn't set errno, but because         of the -1 return, our caller will try to print         it, so we set errno to something "reasonable".       */      errno = EIO;      rv = -1;      len = 0;      break;    case SSL_ERROR_SYSCALL:      if((errno != EWOULDBLOCK) && (errno != EAGAIN))      {        len = 0;        rv = -1;      }      else        tl_msleep(10);      break;    default:      len = 0;      break;    }  }  return rv;}int my_ssl_data_pending(ssl_connection * ssl_con){  return SSL_pending(ssl_con->ssl_con);}void my_ssl_print_last_error(void){  ERR_print_errors_fp(stdout);}#endif

⌨️ 快捷键说明

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