tcptls.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2006, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file tcptls.h
  20. *
  21. * \brief Generic support for tcp/tls servers in Asterisk.
  22. * \note In order to have TLS/SSL support, we need the openssl libraries.
  23. * Still we can decide whether or not to use them by commenting
  24. * in or out the DO_SSL macro.
  25. *
  26. * TLS/SSL support is basically implemented by reading from a config file
  27. * (currently manager.conf, http.conf and sip.conf) the names of the certificate
  28. * files and cipher to use, and then run ssl_setup() to create an appropriate
  29. * data structure named ssl_ctx.
  30. *
  31. * If we support multiple domains, presumably we need to read multiple
  32. * certificates.
  33. *
  34. * When we are requested to open a TLS socket, we run make_file_from_fd()
  35. * on the socket, to do the necessary setup. At the moment the context's name
  36. * is hardwired in the function, but we can certainly make it into an extra
  37. * parameter to the function.
  38. *
  39. * We declare most of ssl support variables unconditionally,
  40. * because their number is small and this simplifies the code.
  41. *
  42. * \note The ssl-support variables (ssl_ctx, do_ssl, certfile, cipher)
  43. * and their setup should be moved to a more central place, e.g. asterisk.conf
  44. * and the source files that processes it. Similarly, ssl_setup() should
  45. * be run earlier in the startup process so modules have it available.
  46. *
  47. * \ref AstTlsOverview
  48. */
  49. #ifndef _ASTERISK_TCPTLS_H
  50. #define _ASTERISK_TCPTLS_H
  51. #include "asterisk.h"
  52. #include <pthread.h> /* for pthread_t */
  53. #include "asterisk/netsock2.h" /* for ast_sockaddr */
  54. #include "asterisk/utils.h" /* for ast_flags */
  55. struct ssl_st; /* forward declaration */
  56. struct ssl_ctx_st; /* forward declaration */
  57. struct timeval; /* forward declaration */
  58. typedef struct ssl_st SSL;
  59. typedef struct ssl_ctx_st SSL_CTX;
  60. #if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE))
  61. #define DO_SSL /* comment in/out if you want to support ssl */
  62. #endif
  63. /*! SSL support */
  64. #define AST_CERTFILE "asterisk.pem"
  65. enum ast_ssl_flags {
  66. /*! Verify certificate when acting as server */
  67. AST_SSL_VERIFY_CLIENT = (1 << 0),
  68. /*! Don't verify certificate when connecting to a server */
  69. AST_SSL_DONT_VERIFY_SERVER = (1 << 1),
  70. /*! Don't compare "Common Name" against IP or hostname */
  71. AST_SSL_IGNORE_COMMON_NAME = (1 << 2),
  72. /*! Use SSLv2 for outgoing client connections */
  73. AST_SSL_SSLV2_CLIENT = (1 << 3),
  74. /*! Use SSLv3 for outgoing client connections */
  75. AST_SSL_SSLV3_CLIENT = (1 << 4),
  76. /*! Use TLSv1 for outgoing client connections */
  77. AST_SSL_TLSV1_CLIENT = (1 << 5),
  78. /*! Use server cipher order instead of the client order */
  79. AST_SSL_SERVER_CIPHER_ORDER = (1 << 6),
  80. /*! Disable TLSv1 support */
  81. AST_SSL_DISABLE_TLSV1 = (1 << 7),
  82. /*! Disable TLSv1.1 support */
  83. AST_SSL_DISABLE_TLSV11 = (1 << 8),
  84. /*! Disable TLSv1.2 support */
  85. AST_SSL_DISABLE_TLSV12 = (1 << 9),
  86. };
  87. struct ast_tls_config {
  88. int enabled;
  89. char *certfile;
  90. char *pvtfile;
  91. char *cipher;
  92. char *cafile;
  93. char *capath;
  94. struct ast_flags flags;
  95. SSL_CTX *ssl_ctx;
  96. char certhash[41];
  97. char pvthash[41];
  98. char cahash[41];
  99. };
  100. /*! \page AstTlsOverview TLS Implementation Overview
  101. *
  102. * The following code implements a generic mechanism for starting
  103. * services on a TCP or TLS socket.
  104. * The service is configured in the struct session_args, and
  105. * then started by calling server_start(desc) on the descriptor.
  106. * server_start() first verifies if an instance of the service is active,
  107. * and in case shuts it down. Then, if the service must be started, creates
  108. * a socket and a thread in charge of doing the accept().
  109. *
  110. * The body of the thread is desc->accept_fn(desc), which the user can define
  111. * freely. We supply a sample implementation, server_root(), structured as an
  112. * infinite loop. At the beginning of each iteration it runs periodic_fn()
  113. * if defined (e.g. to perform some cleanup etc.) then issues a poll()
  114. * or equivalent with a timeout of 'poll_timeout' milliseconds, and if the
  115. * following accept() is successful it creates a thread in charge of
  116. * running the session, whose body is desc->worker_fn(). The argument of
  117. * worker_fn() is a struct ast_tcptls_session_instance, which contains the address
  118. * of the other party, a pointer to desc, the file descriptors (fd) on which
  119. * we can do a select/poll (but NOT I/O), and a FILE *on which we can do I/O.
  120. * We have both because we want to support plain and SSL sockets, and
  121. * going through a FILE * lets us provide the encryption/decryption
  122. * on the stream without using an auxiliary thread.
  123. */
  124. /*! \brief
  125. * arguments for the accepting thread
  126. */
  127. struct ast_tcptls_session_args {
  128. struct ast_sockaddr local_address;
  129. struct ast_sockaddr old_address; /*!< copy of the local or remote address depending on if its a client or server session */
  130. struct ast_sockaddr remote_address;
  131. char hostname[MAXHOSTNAMELEN]; /*!< only necessary for SSL clients so we can compare to common name */
  132. struct ast_tls_config *tls_cfg; /*!< points to the SSL configuration if any */
  133. int accept_fd;
  134. int poll_timeout;
  135. /*! Server accept_fn thread ID used for external shutdown requests. */
  136. pthread_t master;
  137. void *(*accept_fn)(void *); /*!< the function in charge of doing the accept */
  138. void (*periodic_fn)(void *);/*!< something we may want to run before after select on the accept socket */
  139. void *(*worker_fn)(void *); /*!< the function in charge of doing the actual work */
  140. const char *name;
  141. struct ast_tls_config *old_tls_cfg; /*!< copy of the SSL configuration to determine whether changes have been made */
  142. };
  143. struct ast_tcptls_stream;
  144. /*!
  145. * \brief Disable the TCP/TLS stream timeout timer.
  146. *
  147. * \param stream TCP/TLS stream control data.
  148. *
  149. * \return Nothing
  150. */
  151. void ast_tcptls_stream_set_timeout_disable(struct ast_tcptls_stream *stream);
  152. /*!
  153. * \brief Set the TCP/TLS stream inactivity timeout timer.
  154. *
  155. * \param stream TCP/TLS stream control data.
  156. * \param timeout Number of milliseconds to wait for data transfer with the peer.
  157. *
  158. * \details This is basically how much time we are willing to spend
  159. * in an I/O call before we declare the peer unresponsive.
  160. *
  161. * \note Setting timeout to -1 disables the timeout.
  162. * \note Setting this timeout replaces the I/O sequence timeout timer.
  163. *
  164. * \return Nothing
  165. */
  166. void ast_tcptls_stream_set_timeout_inactivity(struct ast_tcptls_stream *stream, int timeout);
  167. /*!
  168. * \brief Set the TCP/TLS stream I/O sequence timeout timer.
  169. *
  170. * \param stream TCP/TLS stream control data.
  171. * \param start Time the I/O sequence timer starts.
  172. * \param timeout Number of milliseconds from the start time before timeout.
  173. *
  174. * \details This is how much time are we willing to allow the peer
  175. * to complete an operation that can take several I/O calls. The
  176. * main use is as an authentication timer with us.
  177. *
  178. * \note Setting timeout to -1 disables the timeout.
  179. * \note Setting this timeout replaces the inactivity timeout timer.
  180. *
  181. * \return Nothing
  182. */
  183. void ast_tcptls_stream_set_timeout_sequence(struct ast_tcptls_stream *stream, struct timeval start, int timeout);
  184. /*!
  185. * \brief Set the TCP/TLS stream I/O if it can exclusively depend upon the set timeouts.
  186. *
  187. * \param stream TCP/TLS stream control data.
  188. * \param exclusive_input TRUE if stream can exclusively wait for fd input.
  189. * Otherwise, the stream will not wait for fd input. It will wait while
  190. * trying to send data.
  191. *
  192. * \note The stream timeouts still need to be set.
  193. *
  194. * \return Nothing
  195. */
  196. void ast_tcptls_stream_set_exclusive_input(struct ast_tcptls_stream *stream, int exclusive_input);
  197. /*! \brief
  198. * describes a server instance
  199. */
  200. struct ast_tcptls_session_instance {
  201. FILE *f; /*!< fopen/funopen result */
  202. int fd; /*!< the socket returned by accept() */
  203. SSL *ssl; /*!< ssl state */
  204. int client;
  205. struct ast_sockaddr remote_address;
  206. struct ast_tcptls_session_args *parent;
  207. /* Sometimes, when an entity reads TCP data, multiple
  208. * logical messages might be read at the same time. In such
  209. * a circumstance, there needs to be a place to stash the
  210. * extra data.
  211. */
  212. struct ast_str *overflow_buf;
  213. /*! ao2 FILE stream cookie object associated with f. */
  214. struct ast_tcptls_stream *stream_cookie;
  215. /*! ao2 object private data of parent->worker_fn */
  216. void *private_data;
  217. };
  218. #if defined(HAVE_FUNOPEN)
  219. #define HOOK_T int
  220. #define LEN_T int
  221. #else
  222. #define HOOK_T ssize_t
  223. #define LEN_T size_t
  224. #endif
  225. /*!
  226. * \brief attempts to connect and start tcptls session, on error the tcptls_session's
  227. * ref count is decremented, fd and file are closed, and NULL is returned.
  228. */
  229. struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session);
  230. /* \brief Creates a client connection's ast_tcptls_session_instance. */
  231. struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc);
  232. void *ast_tcptls_server_root(void *);
  233. /*!
  234. * \brief Closes a tcptls session instance's file and/or file descriptor.
  235. * The tcptls_session will be set to NULL and it's file descriptor will be set to -1
  236. * by this function.
  237. */
  238. void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session);
  239. /*!
  240. * \brief This is a generic (re)start routine for a TCP server,
  241. * which does the socket/bind/listen and starts a thread for handling
  242. * accept().
  243. * \version 1.6.1 changed desc parameter to be of ast_tcptls_session_args type
  244. */
  245. void ast_tcptls_server_start(struct ast_tcptls_session_args *desc);
  246. /*!
  247. * \brief Shutdown a running server if there is one
  248. * \version 1.6.1 changed desc parameter to be of ast_tcptls_session_args type
  249. */
  250. void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc);
  251. /*!
  252. * \brief Set up an SSL server
  253. *
  254. * \param cfg Configuration for the SSL server
  255. * \retval 1 Success
  256. * \retval 0 Failure
  257. */
  258. int ast_ssl_setup(struct ast_tls_config *cfg);
  259. /*!
  260. * \brief free resources used by an SSL server
  261. *
  262. * \note This only needs to be called if ast_ssl_setup() was
  263. * directly called first.
  264. * \param cfg Configuration for the SSL server
  265. */
  266. void ast_ssl_teardown(struct ast_tls_config *cfg);
  267. /*!
  268. * \brief Used to parse conf files containing tls/ssl options.
  269. */
  270. int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value);
  271. HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *ser, void *buf, size_t count);
  272. HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *ser, const void *buf, size_t count);
  273. #endif /* _ASTERISK_TCPTLS_H */