readwrite.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Part of Very Secure FTPd
  3. * Licence: GPL v2
  4. * Author: Chris Evans
  5. * readwrite.c
  6. *
  7. * Routines to encapsulate the underlying read / write mechanism (OpenSSL vs.
  8. * plain read()/write()).
  9. */
  10. #include "readwrite.h"
  11. #include "session.h"
  12. #include "netstr.h"
  13. #include "ssl.h"
  14. #include "privsock.h"
  15. #include "defs.h"
  16. #include "sysutil.h"
  17. static int plain_peek_adapter(struct vsf_session* p_sess,
  18. char* p_buf,
  19. unsigned int len);
  20. static int plain_read_adapter(struct vsf_session* p_sess,
  21. char* p_buf,
  22. unsigned int len);
  23. static int ssl_peek_adapter(struct vsf_session* p_sess,
  24. char* p_buf,
  25. unsigned int len);
  26. static int ssl_read_adapter(struct vsf_session* p_sess,
  27. char* p_buf,
  28. unsigned int len);
  29. int
  30. ftp_write_str(const struct vsf_session* p_sess, const struct mystr* p_str,
  31. enum EVSFRWTarget target)
  32. {
  33. if (target == kVSFRWData)
  34. {
  35. if (p_sess->data_use_ssl && p_sess->ssl_slave_active)
  36. {
  37. int ret = -1;
  38. int written;
  39. priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_DO_SSL_WRITE);
  40. priv_sock_send_str(p_sess->ssl_consumer_fd, p_str);
  41. written = priv_sock_get_int(p_sess->ssl_consumer_fd);
  42. if (written > 0 && written == (int) str_getlen(p_str))
  43. {
  44. ret = 0;
  45. }
  46. return ret;
  47. }
  48. else if (p_sess->data_use_ssl)
  49. {
  50. return ssl_write_str(p_sess->p_data_ssl, p_str);
  51. }
  52. else
  53. {
  54. return str_netfd_write(p_str, p_sess->data_fd);
  55. }
  56. }
  57. else
  58. {
  59. if (p_sess->control_use_ssl && p_sess->ssl_slave_active)
  60. {
  61. priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_WRITE_USER_RESP);
  62. priv_sock_send_str(p_sess->ssl_consumer_fd, p_str);
  63. return priv_sock_get_int(p_sess->ssl_consumer_fd);
  64. }
  65. else if (p_sess->control_use_ssl)
  66. {
  67. return ssl_write_str(p_sess->p_control_ssl, p_str);
  68. }
  69. else
  70. {
  71. return str_netfd_write(p_str, VSFTP_COMMAND_FD);
  72. }
  73. }
  74. }
  75. int
  76. ftp_read_data(struct vsf_session* p_sess, char* p_buf, unsigned int len)
  77. {
  78. if (p_sess->data_use_ssl && p_sess->ssl_slave_active)
  79. {
  80. int ret;
  81. priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_DO_SSL_READ);
  82. priv_sock_send_int(p_sess->ssl_consumer_fd, len);
  83. ret = priv_sock_get_int(p_sess->ssl_consumer_fd);
  84. priv_sock_recv_buf(p_sess->ssl_consumer_fd, p_buf, len);
  85. /* Need to do this here too because it is useless in the slave process. */
  86. vsf_sysutil_check_pending_actions(kVSFSysUtilIO, ret, p_sess->data_fd);
  87. return ret;
  88. }
  89. else if (p_sess->data_use_ssl)
  90. {
  91. return ssl_read(p_sess, p_sess->p_data_ssl, p_buf, len);
  92. }
  93. else
  94. {
  95. return vsf_sysutil_read(p_sess->data_fd, p_buf, len);
  96. }
  97. }
  98. int
  99. ftp_write_data(const struct vsf_session* p_sess, const char* p_buf,
  100. unsigned int len)
  101. {
  102. if (p_sess->data_use_ssl && p_sess->ssl_slave_active)
  103. {
  104. int ret;
  105. priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_DO_SSL_WRITE);
  106. priv_sock_send_buf(p_sess->ssl_consumer_fd, p_buf, len);
  107. ret = priv_sock_get_int(p_sess->ssl_consumer_fd);
  108. /* Need to do this here too because it is useless in the slave process. */
  109. vsf_sysutil_check_pending_actions(kVSFSysUtilIO, ret, p_sess->data_fd);
  110. return ret;
  111. }
  112. else if (p_sess->data_use_ssl)
  113. {
  114. return ssl_write(p_sess->p_data_ssl, p_buf, len);
  115. }
  116. else
  117. {
  118. return vsf_sysutil_write_loop(p_sess->data_fd, p_buf, len);
  119. }
  120. }
  121. int
  122. ftp_getline(struct vsf_session* p_sess, struct mystr* p_str, char* p_buf)
  123. {
  124. if (p_sess->control_use_ssl && p_sess->ssl_slave_active)
  125. {
  126. int ret;
  127. priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_GET_USER_CMD);
  128. ret = priv_sock_get_int(p_sess->ssl_consumer_fd);
  129. if (ret >= 0)
  130. {
  131. priv_sock_get_str(p_sess->ssl_consumer_fd, p_str);
  132. }
  133. return ret;
  134. }
  135. else
  136. {
  137. str_netfd_read_t p_peek = plain_peek_adapter;
  138. str_netfd_read_t p_read = plain_read_adapter;
  139. if (p_sess->control_use_ssl)
  140. {
  141. p_peek = ssl_peek_adapter;
  142. p_read = ssl_read_adapter;
  143. }
  144. return str_netfd_alloc(p_sess,
  145. p_str,
  146. '\n',
  147. p_buf,
  148. VSFTP_MAX_COMMAND_LINE,
  149. p_peek,
  150. p_read);
  151. }
  152. }
  153. static int
  154. plain_peek_adapter(struct vsf_session* p_sess, char* p_buf, unsigned int len)
  155. {
  156. (void) p_sess;
  157. return vsf_sysutil_recv_peek(VSFTP_COMMAND_FD, p_buf, len);
  158. }
  159. static int
  160. plain_read_adapter(struct vsf_session* p_sess, char* p_buf, unsigned int len)
  161. {
  162. (void) p_sess;
  163. return vsf_sysutil_read_loop(VSFTP_COMMAND_FD, p_buf, len);
  164. }
  165. static int
  166. ssl_peek_adapter(struct vsf_session* p_sess, char* p_buf, unsigned int len)
  167. {
  168. return ssl_peek(p_sess, p_sess->p_control_ssl, p_buf, len);
  169. }
  170. static int
  171. ssl_read_adapter(struct vsf_session* p_sess, char* p_buf, unsigned int len)
  172. {
  173. return ssl_read(p_sess, p_sess->p_control_ssl, p_buf, len);
  174. }