SecureSocketImpl.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //
  2. // SecureSocketImpl.h
  3. //
  4. // $Id: //poco/1.4/NetSSL_OpenSSL/include/Poco/Net/SecureSocketImpl.h#2 $
  5. //
  6. // Library: NetSSL_OpenSSL
  7. // Package: SSLSockets
  8. // Module: SecureSocketImpl
  9. //
  10. // Definition of the SecureSocketImpl class.
  11. //
  12. // Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef NetSSL_SecureSocketImpl_INCLUDED
  18. #define NetSSL_SecureSocketImpl_INCLUDED
  19. #include "Poco/Net/NetSSL.h"
  20. #include "Poco/Net/SocketImpl.h"
  21. #include "Poco/Net/Context.h"
  22. #include "Poco/Net/X509Certificate.h"
  23. #include "Poco/Net/Session.h"
  24. #include <openssl/bio.h>
  25. #include <openssl/ssl.h>
  26. namespace Poco {
  27. namespace Net {
  28. class HostEntry;
  29. class NetSSL_API SecureSocketImpl
  30. /// The SocketImpl for SecureStreamSocket.
  31. {
  32. public:
  33. SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext);
  34. /// Creates the SecureSocketImpl using an already
  35. /// connected stream socket.
  36. virtual ~SecureSocketImpl();
  37. /// Destroys the SecureSocketImpl.
  38. SocketImpl* acceptConnection(SocketAddress& clientAddr);
  39. /// Get the next completed connection from the
  40. /// socket's completed connection queue.
  41. ///
  42. /// If the queue is empty, waits until a connection
  43. /// request completes.
  44. ///
  45. /// Returns a new SSL socket for the connection
  46. /// with the client.
  47. ///
  48. /// The client socket's address is returned in clientAddr.
  49. void connect(const SocketAddress& address, bool performHandshake);
  50. /// Initializes the socket and establishes a secure connection to
  51. /// the TCP server at the given address.
  52. ///
  53. /// If performHandshake is true, the SSL handshake is performed immediately
  54. /// after establishing the connection. Otherwise, the handshake is performed
  55. /// the first time sendBytes(), receiveBytes() or completeHandshake() is called.
  56. void connect(const SocketAddress& address, const Poco::Timespan& timeout, bool performHandshake);
  57. /// Initializes the socket, sets the socket timeout and
  58. /// establishes a secure connection to the TCP server at the given address.
  59. ///
  60. /// If performHandshake is true, the SSL handshake is performed immediately
  61. /// after establishing the connection. Otherwise, the handshake is performed
  62. /// the first time sendBytes(), receiveBytes() or completeHandshake() is called.
  63. void connectNB(const SocketAddress& address);
  64. /// Initializes the socket and establishes a secure connection to
  65. /// the TCP server at the given address. Prior to opening the
  66. /// connection the socket is set to nonblocking mode.
  67. void bind(const SocketAddress& address, bool reuseAddress = false);
  68. /// Bind a local address to the socket.
  69. ///
  70. /// This is usually only done when establishing a server
  71. /// socket. SSL clients should not bind a socket to a
  72. /// specific address.
  73. ///
  74. /// If reuseAddress is true, sets the SO_REUSEADDR
  75. /// socket option.
  76. void listen(int backlog = 64);
  77. /// Puts the socket into listening state.
  78. ///
  79. /// The socket becomes a passive socket that
  80. /// can accept incoming connection requests.
  81. ///
  82. /// The backlog argument specifies the maximum
  83. /// number of connections that can be queued
  84. /// for this socket.
  85. void shutdown();
  86. /// Shuts down the connection by attempting
  87. /// an orderly SSL shutdown, then actually
  88. /// shutting down the TCP connection.
  89. void close();
  90. /// Close the socket.
  91. void abort();
  92. /// Aborts the connection by closing the
  93. /// underlying TCP connection. No orderly SSL shutdown
  94. /// is performed.
  95. int sendBytes(const void* buffer, int length, int flags = 0);
  96. /// Sends the contents of the given buffer through
  97. /// the socket. Any specified flags are ignored.
  98. ///
  99. /// Returns the number of bytes sent, which may be
  100. /// less than the number of bytes specified.
  101. int receiveBytes(void* buffer, int length, int flags = 0);
  102. /// Receives data from the socket and stores it
  103. /// in buffer. Up to length bytes are received.
  104. ///
  105. /// Returns the number of bytes received.
  106. int available() const;
  107. /// Returns the number of bytes available from the
  108. /// SSL buffer for immediate reading.
  109. int completeHandshake();
  110. /// Completes the SSL handshake.
  111. ///
  112. /// If the SSL connection was the result of an accept(),
  113. /// the server-side handshake is completed, otherwise
  114. /// a client-side handshake is performed.
  115. poco_socket_t sockfd();
  116. /// Returns the underlying socket descriptor.
  117. X509* peerCertificate() const;
  118. /// Returns the peer's certificate.
  119. Context::Ptr context() const;
  120. /// Returns the SSL context used for this socket.
  121. void verifyPeerCertificate();
  122. /// Performs post-connect (or post-accept) peer certificate validation,
  123. /// using the peer host name set with setPeerHostName(), or the peer's
  124. /// IP address string if no peer host name has been set.
  125. void verifyPeerCertificate(const std::string& hostName);
  126. /// Performs post-connect (or post-accept) peer certificate validation
  127. /// using the given peer host name.
  128. void setPeerHostName(const std::string& hostName);
  129. /// Sets the peer host name for certificate validation purposes.
  130. const std::string& getPeerHostName() const;
  131. /// Returns the peer host name.
  132. Session::Ptr currentSession();
  133. /// Returns the SSL session of the current connection,
  134. /// for reuse in a future connection (if session caching
  135. /// is enabled).
  136. ///
  137. /// If no connection is established, returns null.
  138. void useSession(Session::Ptr pSession);
  139. /// Sets the SSL session to use for the next
  140. /// connection. Setting a previously saved Session
  141. /// object is necessary to enable session caching.
  142. ///
  143. /// To remove the currently set session, a null pointer
  144. /// can be given.
  145. ///
  146. /// Must be called before connect() to be effective.
  147. bool sessionWasReused();
  148. /// Returns true iff a reused session was negotiated during
  149. /// the handshake.
  150. protected:
  151. void acceptSSL();
  152. /// Performs a server-side SSL handshake and certificate verification.
  153. void connectSSL(bool performHandshake);
  154. /// Performs a client-side SSL handshake and establishes a secure
  155. /// connection over an already existing TCP connection.
  156. long verifyPeerCertificateImpl(const std::string& hostName);
  157. /// Performs post-connect (or post-accept) peer certificate validation.
  158. static bool isLocalHost(const std::string& hostName);
  159. /// Returns true iff the given host name is the local host
  160. /// (either "localhost" or "127.0.0.1").
  161. bool mustRetry(int rc);
  162. /// Returns true if the last operation should be retried,
  163. /// otherwise false.
  164. ///
  165. /// In case of an SSL_ERROR_WANT_READ error, and if the socket is
  166. /// blocking, waits for the underlying socket to become readable.
  167. ///
  168. /// In case of an SSL_ERROR_WANT_WRITE error, and if the socket is
  169. /// blocking, waits for the underlying socket to become writable.
  170. ///
  171. /// Can also throw a Poco::TimeoutException if the socket does
  172. /// not become readable or writable within the sockets
  173. /// receive or send timeout.
  174. int handleError(int rc);
  175. /// Handles an SSL error by throwing an appropriate exception.
  176. void reset();
  177. /// Prepares the socket for re-use.
  178. ///
  179. /// After closing and resetting a socket, the socket can
  180. /// be used for a new connection.
  181. ///
  182. /// Note that simply closing a socket is not sufficient
  183. /// to be able to re-use it again.
  184. private:
  185. SecureSocketImpl(const SecureSocketImpl&);
  186. SecureSocketImpl& operator = (const SecureSocketImpl&);
  187. SSL* _pSSL;
  188. Poco::AutoPtr<SocketImpl> _pSocket;
  189. Context::Ptr _pContext;
  190. bool _needHandshake;
  191. std::string _peerHostName;
  192. Session::Ptr _pSession;
  193. friend class SecureStreamSocketImpl;
  194. };
  195. //
  196. // inlines
  197. //
  198. inline poco_socket_t SecureSocketImpl::sockfd()
  199. {
  200. return _pSocket->sockfd();
  201. }
  202. inline Context::Ptr SecureSocketImpl::context() const
  203. {
  204. return _pContext;
  205. }
  206. inline const std::string& SecureSocketImpl::getPeerHostName() const
  207. {
  208. return _peerHostName;
  209. }
  210. } } // namespace Poco::Net
  211. #endif // NetSSL_SecureSocketImpl_INCLUDED