2 * Part of Very Secure FTPd
3 * Licence: GPL v2. Note that this code interfaces with with the OpenSSL
4 * libraries, so please read LICENSE where I give explicit permission to link
5 * against the OpenSSL libraries.
9 * Routines to handle a SSL/TLS-based implementation of RFC 2228, i.e.
22 #include "builddefs.h"
27 #include <openssl/ssl.h>
28 #include <openssl/err.h>
29 #include <openssl/rand.h>
30 #include <openssl/bio.h>
34 static char* get_ssl_error();
35 static SSL
* get_ssl(struct vsf_session
* p_sess
, int fd
);
36 static int ssl_session_init(struct vsf_session
* p_sess
);
37 static void setup_bio_callbacks();
38 static long bio_callback(
39 BIO
* p_bio
, int oper
, const char* p_arg
, int argi
, long argl
, long retval
);
40 static int ssl_verify_callback(int verify_ok
, X509_STORE_CTX
* p_ctx
);
41 static int ssl_cert_digest(
42 SSL
* p_ssl
, struct vsf_session
* p_sess
, struct mystr
* p_str
);
43 static void maybe_log_shutdown_state(struct vsf_session
* p_sess
);
44 static void maybe_log_ssl_error_state(struct vsf_session
* p_sess
, int ret
);
45 static int ssl_read_common(struct vsf_session
* p_sess
,
49 int (*p_ssl_func
)(SSL
*, void*, int));
51 static int ssl_inited
;
52 static struct mystr debug_str
;
55 ssl_init(struct vsf_session
* p_sess
)
61 int verify_option
= 0;
63 p_ctx
= SSL_CTX_new(SSLv23_server_method());
66 die("SSL: could not allocate SSL context");
71 options
|= SSL_OP_NO_SSLv2
;
75 options
|= SSL_OP_NO_SSLv3
;
79 options
|= SSL_OP_NO_TLSv1
;
81 SSL_CTX_set_options(p_ctx
, options
);
82 if (tunable_rsa_cert_file
)
84 const char* p_key
= tunable_rsa_private_key_file
;
87 p_key
= tunable_rsa_cert_file
;
89 if (SSL_CTX_use_certificate_chain_file(p_ctx
, tunable_rsa_cert_file
) != 1)
91 die("SSL: cannot load RSA certificate");
93 if (SSL_CTX_use_PrivateKey_file(p_ctx
, p_key
, X509_FILETYPE_PEM
) != 1)
95 die("SSL: cannot load RSA private key");
98 if (tunable_dsa_cert_file
)
100 const char* p_key
= tunable_dsa_private_key_file
;
103 p_key
= tunable_dsa_cert_file
;
105 if (SSL_CTX_use_certificate_chain_file(p_ctx
, tunable_dsa_cert_file
) != 1)
107 die("SSL: cannot load DSA certificate");
109 if (SSL_CTX_use_PrivateKey_file(p_ctx
, p_key
, X509_FILETYPE_PEM
) != 1)
111 die("SSL: cannot load DSA private key");
114 if (tunable_ssl_ciphers
&&
115 SSL_CTX_set_cipher_list(p_ctx
, tunable_ssl_ciphers
) != 1)
117 die("SSL: could not set cipher list");
119 if (RAND_status() != 1)
121 die("SSL: RNG is not seeded");
123 if (tunable_ssl_request_cert
)
125 verify_option
|= SSL_VERIFY_PEER
;
127 if (tunable_require_cert
)
129 verify_option
|= SSL_VERIFY_FAIL_IF_NO_PEER_CERT
;
133 SSL_CTX_set_verify(p_ctx
, verify_option
, ssl_verify_callback
);
134 if (tunable_ca_certs_file
)
136 STACK_OF(X509_NAME
)* p_names
;
137 if (!SSL_CTX_load_verify_locations(p_ctx
, tunable_ca_certs_file
, NULL
))
139 die("SSL: could not load verify file");
141 p_names
= SSL_load_client_CA_file(tunable_ca_certs_file
);
144 die("SSL: could not load client certs file");
146 SSL_CTX_set_client_CA_list(p_ctx
, p_names
);
150 static const char* p_ctx_id
= "vsftpd";
151 SSL_CTX_set_session_id_context(p_ctx
, (void*) p_ctx_id
,
152 vsf_sysutil_strlen(p_ctx_id
));
154 if (tunable_require_ssl_reuse
)
156 /* Ensure cached session doesn't expire */
157 SSL_CTX_set_timeout(p_ctx
, INT_MAX
);
159 p_sess
->p_ssl_ctx
= p_ctx
;
165 ssl_control_handshake(struct vsf_session
* p_sess
)
167 if (!ssl_session_init(p_sess
))
169 struct mystr err_str
= INIT_MYSTR
;
170 str_alloc_text(&err_str
, "Negotiation failed: ");
171 /* Technically, we shouldn't leak such detailed error messages. */
172 str_append_text(&err_str
, get_ssl_error());
173 vsf_cmdio_write_str(p_sess
, FTP_TLS_FAIL
, &err_str
);
176 p_sess
->control_use_ssl
= 1;
180 handle_auth(struct vsf_session
* p_sess
)
182 str_upper(&p_sess
->ftp_arg_str
);
183 if (str_equal_text(&p_sess
->ftp_arg_str
, "TLS") ||
184 str_equal_text(&p_sess
->ftp_arg_str
, "TLS-C") ||
185 str_equal_text(&p_sess
->ftp_arg_str
, "SSL") ||
186 str_equal_text(&p_sess
->ftp_arg_str
, "TLS-P"))
188 vsf_cmdio_write(p_sess
, FTP_AUTHOK
, "Proceed with negotiation.");
189 ssl_control_handshake(p_sess
);
190 if (str_equal_text(&p_sess
->ftp_arg_str
, "SSL") ||
191 str_equal_text(&p_sess
->ftp_arg_str
, "TLS-P"))
193 p_sess
->data_use_ssl
= 1;
198 vsf_cmdio_write(p_sess
, FTP_BADAUTH
, "Unknown AUTH type.");
203 handle_pbsz(struct vsf_session
* p_sess
)
205 if (!p_sess
->control_use_ssl
)
207 vsf_cmdio_write(p_sess
, FTP_BADPBSZ
, "PBSZ needs a secure connection.");
211 vsf_cmdio_write(p_sess
, FTP_PBSZOK
, "PBSZ set to 0.");
216 handle_prot(struct vsf_session
* p_sess
)
218 str_upper(&p_sess
->ftp_arg_str
);
219 if (!p_sess
->control_use_ssl
)
221 vsf_cmdio_write(p_sess
, FTP_BADPROT
, "PROT needs a secure connection.");
223 else if (str_equal_text(&p_sess
->ftp_arg_str
, "C"))
225 p_sess
->data_use_ssl
= 0;
226 vsf_cmdio_write(p_sess
, FTP_PROTOK
, "PROT now Clear.");
228 else if (str_equal_text(&p_sess
->ftp_arg_str
, "P"))
230 p_sess
->data_use_ssl
= 1;
231 vsf_cmdio_write(p_sess
, FTP_PROTOK
, "PROT now Private.");
233 else if (str_equal_text(&p_sess
->ftp_arg_str
, "S") ||
234 str_equal_text(&p_sess
->ftp_arg_str
, "E"))
236 vsf_cmdio_write(p_sess
, FTP_NOHANDLEPROT
, "PROT not supported.");
240 vsf_cmdio_write(p_sess
, FTP_NOSUCHPROT
, "PROT not recognized.");
245 ssl_read(struct vsf_session
* p_sess
, void* p_ssl
, char* p_buf
, unsigned int len
)
247 return ssl_read_common(p_sess
, (SSL
*) p_ssl
, p_buf
, len
, SSL_read
);
251 ssl_peek(struct vsf_session
* p_sess
, void* p_ssl
, char* p_buf
, unsigned int len
)
253 return ssl_read_common(p_sess
, (SSL
*) p_ssl
, p_buf
, len
, SSL_peek
);
257 ssl_read_common(struct vsf_session
* p_sess
,
261 int (*p_ssl_func
)(SSL
*, void*, int))
265 SSL
* p_ssl
= (SSL
*) p_void_ssl
;
268 retval
= (*p_ssl_func
)(p_ssl
, p_buf
, len
);
269 err
= SSL_get_error(p_ssl
, retval
);
271 while (retval
< 0 && (err
== SSL_ERROR_WANT_READ
||
272 err
== SSL_ERROR_WANT_WRITE
));
273 /* If we hit an EOF, make sure it was from the peer, not injected by the
276 if (retval
== 0 && SSL_get_shutdown(p_ssl
) != SSL_RECEIVED_SHUTDOWN
)
278 str_alloc_text(&debug_str
, "Connection terminated without SSL shutdown "
280 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
281 if (tunable_strict_ssl_read_eof
)
290 ssl_write(void* p_ssl
, const char* p_buf
, unsigned int len
)
296 retval
= SSL_write((SSL
*) p_ssl
, p_buf
, len
);
297 err
= SSL_get_error((SSL
*) p_ssl
, retval
);
299 while (retval
< 0 && (err
== SSL_ERROR_WANT_READ
||
300 err
== SSL_ERROR_WANT_WRITE
));
305 ssl_write_str(void* p_ssl
, const struct mystr
* p_str
)
307 unsigned int len
= str_getlen(p_str
);
308 int ret
= SSL_write((SSL
*) p_ssl
, str_getbuf(p_str
), len
);
309 if ((unsigned int) ret
!= len
)
317 ssl_read_into_str(struct vsf_session
* p_sess
, void* p_ssl
, struct mystr
* p_str
)
319 unsigned int len
= str_getlen(p_str
);
320 int ret
= ssl_read(p_sess
, p_ssl
, (char*) str_getbuf(p_str
), len
);
323 str_trunc(p_str
, (unsigned int) ret
);
333 maybe_log_shutdown_state(struct vsf_session
* p_sess
)
335 if (tunable_debug_ssl
)
337 int ret
= SSL_get_shutdown(p_sess
->p_data_ssl
);
338 str_alloc_text(&debug_str
, "SSL shutdown state is: ");
341 str_append_text(&debug_str
, "NONE");
343 else if (ret
== SSL_SENT_SHUTDOWN
)
345 str_append_text(&debug_str
, "SSL_SENT_SHUTDOWN");
347 else if (ret
== SSL_RECEIVED_SHUTDOWN
)
349 str_append_text(&debug_str
, "SSL_RECEIVED_SHUTDOWN");
353 str_append_ulong(&debug_str
, ret
);
355 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
360 maybe_log_ssl_error_state(struct vsf_session
* p_sess
, int ret
)
362 if (tunable_debug_ssl
)
364 str_alloc_text(&debug_str
, "SSL ret: ");
365 str_append_ulong(&debug_str
, ret
);
366 str_append_text(&debug_str
, ", SSL error: ");
367 str_append_text(&debug_str
, get_ssl_error());
368 str_append_text(&debug_str
, ", errno: ");
369 str_append_ulong(&debug_str
, errno
);
370 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
375 ssl_data_close(struct vsf_session
* p_sess
)
378 SSL
* p_ssl
= p_sess
->p_data_ssl
;
382 maybe_log_shutdown_state(p_sess
);
383 /* This is a mess. Ideally, when we're the sender, we'd like to get to the
384 * SSL_RECEIVED_SHUTDOWN state to get a cryptographic guarantee that the
385 * peer received all the data and shut the connection down cleanly. It
386 * doesn't matter hugely apart from logging, but it's a nagging detail.
387 * Unfortunately, no FTP client I found was able to get sends into that
388 * state, so the best we can do is issue SSL_shutdown but not check the
389 * errors / returns. At least this enables the receiver to be sure of the
390 * integrity of the send in terms of unwanted truncation.
392 ret
= SSL_shutdown(p_ssl
);
393 maybe_log_shutdown_state(p_sess
);
396 ret
= SSL_shutdown(p_ssl
);
397 maybe_log_shutdown_state(p_sess
);
400 if (tunable_strict_ssl_write_shutdown
)
404 maybe_log_shutdown_state(p_sess
);
405 maybe_log_ssl_error_state(p_sess
, ret
);
410 if (tunable_strict_ssl_write_shutdown
)
414 maybe_log_ssl_error_state(p_sess
, ret
);
417 p_sess
->p_data_ssl
= NULL
;
423 ssl_accept(struct vsf_session
* p_sess
, int fd
)
425 /* SECURITY: data SSL connections don't have any auth on them as part of the
426 * protocol. If a client sends an unfortunately optional client cert then
427 * we can check for a match between the control and data connections.
431 if (p_sess
->p_data_ssl
!= NULL
)
433 die("p_data_ssl should be NULL.");
435 p_ssl
= get_ssl(p_sess
, fd
);
440 p_sess
->p_data_ssl
= p_ssl
;
441 setup_bio_callbacks(p_ssl
);
442 reused
= SSL_session_reused(p_ssl
);
443 if (tunable_require_ssl_reuse
&& !reused
)
445 str_alloc_text(&debug_str
, "No SSL session reuse on data channel.");
446 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
447 ssl_data_close(p_sess
);
450 if (str_getlen(&p_sess
->control_cert_digest
) > 0)
452 static struct mystr data_cert_digest
;
453 if (!ssl_cert_digest(p_ssl
, p_sess
, &data_cert_digest
))
455 str_alloc_text(&debug_str
, "Missing cert on data channel.");
456 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
457 ssl_data_close(p_sess
);
460 if (str_strcmp(&p_sess
->control_cert_digest
, &data_cert_digest
))
462 str_alloc_text(&debug_str
, "DIFFERENT cert on data channel.");
463 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
464 ssl_data_close(p_sess
);
467 if (tunable_debug_ssl
)
469 str_alloc_text(&debug_str
, "Matching cert on data channel.");
470 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
477 ssl_comm_channel_init(struct vsf_session
* p_sess
)
479 if (p_sess
->ssl_consumer_fd
!= -1)
481 bug("ssl_consumer_fd active");
483 if (p_sess
->ssl_slave_fd
!= -1)
485 bug("ssl_slave_fd active");
487 const struct vsf_sysutil_socketpair_retval retval
=
488 vsf_sysutil_unix_stream_socketpair();
489 p_sess
->ssl_consumer_fd
= retval
.socket_one
;
490 p_sess
->ssl_slave_fd
= retval
.socket_two
;
494 ssl_comm_channel_set_consumer_context(struct vsf_session
* p_sess
)
496 if (p_sess
->ssl_slave_fd
== -1)
498 bug("ssl_slave_fd already closed");
500 vsf_sysutil_close(p_sess
->ssl_slave_fd
);
501 p_sess
->ssl_slave_fd
= -1;
505 ssl_comm_channel_set_producer_context(struct vsf_session
* p_sess
)
507 if (p_sess
->ssl_consumer_fd
== -1)
509 bug("ssl_consumer_fd already closed");
511 vsf_sysutil_close(p_sess
->ssl_consumer_fd
);
512 p_sess
->ssl_consumer_fd
= -1;
516 get_ssl(struct vsf_session
* p_sess
, int fd
)
518 SSL
* p_ssl
= SSL_new(p_sess
->p_ssl_ctx
);
521 if (tunable_debug_ssl
)
523 str_alloc_text(&debug_str
, "SSL_new failed");
524 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
528 if (!SSL_set_fd(p_ssl
, fd
))
530 if (tunable_debug_ssl
)
532 str_alloc_text(&debug_str
, "SSL_set_fd failed");
533 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
538 if (SSL_accept(p_ssl
) != 1)
540 const char* p_err
= get_ssl_error();
541 if (tunable_debug_ssl
)
543 str_alloc_text(&debug_str
, "SSL_accept failed: ");
544 str_append_text(&debug_str
, p_err
);
545 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
547 /* The RFC is quite clear that we can just close the control channel
552 if (tunable_debug_ssl
)
554 const char* p_ssl_version
= SSL_get_cipher_version(p_ssl
);
555 SSL_CIPHER
* p_ssl_cipher
= SSL_get_current_cipher(p_ssl
);
556 const char* p_cipher_name
= SSL_CIPHER_get_name(p_ssl_cipher
);
557 X509
* p_ssl_cert
= SSL_get_peer_certificate(p_ssl
);
558 int reused
= SSL_session_reused(p_ssl
);
559 str_alloc_text(&debug_str
, "SSL version: ");
560 str_append_text(&debug_str
, p_ssl_version
);
561 str_append_text(&debug_str
, ", SSL cipher: ");
562 str_append_text(&debug_str
, p_cipher_name
);
565 str_append_text(&debug_str
, ", reused");
569 str_append_text(&debug_str
, ", not reused");
571 if (p_ssl_cert
!= NULL
)
573 str_append_text(&debug_str
, ", CERT PRESENTED");
574 X509_free(p_ssl_cert
);
578 str_append_text(&debug_str
, ", no cert");
580 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
586 ssl_session_init(struct vsf_session
* p_sess
)
588 SSL
* p_ssl
= get_ssl(p_sess
, VSFTP_COMMAND_FD
);
593 p_sess
->p_control_ssl
= p_ssl
;
594 (void) ssl_cert_digest(p_ssl
, p_sess
, &p_sess
->control_cert_digest
);
595 setup_bio_callbacks(p_ssl
);
600 ssl_cert_digest(SSL
* p_ssl
, struct vsf_session
* p_sess
, struct mystr
* p_str
)
602 X509
* p_cert
= SSL_get_peer_certificate(p_ssl
);
603 unsigned int num_bytes
= 0;
608 str_reserve(p_str
, EVP_MAX_MD_SIZE
);
610 str_rpad(p_str
, EVP_MAX_MD_SIZE
);
611 if (!X509_digest(p_cert
, EVP_sha256(), (unsigned char*) str_getbuf(p_str
),
614 die("X509_digest failed");
617 if (tunable_debug_ssl
)
620 str_alloc_text(&debug_str
, "Cert digest:");
621 for (i
= 0; i
< num_bytes
; ++i
)
623 str_append_char(&debug_str
, ' ');
625 &debug_str
, (unsigned long) (unsigned char) str_get_char_at(p_str
, i
));
627 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
629 str_trunc(p_str
, num_bytes
);
636 SSL_load_error_strings();
637 return ERR_error_string(ERR_get_error(), NULL
);
640 static void setup_bio_callbacks(SSL
* p_ssl
)
642 BIO
* p_bio
= SSL_get_rbio(p_ssl
);
643 BIO_set_callback(p_bio
, bio_callback
);
644 p_bio
= SSL_get_wbio(p_ssl
);
645 BIO_set_callback(p_bio
, bio_callback
);
650 BIO
* p_bio
, int oper
, const char* p_arg
, int argi
, long argl
, long ret
)
657 if (oper
== (BIO_CB_READ
| BIO_CB_RETURN
) ||
658 oper
== (BIO_CB_WRITE
| BIO_CB_RETURN
))
661 fd
= BIO_get_fd(p_bio
, NULL
);
663 vsf_sysutil_check_pending_actions(kVSFSysUtilIO
, retval
, fd
);
668 ssl_verify_callback(int verify_ok
, X509_STORE_CTX
* p_ctx
)
671 if (tunable_validate_cert
)
679 ssl_add_entropy(struct vsf_session
* p_sess
)
681 /* Although each child does seem to have its different pool of entropy, I
682 * don't trust the interaction of OpenSSL's opaque RAND API and fork(). So
683 * throw a bit more in (only works on systems with /dev/urandom for now).
685 int ret
= RAND_load_file("/dev/urandom", 16);
688 str_alloc_text(&debug_str
, "Couldn't add extra OpenSSL entropy: ");
689 str_append_ulong(&debug_str
, (unsigned long) ret
);
690 vsf_log_line(p_sess
, kVSFLogEntryDebug
, &debug_str
);
694 #else /* VSF_BUILD_SSL */
697 ssl_init(struct vsf_session
* p_sess
)
700 die("SSL: ssl_enable is set but SSL support not compiled in");
704 ssl_control_handshake(struct vsf_session
* p_sess
)
710 handle_auth(struct vsf_session
* p_sess
)
716 handle_pbsz(struct vsf_session
* p_sess
)
722 handle_prot(struct vsf_session
* p_sess
)
728 ssl_read(struct vsf_session
* p_sess
, void* p_ssl
, char* p_buf
, unsigned int len
)
738 ssl_peek(struct vsf_session
* p_sess
, void* p_ssl
, char* p_buf
, unsigned int len
)
748 ssl_write(void* p_ssl
, const char* p_buf
, unsigned int len
)
757 ssl_write_str(void* p_ssl
, const struct mystr
* p_str
)
765 ssl_accept(struct vsf_session
* p_sess
, int fd
)
773 ssl_data_close(struct vsf_session
* p_sess
)
780 ssl_comm_channel_init(struct vsf_session
* p_sess
)
786 ssl_comm_channel_set_consumer_context(struct vsf_session
* p_sess
)
792 ssl_comm_channel_set_producer_context(struct vsf_session
* p_sess
)
798 ssl_add_entropy(struct vsf_session
* p_sess
)
804 ssl_read_into_str(struct vsf_session
* p_sess
, void* p_ssl
, struct mystr
* p_str
)
812 #endif /* VSF_BUILD_SSL */