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

📄 ssl.c

📁 文件传输协议linux 下vsftpd2.1.0.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
    SSL_free(p_ssl);    p_sess->p_data_ssl = NULL;  }  return success;}intssl_accept(struct vsf_session* p_sess, int fd){  /* SECURITY: data SSL connections don't have any auth on them as part of the   * protocol. If a client sends an unfortunately optional client cert then   * we can check for a match between the control and data connections.   */  SSL* p_ssl;  int reused;  if (p_sess->p_data_ssl != NULL)  {    die("p_data_ssl should be NULL.");  }  p_ssl = get_ssl(p_sess, fd);  if (p_ssl == NULL)  {    return 0;  }  p_sess->p_data_ssl = p_ssl;  setup_bio_callbacks(p_ssl);  reused = SSL_session_reused(p_ssl);  if (tunable_require_ssl_reuse && !reused)  {    str_alloc_text(&debug_str, "No SSL session reuse on data channel.");    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);    ssl_data_close(p_sess);    return 0;  }  if (str_getlen(&p_sess->control_cert_digest) > 0)  {    static struct mystr data_cert_digest;    if (!ssl_cert_digest(p_ssl, p_sess, &data_cert_digest))    {      str_alloc_text(&debug_str, "Missing cert on data channel.");      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);      ssl_data_close(p_sess);      return 0;    }    if (str_strcmp(&p_sess->control_cert_digest, &data_cert_digest))    {      str_alloc_text(&debug_str, "DIFFERENT cert on data channel.");      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);      ssl_data_close(p_sess);      return 0;    }    if (tunable_debug_ssl)    {      str_alloc_text(&debug_str, "Matching cert on data channel.");      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);    }  }  return 1;}voidssl_comm_channel_init(struct vsf_session* p_sess){  if (p_sess->ssl_consumer_fd != -1)  {    bug("ssl_consumer_fd active");  }  if (p_sess->ssl_slave_fd != -1)  {    bug("ssl_slave_fd active");  }  const struct vsf_sysutil_socketpair_retval retval =    vsf_sysutil_unix_stream_socketpair();  p_sess->ssl_consumer_fd = retval.socket_one;  p_sess->ssl_slave_fd = retval.socket_two;}voidssl_comm_channel_set_consumer_context(struct vsf_session* p_sess){  if (p_sess->ssl_slave_fd == -1)  {    bug("ssl_slave_fd already closed");  }  vsf_sysutil_close(p_sess->ssl_slave_fd);  p_sess->ssl_slave_fd = -1;}voidssl_comm_channel_set_producer_context(struct vsf_session* p_sess){  if (p_sess->ssl_consumer_fd == -1)  {    bug("ssl_consumer_fd already closed");  }  vsf_sysutil_close(p_sess->ssl_consumer_fd);  p_sess->ssl_consumer_fd = -1;}static SSL*get_ssl(struct vsf_session* p_sess, int fd){  SSL* p_ssl = SSL_new(p_sess->p_ssl_ctx);  if (p_ssl == NULL)  {    if (tunable_debug_ssl)    {      str_alloc_text(&debug_str, "SSL_new failed");      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);    }    return NULL;  }  if (!SSL_set_fd(p_ssl, fd))  {    if (tunable_debug_ssl)    {      str_alloc_text(&debug_str, "SSL_set_fd failed");      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);    }    SSL_free(p_ssl);    return NULL;  }  if (SSL_accept(p_ssl) != 1)  {    const char* p_err = get_ssl_error();    if (tunable_debug_ssl)    {      str_alloc_text(&debug_str, "SSL_accept failed: ");      str_append_text(&debug_str, p_err);      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);    }    /* The RFC is quite clear that we can just close the control channel     * here.     */    die(p_err);  }  if (tunable_debug_ssl)  {    const char* p_ssl_version = SSL_get_cipher_version(p_ssl);    SSL_CIPHER* p_ssl_cipher = SSL_get_current_cipher(p_ssl);    const char* p_cipher_name = SSL_CIPHER_get_name(p_ssl_cipher);    X509* p_ssl_cert = SSL_get_peer_certificate(p_ssl);    int reused = SSL_session_reused(p_ssl);    str_alloc_text(&debug_str, "SSL version: ");    str_append_text(&debug_str, p_ssl_version);    str_append_text(&debug_str, ", SSL cipher: ");    str_append_text(&debug_str, p_cipher_name);    if (reused)    {      str_append_text(&debug_str, ", reused");    }    else    {      str_append_text(&debug_str, ", not reused");    }    if (p_ssl_cert != NULL)    {      str_append_text(&debug_str, ", CERT PRESENTED");      X509_free(p_ssl_cert);    }    else    {      str_append_text(&debug_str, ", no cert");    }    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);  }  return p_ssl;}static intssl_session_init(struct vsf_session* p_sess){  SSL* p_ssl = get_ssl(p_sess, VSFTP_COMMAND_FD);  if (p_ssl == NULL)  {    return 0;  }  p_sess->p_control_ssl = p_ssl;  (void) ssl_cert_digest(p_ssl, p_sess, &p_sess->control_cert_digest);  setup_bio_callbacks(p_ssl);  return 1;}static intssl_cert_digest(SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str){  X509* p_cert = SSL_get_peer_certificate(p_ssl);  unsigned int num_bytes = 0;  if (p_cert == NULL)  {    return 0;  }  str_reserve(p_str, EVP_MAX_MD_SIZE);  str_empty(p_str);  str_rpad(p_str, EVP_MAX_MD_SIZE);  if (!X509_digest(p_cert, EVP_sha256(), (unsigned char*) str_getbuf(p_str),                   &num_bytes))  {    die("X509_digest failed");  }  X509_free(p_cert);  if (tunable_debug_ssl)  {    unsigned int i;    str_alloc_text(&debug_str, "Cert digest:");    for (i = 0; i < num_bytes; ++i)    {       str_append_char(&debug_str, ' ');      str_append_ulong(        &debug_str, (unsigned long) (unsigned char) str_get_char_at(p_str, i));    }    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);  }  str_trunc(p_str, num_bytes);  return 1;}static char*get_ssl_error(){  SSL_load_error_strings();  return ERR_error_string(ERR_get_error(), NULL);}static void setup_bio_callbacks(SSL* p_ssl){  BIO* p_bio = SSL_get_rbio(p_ssl);  BIO_set_callback(p_bio, bio_callback);  p_bio = SSL_get_wbio(p_ssl);  BIO_set_callback(p_bio, bio_callback);}static longbio_callback(  BIO* p_bio, int oper, const char* p_arg, int argi, long argl, long ret){  int retval = 0;  int fd = 0;  (void) p_arg;  (void) argi;  (void) argl;  if (oper == (BIO_CB_READ | BIO_CB_RETURN) ||      oper == (BIO_CB_WRITE | BIO_CB_RETURN))  {    retval = (int) ret;    fd = BIO_get_fd(p_bio, NULL);  }  vsf_sysutil_check_pending_actions(kVSFSysUtilIO, retval, fd);  return ret;}static intssl_verify_callback(int verify_ok, X509_STORE_CTX* p_ctx){  (void) p_ctx;  if (tunable_validate_cert)  {    return verify_ok;  }  return 1;}voidssl_add_entropy(struct vsf_session* p_sess){  /* Although each child does seem to have its different pool of entropy, I   * don't trust the interaction of OpenSSL's opaque RAND API and fork(). So   * throw a bit more in (only works on systems with /dev/urandom for now).   */  int ret = RAND_load_file("/dev/urandom", 16);  if (ret != 16)  {    str_alloc_text(&debug_str, "Couldn't add extra OpenSSL entropy: ");    str_append_ulong(&debug_str, (unsigned long) ret);    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);  }}#else /* VSF_BUILD_SSL */voidssl_init(struct vsf_session* p_sess){  (void) p_sess;  die("SSL: ssl_enable is set but SSL support not compiled in");}voidssl_control_handshake(struct vsf_session* p_sess){  (void) p_sess;}voidhandle_auth(struct vsf_session* p_sess){  (void) p_sess;}voidhandle_pbsz(struct vsf_session* p_sess){  (void) p_sess;}voidhandle_prot(struct vsf_session* p_sess){  (void) p_sess;}intssl_read(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len){  (void) p_sess;  (void) p_ssl;  (void) p_buf;  (void) len;  return -1;}intssl_peek(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len){  (void) p_sess;  (void) p_ssl;  (void) p_buf;  (void) len;  return -1;}intssl_write(void* p_ssl, const char* p_buf, unsigned int len){  (void) p_ssl;  (void) p_buf;  (void) len;  return -1;}intssl_write_str(void* p_ssl, const struct mystr* p_str){  (void) p_ssl;  (void) p_str;  return -1;}intssl_accept(struct vsf_session* p_sess, int fd){  (void) p_sess;  (void) fd;  return -1;}intssl_data_close(struct vsf_session* p_sess){  (void) p_sess;  return 1;}voidssl_comm_channel_init(struct vsf_session* p_sess){  (void) p_sess;}voidssl_comm_channel_set_consumer_context(struct vsf_session* p_sess){  (void) p_sess;}voidssl_comm_channel_set_producer_context(struct vsf_session* p_sess){  (void) p_sess;}voidssl_add_entropy(struct vsf_session* p_sess){  (void) p_sess;}intssl_read_into_str(struct vsf_session* p_sess, void* p_ssl, struct mystr* p_str){  (void) p_sess;  (void) p_ssl;  (void) p_str;  return -1;}#endif /* VSF_BUILD_SSL */

⌨️ 快捷键说明

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