sslslave.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Part of Very Secure FTPd
  3. * Licence: GPL v2
  4. * Author: Chris Evans
  5. * sslslave.c
  6. */
  7. #include "sslslave.h"
  8. #include "session.h"
  9. #include "privsock.h"
  10. #include "tunables.h"
  11. #include "sysutil.h"
  12. #include "sysdeputil.h"
  13. #include "utility.h"
  14. #include "ssl.h"
  15. #include "readwrite.h"
  16. #include "defs.h"
  17. void
  18. ssl_slave(struct vsf_session* p_sess)
  19. {
  20. struct mystr data_str = INIT_MYSTR;
  21. str_reserve(&data_str, VSFTP_DATA_BUFSIZE);
  22. /* Before becoming the slave, clear the alarm for the FTP protocol. */
  23. vsf_sysutil_clear_alarm();
  24. /* No need for any further communications with the privileged parent. */
  25. priv_sock_set_parent_context(p_sess);
  26. if (tunable_setproctitle_enable)
  27. {
  28. vsf_sysutil_setproctitle("SSL handler");
  29. }
  30. while (1)
  31. {
  32. char cmd = priv_sock_get_cmd(p_sess->ssl_slave_fd);
  33. int ret;
  34. if (cmd == PRIV_SOCK_GET_USER_CMD)
  35. {
  36. ret = ftp_getline(p_sess, &p_sess->ftp_cmd_str,
  37. p_sess->p_control_line_buf);
  38. priv_sock_send_int(p_sess->ssl_slave_fd, ret);
  39. if (ret >= 0)
  40. {
  41. priv_sock_send_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str);
  42. }
  43. }
  44. else if (cmd == PRIV_SOCK_WRITE_USER_RESP)
  45. {
  46. priv_sock_get_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str);
  47. ret = ftp_write_str(p_sess, &p_sess->ftp_cmd_str, kVSFRWControl);
  48. priv_sock_send_int(p_sess->ssl_slave_fd, ret);
  49. }
  50. else if (cmd == PRIV_SOCK_DO_SSL_HANDSHAKE)
  51. {
  52. char result = PRIV_SOCK_RESULT_BAD;
  53. if (p_sess->data_fd != -1 || p_sess->p_data_ssl != 0)
  54. {
  55. bug("state not clean");
  56. }
  57. p_sess->data_fd = priv_sock_recv_fd(p_sess->ssl_slave_fd);
  58. ret = ssl_accept(p_sess, p_sess->data_fd);
  59. if (ret == 1)
  60. {
  61. result = PRIV_SOCK_RESULT_OK;
  62. }
  63. else
  64. {
  65. vsf_sysutil_close(p_sess->data_fd);
  66. p_sess->data_fd = -1;
  67. }
  68. priv_sock_send_result(p_sess->ssl_slave_fd, result);
  69. }
  70. else if (cmd == PRIV_SOCK_DO_SSL_READ)
  71. {
  72. int size = priv_sock_get_int(p_sess->ssl_slave_fd);
  73. if (size <= 0 || size > VSFTP_DATA_BUFSIZE)
  74. {
  75. bug("bad size");
  76. }
  77. if (p_sess->data_fd == -1 || p_sess->p_data_ssl == 0)
  78. {
  79. bug("invalid state");
  80. }
  81. str_trunc(&data_str, (unsigned int) size);
  82. ret = ssl_read_into_str(p_sess, p_sess->p_data_ssl, &data_str);
  83. priv_sock_send_int(p_sess->ssl_slave_fd, ret);
  84. priv_sock_send_str(p_sess->ssl_slave_fd, &data_str);
  85. }
  86. else if (cmd == PRIV_SOCK_DO_SSL_WRITE)
  87. {
  88. if (p_sess->data_fd == -1 || p_sess->p_data_ssl == 0)
  89. {
  90. bug("invalid state");
  91. }
  92. priv_sock_get_str(p_sess->ssl_slave_fd, &data_str);
  93. ret = ssl_write(p_sess->p_data_ssl,
  94. str_getbuf(&data_str),
  95. str_getlen(&data_str));
  96. priv_sock_send_int(p_sess->ssl_slave_fd, ret);
  97. }
  98. else if (cmd == PRIV_SOCK_DO_SSL_CLOSE)
  99. {
  100. char result = PRIV_SOCK_RESULT_BAD;
  101. if (p_sess->data_fd == -1 && p_sess->p_data_ssl == 0)
  102. {
  103. result = PRIV_SOCK_RESULT_OK;
  104. }
  105. else
  106. {
  107. if (p_sess->data_fd == -1 || p_sess->p_data_ssl == 0)
  108. {
  109. bug("invalid state");
  110. }
  111. ret = ssl_data_close(p_sess);
  112. if (ret == 1)
  113. {
  114. result = PRIV_SOCK_RESULT_OK;
  115. }
  116. vsf_sysutil_close(p_sess->data_fd);
  117. p_sess->data_fd = -1;
  118. }
  119. priv_sock_send_result(p_sess->ssl_slave_fd, result);
  120. }
  121. else
  122. {
  123. die("bad request in process_ssl_slave_req");
  124. }
  125. }
  126. }