libsodium: Needed for Dnscrypto-proxy Release 1.3.0
[tomato.git] / release / src / router / vsftpd / sslslave.c
blobd2b0953e74c3d63e040de8c30bcb812ea6c1fdb7
1 /*
2 * Part of Very Secure FTPd
3 * Licence: GPL v2
4 * Author: Chris Evans
5 * sslslave.c
6 */
8 #include "sslslave.h"
9 #include "session.h"
10 #include "privsock.h"
11 #include "tunables.h"
12 #include "sysutil.h"
13 #include "sysdeputil.h"
14 #include "utility.h"
15 #include "ssl.h"
16 #include "readwrite.h"
17 #include "defs.h"
19 void
20 ssl_slave(struct vsf_session* p_sess)
22 struct mystr data_str = INIT_MYSTR;
23 str_reserve(&data_str, VSFTP_DATA_BUFSIZE);
24 /* Before becoming the slave, clear the alarm for the FTP protocol. */
25 vsf_sysutil_clear_alarm();
26 /* No need for any further communications with the privileged parent. */
27 priv_sock_set_parent_context(p_sess);
28 if (tunable_setproctitle_enable)
30 vsf_sysutil_setproctitle("SSL handler");
32 while (1)
34 char cmd = priv_sock_get_cmd(p_sess->ssl_slave_fd);
35 int ret;
36 if (cmd == PRIV_SOCK_GET_USER_CMD)
38 ret = ftp_getline(p_sess, &p_sess->ftp_cmd_str,
39 p_sess->p_control_line_buf);
40 priv_sock_send_int(p_sess->ssl_slave_fd, ret);
41 if (ret >= 0)
43 priv_sock_send_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str);
46 else if (cmd == PRIV_SOCK_WRITE_USER_RESP)
48 priv_sock_get_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str);
49 ret = ftp_write_str(p_sess, &p_sess->ftp_cmd_str, kVSFRWControl);
50 priv_sock_send_int(p_sess->ssl_slave_fd, ret);
52 else if (cmd == PRIV_SOCK_DO_SSL_HANDSHAKE)
54 char result = PRIV_SOCK_RESULT_BAD;
55 if (p_sess->data_fd != -1 || p_sess->p_data_ssl != 0)
57 bug("state not clean");
59 p_sess->data_fd = priv_sock_recv_fd(p_sess->ssl_slave_fd);
60 ret = ssl_accept(p_sess, p_sess->data_fd);
61 if (ret == 1)
63 result = PRIV_SOCK_RESULT_OK;
65 else
67 vsf_sysutil_close(p_sess->data_fd);
68 p_sess->data_fd = -1;
70 priv_sock_send_result(p_sess->ssl_slave_fd, result);
72 else if (cmd == PRIV_SOCK_DO_SSL_READ)
74 str_trunc(&data_str, VSFTP_DATA_BUFSIZE);
75 ret = ssl_read_into_str(p_sess, p_sess->p_data_ssl, &data_str);
76 priv_sock_send_int(p_sess->ssl_slave_fd, ret);
77 priv_sock_send_str(p_sess->ssl_slave_fd, &data_str);
79 else if (cmd == PRIV_SOCK_DO_SSL_WRITE)
81 priv_sock_get_str(p_sess->ssl_slave_fd, &data_str);
82 ret = ssl_write(p_sess->p_data_ssl,
83 str_getbuf(&data_str),
84 str_getlen(&data_str));
85 priv_sock_send_int(p_sess->ssl_slave_fd, ret);
87 else if (cmd == PRIV_SOCK_DO_SSL_CLOSE)
89 char result = PRIV_SOCK_RESULT_BAD;
90 if (p_sess->data_fd == -1 && p_sess->p_data_ssl == 0)
92 result = PRIV_SOCK_RESULT_OK;
94 else
96 ret = ssl_data_close(p_sess);
97 if (ret == 1)
99 result = PRIV_SOCK_RESULT_OK;
101 vsf_sysutil_close(p_sess->data_fd);
102 p_sess->data_fd = -1;
104 priv_sock_send_result(p_sess->ssl_slave_fd, result);
106 else
108 die("bad request in process_ssl_slave_req");