ssl.c
上传用户:ig0539
上传日期:2022-05-21
资源大小:181k
文件大小:19k
- /*
- * Part of Very Secure FTPd
- * Licence: GPL v2. Note that this code interfaces with with the OpenSSL
- * libraries, so please read LICENSE where I give explicit permission to link
- * against the OpenSSL libraries.
- * Author: Chris Evans
- * ssl.c
- *
- * Routines to handle a SSL/TLS-based implementation of RFC 2228, i.e.
- * encryption.
- */
- #include "ssl.h"
- #include "session.h"
- #include "ftpcodes.h"
- #include "ftpcmdio.h"
- #include "defs.h"
- #include "str.h"
- #include "sysutil.h"
- #include "tunables.h"
- #include "utility.h"
- #include "builddefs.h"
- #include "logging.h"
- #ifdef VSF_BUILD_SSL
- #include <openssl/ssl.h>
- #include <openssl/err.h>
- #include <openssl/rand.h>
- #include <openssl/bio.h>
- #include <errno.h>
- #include <limits.h>
- static char* get_ssl_error();
- static SSL* get_ssl(struct vsf_session* p_sess, int fd);
- static int ssl_session_init(struct vsf_session* p_sess);
- static void setup_bio_callbacks();
- static long bio_callback(
- BIO* p_bio, int oper, const char* p_arg, int argi, long argl, long retval);
- static int ssl_verify_callback(int verify_ok, X509_STORE_CTX* p_ctx);
- static int ssl_cert_digest(
- SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str);
- static void maybe_log_shutdown_state(struct vsf_session* p_sess);
- static void maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret);
- static int ssl_read_common(struct vsf_session* p_sess,
- SSL* p_ssl,
- char* p_buf,
- unsigned int len,
- int (*p_ssl_func)(SSL*, void*, int));
- static int ssl_inited;
- static struct mystr debug_str;
- void
- ssl_init(struct vsf_session* p_sess)
- {
- if (!ssl_inited)
- {
- SSL_CTX* p_ctx;
- long options;
- int verify_option = 0;
- SSL_library_init();
- p_ctx = SSL_CTX_new(SSLv23_server_method());
- if (p_ctx == NULL)
- {
- die("SSL: could not allocate SSL context");
- }
- options = SSL_OP_ALL;
- if (!tunable_sslv2)
- {
- options |= SSL_OP_NO_SSLv2;
- }
- if (!tunable_sslv3)
- {
- options |= SSL_OP_NO_SSLv3;
- }
- if (!tunable_tlsv1)
- {
- options |= SSL_OP_NO_TLSv1;
- }
- SSL_CTX_set_options(p_ctx, options);
- if (tunable_rsa_cert_file)
- {
- const char* p_key = tunable_rsa_private_key_file;
- if (!p_key)
- {
- p_key = tunable_rsa_cert_file;
- }
- if (SSL_CTX_use_certificate_chain_file(p_ctx, tunable_rsa_cert_file) != 1)
- {
- die("SSL: cannot load RSA certificate");
- }
- if (SSL_CTX_use_PrivateKey_file(p_ctx, p_key, X509_FILETYPE_PEM) != 1)
- {
- die("SSL: cannot load RSA private key");
- }
- }
- if (tunable_dsa_cert_file)
- {
- const char* p_key = tunable_dsa_private_key_file;
- if (!p_key)
- {
- p_key = tunable_dsa_cert_file;
- }
- if (SSL_CTX_use_certificate_chain_file(p_ctx, tunable_dsa_cert_file) != 1)
- {
- die("SSL: cannot load DSA certificate");
- }
- if (SSL_CTX_use_PrivateKey_file(p_ctx, p_key, X509_FILETYPE_PEM) != 1)
- {
- die("SSL: cannot load DSA private key");
- }
- }
- if (tunable_ssl_ciphers &&
- SSL_CTX_set_cipher_list(p_ctx, tunable_ssl_ciphers) != 1)
- {
- die("SSL: could not set cipher list");
- }
- if (RAND_status() != 1)
- {
- die("SSL: RNG is not seeded");
- }
- if (tunable_ssl_request_cert)
- {
- verify_option |= SSL_VERIFY_PEER;
- }
- if (tunable_require_cert)
- {
- verify_option |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
- }
- if (verify_option)
- {
- SSL_CTX_set_verify(p_ctx, verify_option, ssl_verify_callback);
- if (tunable_ca_certs_file)
- {
- STACK_OF(X509_NAME)* p_names;
- if (!SSL_CTX_load_verify_locations(p_ctx, tunable_ca_certs_file, NULL))
- {
- die("SSL: could not load verify file");
- }
- p_names = SSL_load_client_CA_file(tunable_ca_certs_file);
- if (!p_names)
- {
- die("SSL: could not load client certs file");
- }
- SSL_CTX_set_client_CA_list(p_ctx, p_names);
- }
- }
- {
- static const char* p_ctx_id = "vsftpd";
- SSL_CTX_set_session_id_context(p_ctx, (void*) p_ctx_id,
- vsf_sysutil_strlen(p_ctx_id));
- }
- if (tunable_require_ssl_reuse)
- {
- /* Ensure cached session doesn't expire */
- SSL_CTX_set_timeout(p_ctx, INT_MAX);
- }
- p_sess->p_ssl_ctx = p_ctx;
- ssl_inited = 1;
- }
- }
- void
- ssl_control_handshake(struct vsf_session* p_sess)
- {
- if (!ssl_session_init(p_sess))
- {
- struct mystr err_str = INIT_MYSTR;
- str_alloc_text(&err_str, "Negotiation failed: ");
- /* Technically, we shouldn't leak such detailed error messages. */
- str_append_text(&err_str, get_ssl_error());
- vsf_cmdio_write_str(p_sess, FTP_TLS_FAIL, &err_str);
- vsf_sysutil_exit(0);
- }
- p_sess->control_use_ssl = 1;
- }
- void
- handle_auth(struct vsf_session* p_sess)
- {
- str_upper(&p_sess->ftp_arg_str);
- if (str_equal_text(&p_sess->ftp_arg_str, "TLS") ||
- str_equal_text(&p_sess->ftp_arg_str, "TLS-C") ||
- str_equal_text(&p_sess->ftp_arg_str, "SSL") ||
- str_equal_text(&p_sess->ftp_arg_str, "TLS-P"))
- {
- vsf_cmdio_write(p_sess, FTP_AUTHOK, "Proceed with negotiation.");
- ssl_control_handshake(p_sess);
- if (str_equal_text(&p_sess->ftp_arg_str, "SSL") ||
- str_equal_text(&p_sess->ftp_arg_str, "TLS-P"))
- {
- p_sess->data_use_ssl = 1;
- }
- }
- else
- {
- vsf_cmdio_write(p_sess, FTP_BADAUTH, "Unknown AUTH type.");
- }
- }
- void
- handle_pbsz(struct vsf_session* p_sess)
- {
- if (!p_sess->control_use_ssl)
- {
- vsf_cmdio_write(p_sess, FTP_BADPBSZ, "PBSZ needs a secure connection.");
- }
- else
- {
- vsf_cmdio_write(p_sess, FTP_PBSZOK, "PBSZ set to 0.");
- }
- }
- void
- handle_prot(struct vsf_session* p_sess)
- {
- str_upper(&p_sess->ftp_arg_str);
- if (!p_sess->control_use_ssl)
- {
- vsf_cmdio_write(p_sess, FTP_BADPROT, "PROT needs a secure connection.");
- }
- else if (str_equal_text(&p_sess->ftp_arg_str, "C"))
- {
- p_sess->data_use_ssl = 0;
- vsf_cmdio_write(p_sess, FTP_PROTOK, "PROT now Clear.");
- }
- else if (str_equal_text(&p_sess->ftp_arg_str, "P"))
- {
- p_sess->data_use_ssl = 1;
- vsf_cmdio_write(p_sess, FTP_PROTOK, "PROT now Private.");
- }
- else if (str_equal_text(&p_sess->ftp_arg_str, "S") ||
- str_equal_text(&p_sess->ftp_arg_str, "E"))
- {
- vsf_cmdio_write(p_sess, FTP_NOHANDLEPROT, "PROT not supported.");
- }
- else
- {
- vsf_cmdio_write(p_sess, FTP_NOSUCHPROT, "PROT not recognized.");
- }
- }
- int
- ssl_read(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len)
- {
- return ssl_read_common(p_sess, (SSL*) p_ssl, p_buf, len, SSL_read);
- }
- int
- ssl_peek(struct vsf_session* p_sess, void* p_ssl, char* p_buf, unsigned int len)
- {
- return ssl_read_common(p_sess, (SSL*) p_ssl, p_buf, len, SSL_peek);
- }
- static int
- ssl_read_common(struct vsf_session* p_sess,
- SSL* p_void_ssl,
- char* p_buf,
- unsigned int len,
- int (*p_ssl_func)(SSL*, void*, int))
- {
- int retval;
- int err;
- SSL* p_ssl = (SSL*) p_void_ssl;
- do
- {
- retval = (*p_ssl_func)(p_ssl, p_buf, len);
- err = SSL_get_error(p_ssl, retval);
- }
- while (retval < 0 && (err == SSL_ERROR_WANT_READ ||
- err == SSL_ERROR_WANT_WRITE));
- /* If we hit an EOF, make sure it was from the peer, not injected by the
- * attacker.
- */
- if (retval == 0 && SSL_get_shutdown(p_ssl) != SSL_RECEIVED_SHUTDOWN)
- {
- str_alloc_text(&debug_str, "Connection terminated without SSL shutdown "
- "- buggy client?");
- vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
- if (tunable_strict_ssl_read_eof)
- {
- return -1;
- }
- }
- return retval;
- }
- int
- ssl_write(void* p_ssl, const char* p_buf, unsigned int len)
- {
- int retval;
- int err;
- do
- {
- retval = SSL_write((SSL*) p_ssl, p_buf, len);
- err = SSL_get_error((SSL*) p_ssl, retval);
- }
- while (retval < 0 && (err == SSL_ERROR_WANT_READ ||
- err == SSL_ERROR_WANT_WRITE));
- return retval;
- }
- int
- ssl_write_str(void* p_ssl, const struct mystr* p_str)
- {
- unsigned int len = str_getlen(p_str);
- int ret = SSL_write((SSL*) p_ssl, str_getbuf(p_str), len);
- if ((unsigned int) ret != len)
- {
- return -1;
- }
- return 0;
- }
- int
- ssl_read_into_str(struct vsf_session* p_sess, void* p_ssl, struct mystr* p_str)
- {
- unsigned int len = str_getlen(p_str);
- int ret = ssl_read(p_sess, p_ssl, (char*) str_getbuf(p_str), len);
- if (ret >= 0)
- {
- str_trunc(p_str, (unsigned int) ret);
- }
- else
- {
- str_empty(p_str);
- }
- return ret;
- }
- static void
- maybe_log_shutdown_state(struct vsf_session* p_sess)
- {
- if (tunable_debug_ssl)
- {
- int ret = SSL_get_shutdown(p_sess->p_data_ssl);
- str_alloc_text(&debug_str, "SSL shutdown state is: ");
- if (ret == 0)
- {
- str_append_text(&debug_str, "NONE");
- }
- else if (ret == SSL_SENT_SHUTDOWN)
- {
- str_append_text(&debug_str, "SSL_SENT_SHUTDOWN");
- }
- else if (ret == SSL_RECEIVED_SHUTDOWN)
- {
- str_append_text(&debug_str, "SSL_RECEIVED_SHUTDOWN");
- }
- else
- {
- str_append_ulong(&debug_str, ret);
- }
- vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
- }
- }
- static void
- maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret)
- {
- if (tunable_debug_ssl)
- {
- str_alloc_text(&debug_str, "SSL ret: ");
- str_append_ulong(&debug_str, ret);
- str_append_text(&debug_str, ", SSL error: ");
- str_append_text(&debug_str, get_ssl_error());
- str_append_text(&debug_str, ", errno: ");
- str_append_ulong(&debug_str, errno);
- vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
- }
- }
- int
- ssl_data_close(struct vsf_session* p_sess)
- {
- int success = 1;
- SSL* p_ssl = p_sess->p_data_ssl;
- if (p_ssl)
- {
- 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;
- }
- int
- ssl_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;
- }
- void
- ssl_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;
- }
- void
- ssl_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;
- }
- void
- ssl_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 int
- ssl_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 int
- ssl_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 long
- bio_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 int
- ssl_verify_callback(int verify_ok, X509_STORE_CTX* p_ctx)
- {
- (void) p_ctx;
- if (tunable_validate_cert)
- {
- return verify_ok;
- }
- return 1;
- }
- void
- ssl_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 */
- void
- ssl_init(struct vsf_session* p_sess)
- {
- (void) p_sess;
- die("SSL: ssl_enable is set but SSL support not compiled in");
- }
- void
- ssl_control_handshake(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- void
- handle_auth(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- void
- handle_pbsz(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- void
- handle_prot(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- int
- ssl_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;
- }
- int
- ssl_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;
- }
- int
- ssl_write(void* p_ssl, const char* p_buf, unsigned int len)
- {
- (void) p_ssl;
- (void) p_buf;
- (void) len;
- return -1;
- }
- int
- ssl_write_str(void* p_ssl, const struct mystr* p_str)
- {
- (void) p_ssl;
- (void) p_str;
- return -1;
- }
- int
- ssl_accept(struct vsf_session* p_sess, int fd)
- {
- (void) p_sess;
- (void) fd;
- return -1;
- }
- int
- ssl_data_close(struct vsf_session* p_sess)
- {
- (void) p_sess;
- return 1;
- }
- void
- ssl_comm_channel_init(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- void
- ssl_comm_channel_set_consumer_context(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- void
- ssl_comm_channel_set_producer_context(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- void
- ssl_add_entropy(struct vsf_session* p_sess)
- {
- (void) p_sess;
- }
- int
- ssl_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 */