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

📄 ssl.c

📁 linux下的轻量级的ftp服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
  {    int ret;    maybe_log_shutdown_state(p_sess);    // This is a mess. Ideally, when we're the sender, we'd like to get to the    // SSL_RECEIVED_SHUTDOWN state to get a cryptographic guarantee that the    // peer received all the data and shut the connection down cleanly. It    // doesn't matter hugely apart from logging, but it's a nagging detail.    // Unfortunately, no FTP client I found was able to get sends into that    // state, so the best we can do is issue SSL_shutdown but not check the    // errors / returns. At least this enables the receiver to be sure of the    // integrity of the send in terms of unwanted truncation.    ret = SSL_shutdown(p_ssl);    maybe_log_shutdown_state(p_sess);    if (ret == 0)    {      ret = SSL_shutdown(p_ssl);      maybe_log_shutdown_state(p_sess);      if (ret != 1)      {        if (tunable_strict_ssl_write_shutdown)        {          success = 0;        }        maybe_log_shutdown_state(p_sess);        maybe_log_ssl_error_state(p_sess, ret);      }    }    else if (ret < 0)    {      if (tunable_strict_ssl_write_shutdown)      {        success = 0;      }      maybe_log_ssl_error_state(p_sess, ret);    }    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;  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);  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))    {      if (tunable_debug_ssl)      {        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))    {      if (tunable_debug_ssl)      {        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){  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;}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);    }    die(p_err);    SSL_free(p_ssl);    return NULL;  }  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);    int reused = SSL_session_reused(p_ssl);    X509* p_ssl_cert = SSL_get_peer_certificate(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;}#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");}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;}voidssl_getline(const struct vsf_session* p_sess, struct mystr* p_str,            char end_char, char* p_buf, unsigned int buflen){  (void) p_sess;  (void) p_str;  (void) end_char;  (void) p_buf;  (void) buflen;}intssl_read(struct vsf_session* p_sess, char* p_buf, unsigned int len){  (void) p_sess;  (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;}#endif /* VSF_BUILD_SSL */

⌨️ 快捷键说明

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