1//
2// SecureStreamSocketImpl.h
3//
4// Library: NetSSL_OpenSSL
5// Package: SSLSockets
6// Module: SecureStreamSocketImpl
7//
8// Definition of the SecureStreamSocketImpl class.
9//
10// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef NetSSL_SecureStreamSocketImpl_INCLUDED
18#define NetSSL_SecureStreamSocketImpl_INCLUDED
19
20
21#include "Poco/Net/NetSSL.h"
22#include "Poco/Net/SecureSocketImpl.h"
23#include "Poco/Net/StreamSocketImpl.h"
24#include "Poco/Net/Context.h"
25#include "Poco/Net/X509Certificate.h"
26
27
28namespace Poco {
29namespace Net {
30
31
32class NetSSL_API SecureStreamSocketImpl: public StreamSocketImpl
33 /// This class implements a SSL stream socket.
34{
35public:
36 SecureStreamSocketImpl(Context::Ptr pContext);
37 /// Creates the SecureStreamSocketImpl.
38
39 SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext);
40 /// Creates the SecureStreamSocketImpl.
41
42 SocketImpl* acceptConnection(SocketAddress& clientAddr);
43 /// Not supported by a SecureStreamSocket.
44 ///
45 /// Throws a Poco::InvalidAccessException.
46
47 void connect(const SocketAddress& address);
48 /// Initializes the socket and establishes a connection to
49 /// the TCP server at the given address.
50 ///
51 /// Can also be used for UDP sockets. In this case, no
52 /// connection is established. Instead, incoming and outgoing
53 /// packets are restricted to the specified address.
54
55 void connect(const SocketAddress& address, const Poco::Timespan& timeout);
56 /// Initializes the socket, sets the socket timeout and
57 /// establishes a connection to the TCP server at the given address.
58
59 void connectNB(const SocketAddress& address);
60 /// Initializes the socket and establishes a connection to
61 /// the TCP server at the given address. Prior to opening the
62 /// connection the socket is set to nonblocking mode.
63
64 void bind(const SocketAddress& address, bool reuseAddress, bool reusePort = false);
65 /// Bind a local address to the socket.
66 ///
67 /// This is usually only done when establishing a server
68 /// socket.
69 ///
70 /// TCP clients normally do not bind to a local address,
71 /// but in some special advanced cases it may be useful to have
72 /// this type of functionality. (e.g. in multihoming situations
73 /// where the traffic will be sent through a particular interface;
74 /// or in computer clustered environments with active/standby
75 /// servers and it is desired to make the traffic from either
76 /// active host present the same source IP address).
77 ///
78 /// Note: Practical use of client source IP address binding
79 /// may require OS networking setup outside the scope of
80 /// the Poco library.
81 ///
82 /// If reuseAddress is true, sets the SO_REUSEADDR
83 /// socket option.
84 ///
85 /// TODO: implement IPv6 version
86
87 void listen(int backlog = 64);
88 /// Not supported by a SecureStreamSocket.
89 ///
90 /// Throws a Poco::InvalidAccessException.
91
92 void close();
93 /// Close the socket.
94
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
102 int receiveBytes(void* buffer, int length, int flags = 0);
103 /// Receives data from the socket and stores it
104 /// in buffer. Up to length bytes are received.
105 ///
106 /// Returns the number of bytes received.
107
108 int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0);
109 /// Not supported by a SecureStreamSocket.
110 ///
111 /// Throws a Poco::InvalidAccessException.
112
113 int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0);
114 /// Not supported by a SecureStreamSocket.
115 ///
116 /// Throws a Poco::InvalidAccessException.
117
118 void sendUrgent(unsigned char data);
119 /// Not supported by a SecureStreamSocket.
120 ///
121 /// Throws a Poco::InvalidAccessException.
122
123 int available();
124 /// Returns the number of bytes available that can be read
125 /// without causing the socket to block.
126 ///
127 /// For an SSL connection, returns the number of bytes that
128 /// can be read from the currently buffered SSL record,
129 /// before a new record is read from the underlying socket.
130
131 void shutdownReceive();
132 /// Shuts down the receiving part of the socket connection.
133 ///
134 /// Since SSL does not support a half shutdown, this does
135 /// nothing.
136
137 void shutdownSend();
138 /// Shuts down the receiving part of the socket connection.
139 ///
140 /// Since SSL does not support a half shutdown, this does
141 /// nothing.
142
143 void shutdown();
144 /// Shuts down the SSL connection.
145
146 void abort();
147 /// Aborts the connection by closing the underlying
148 /// TCP connection. No orderly SSL shutdown is performed.
149
150 bool secure() const;
151 /// Returns true iff the socket's connection is secure
152 /// (using SSL or TLS).
153
154 void setPeerHostName(const std::string& hostName);
155 /// Sets the peer host name for certificate validation purposes.
156
157 const std::string& getPeerHostName() const;
158 /// Returns the peer host name.
159
160 bool havePeerCertificate() const;
161 /// Returns true iff the peer has presented a
162 /// certificate.
163
164 X509Certificate peerCertificate() const;
165 /// Returns the peer's X509 certificate.
166 ///
167 /// Throws a SSLException if the peer did not
168 /// present a certificate.
169
170 Context::Ptr context() const;
171 /// Returns the SSL context used by this socket.
172
173 void setLazyHandshake(bool flag = true);
174 /// Enable lazy SSL handshake. If enabled, the SSL handshake
175 /// will be performed the first time date is sent or
176 /// received over the connection.
177
178 bool getLazyHandshake() const;
179 /// Returns true if setLazyHandshake(true) has been called.
180
181 void verifyPeerCertificate();
182 /// Performs post-connect (or post-accept) peer certificate validation,
183 /// using the peer's IP address as host name.
184
185 void verifyPeerCertificate(const std::string& hostName);
186 /// Performs post-connect (or post-accept) peer certificate validation
187 /// using the given host name.
188
189 int completeHandshake();
190 /// Completes the SSL handshake.
191 ///
192 /// If the SSL connection was the result of an accept(),
193 /// the server-side handshake is completed, otherwise
194 /// a client-side handshake is performed.
195
196 Session::Ptr currentSession();
197 /// Returns the SSL session of the current connection,
198 /// for reuse in a future connection (if session caching
199 /// is enabled).
200 ///
201 /// If no connection is established, returns null.
202
203 void useSession(Session::Ptr pSession);
204 /// Sets the SSL session to use for the next
205 /// connection. Setting a previously saved Session
206 /// object is necessary to enable session caching.
207 ///
208 /// To remove the currently set session, a null pointer
209 /// can be given.
210 ///
211 /// Must be called before connect() to be effective.
212
213 bool sessionWasReused();
214 /// Returns true iff a reused session was negotiated during
215 /// the handshake.
216
217protected:
218 void acceptSSL();
219 /// Performs a SSL server-side handshake.
220
221 void connectSSL();
222 /// Performs a SSL client-side handshake on an already connected TCP socket.
223
224 ~SecureStreamSocketImpl();
225 /// Destroys the SecureStreamSocketImpl.
226
227 static int lastError();
228 static void error();
229 static void error(const std::string& arg);
230 static void error(int code);
231 static void error(int code, const std::string& arg);
232
233private:
234 SecureStreamSocketImpl(const SecureStreamSocketImpl&);
235 SecureStreamSocketImpl& operator = (const SecureStreamSocketImpl&);
236
237 SecureSocketImpl _impl;
238 bool _lazyHandshake;
239
240 friend class SecureSocketImpl;
241 friend class SecureStreamSocket;
242};
243
244
245//
246// inlines
247//
248inline const std::string& SecureStreamSocketImpl::getPeerHostName() const
249{
250 return _impl.getPeerHostName();
251}
252
253
254inline void SecureStreamSocketImpl::setPeerHostName(const std::string& peerHostName)
255{
256 _impl.setPeerHostName(peerHostName);
257}
258
259
260inline Context::Ptr SecureStreamSocketImpl::context() const
261{
262 return _impl.context();
263}
264
265
266inline Session::Ptr SecureStreamSocketImpl::currentSession()
267{
268 return _impl.currentSession();
269}
270
271
272inline void SecureStreamSocketImpl::useSession(Session::Ptr pSession)
273{
274 _impl.useSession(pSession);
275}
276
277
278inline bool SecureStreamSocketImpl::sessionWasReused()
279{
280 return _impl.sessionWasReused();
281}
282
283
284inline int SecureStreamSocketImpl::lastError()
285{
286 return SocketImpl::lastError();
287}
288
289
290inline void SecureStreamSocketImpl::error()
291{
292 return SocketImpl::error();
293}
294
295
296inline void SecureStreamSocketImpl::error(const std::string& arg)
297{
298 return SocketImpl::error(arg);
299}
300
301
302inline void SecureStreamSocketImpl::error(int code)
303{
304 return SocketImpl::error(code);
305}
306
307
308inline void SecureStreamSocketImpl::error(int code, const std::string& arg)
309{
310 return SocketImpl::error(code, arg);
311}
312
313
314} } // namespace Poco::Net
315
316
317#endif // NetSSL_SecureStreamSocketImpl_INCLUDED
318