int ssl_handshake(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."); } /* Initiate the SSL connection by either calling accept or connect */ 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; }
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; setup_bio_callbacks(p_ssl); return 1; }
int ssl_accept(struct vsf_session* p_sess, int fd) { SSL* 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); return 1; }