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 + -
显示快捷键?