1 karl 1.48 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.32 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.22 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.32 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.35 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.48 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.11 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.2 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.48 //
|
21 kumpf 1.11 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.11 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.2 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
|
30 sushma.fernandes 1.58 //==============================================================================
31 //
|
32 mike 1.2 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <Pegasus/Common/Socket.h>
|
35 kumpf 1.8 #include <Pegasus/Common/Tracer.h>
|
36 kumpf 1.9 #include <Pegasus/Common/SSLContextRep.h>
|
37 h.sterling 1.26 #include <Pegasus/Common/SSLContext.h>
|
38 humberto 1.18 #include <Pegasus/Common/MessageLoader.h> //l10n
|
39 david.dillard 1.41 #include <Pegasus/Common/FileSystem.h>
|
40 kumpf 1.3
|
41 mike 1.2 #include "TLS.h"
|
42 kumpf 1.9
|
43 thilo.boehm 1.57 #ifdef PEGASUS_OS_ZOS
44 #include "SocketzOS_inline.h"
45 #endif
46
|
47 mike 1.2 //
48 // use the following definitions only if SSL is available
|
49 david.dillard 1.41 //
|
50 mike 1.2 #ifdef PEGASUS_HAS_SSL
51
52 PEGASUS_NAMESPACE_BEGIN
53
54 //
55 // Basic SSL socket
56 //
57
|
58 kumpf 1.40 SSLSocket::SSLSocket(
|
59 mike 1.52 SocketHandle socket,
|
60 kumpf 1.40 SSLContext * sslcontext,
|
61 sushma.fernandes 1.58 ReadWriteSem * sslContextObjectLock)
|
62 david.dillard 1.37 :
|
63 mike 1.2 _SSLConnection(0),
64 _socket(socket),
|
65 h.sterling 1.24 _SSLContext(sslcontext),
|
66 kumpf 1.40 _sslContextObjectLock(sslContextObjectLock),
|
67 w.otsuka 1.34 _SSLCallbackInfo(0),
|
68 sushma.fernandes 1.58 _certificateVerified(false)
|
69 mike 1.2 {
|
70 kumpf 1.12 PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::SSLSocket()");
71
|
72 sushma.fernandes 1.44 _sslReadErrno = 0;
73
|
74 kumpf 1.12 //
75 // create the SSLConnection area
76 //
77 if (!( _SSLConnection = SSL_new(_SSLContext->_rep->getContext() )))
78 {
79 PEG_METHOD_EXIT();
|
80 humberto 1.18 //l10n
81 //throw( SSLException("Could not get SSL Connection Area"));
82 MessageLoaderParms parms("Common.TLS.COULD_NOT_GET_SSL_CONNECTION_AREA",
83 "Could not get SSL Connection Area");
|
84 tony 1.23 throw SSLException(parms);
|
85 kumpf 1.12 }
86
|
87 dave.sudlik 1.46 // This try/catch block is necessary so that we can free the SSL Connection
88 // Area if any exceptions are thrown.
89 try
90 {
91 //
92 // set the verification callback data
93 //
94
95 //we are only storing one set of data, so we can just use index 0, this is defined in SSLContext.h
96 //int index = SSL_get_ex_new_index(0, (void*)"pegasus", NULL, NULL, NULL);
|
97 david.dillard 1.41
|
98 dave.sudlik 1.46 //
99 // Create a new callback info for each new connection
100 //
|
101 sushma.fernandes 1.51 _SSLCallbackInfo.reset(new SSLCallbackInfo(_SSLContext->getSSLCertificateVerifyFunction()
102 #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
103 , _SSLContext->getCRLStore()));
104 #else
105 ));
106 #endif
|
107 h.sterling 1.26
|
108 dave.sudlik 1.46 if (SSL_set_ex_data(_SSLConnection, SSLCallbackInfo::SSL_CALLBACK_INDEX, _SSLCallbackInfo.get()))
109 {
110 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "--->SSL: Set callback info");
111 }
112 else
113 {
114 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "--->SSL: Error setting callback info");
115 }
|
116 h.sterling 1.26
|
117 dave.sudlik 1.46 //
118 // and connect the active socket with the ssl operation
119 //
120 if (!(SSL_set_fd(_SSLConnection, _socket) ))
121 {
122 PEG_METHOD_EXIT();
123 //l10n
124 //throw( SSLException("Could not link socket to SSL Connection"));
125 MessageLoaderParms parms("Common.TLS.COULD_NOT_LINK_SOCKET",
126 "Could not link socket to SSL Connection");
127 throw SSLException(parms);
128 }
|
129 h.sterling 1.26 }
|
130 dave.sudlik 1.46 catch(...)
|
131 h.sterling 1.26 {
|
132 dave.sudlik 1.46 SSL_free(_SSLConnection);
133 throw;
|
134 kumpf 1.12 }
|
135 mike 1.2
|
136 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: Created SSL socket");
137
138 PEG_METHOD_EXIT();
|
139 mike 1.2 }
140
141 SSLSocket::~SSLSocket()
142 {
|
143 kumpf 1.12 PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::~SSLSocket()");
144
|
145 mike 1.2 SSL_free(_SSLConnection);
|
146 kumpf 1.12
147 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Deleted SSL socket");
148
149 PEG_METHOD_EXIT();
|
150 mike 1.2 }
151
|
152 mday 1.19
|
153 kumpf 1.17 Boolean SSLSocket::incompleteReadOccurred(Sint32 retCode)
154 {
|
155 h.sterling 1.39 Sint32 err = SSL_get_error(_SSLConnection, retCode);
|
156 kumpf 1.17
157 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
|
158 sushma.fernandes 1.44 "In SSLSocket::incompleteReadOccurred : err = %d", err);
|
159 kumpf 1.17
|
160 sushma.fernandes 1.44 return ((err == SSL_ERROR_SYSCALL) && (_sslReadErrno == EAGAIN || _sslReadErrno == EINTR)) ||
161 err == SSL_ERROR_WANT_READ ||
162 err == SSL_ERROR_WANT_WRITE;
|
163 kumpf 1.17 }
164
|
165 mike 1.2 Sint32 SSLSocket::read(void* ptr, Uint32 size)
166 {
|
167 kumpf 1.12 PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::read()");
168 Sint32 rc;
169
170 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (r) ");
171 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, SSL_state_string_long(_SSLConnection) );
|
172 kumpf 1.17 rc = SSL_read(_SSLConnection, (char *)ptr, size);
|
173 kumpf 1.12
|
174 sushma.fernandes 1.44 _sslReadErrno = errno;
175
|
176 kumpf 1.12 PEG_METHOD_EXIT();
|
177 mike 1.2 return rc;
178 }
179
|
180 marek 1.53 Sint32 SSLSocket::timedWrite( const void* ptr,
181 Uint32 size,
182 Uint32 socketWriteTimeout)
183 {
184 PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::timedWrite()");
185 Sint32 bytesWritten = 0;
186 Sint32 totalBytesWritten = 0;
187 Boolean socketTimedOut = false;
188 Uint32 selreturn = 0;
|
189 kumpf 1.12
|
190 marek 1.53 while (1)
191 {
|
192 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (w) ");
|
193 marek 1.53 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
194 SSL_state_string_long(_SSLConnection) );
195 bytesWritten = SSL_write(_SSLConnection, (char *)ptr, size);
196
197 // Some data written this cycle ?
198 // Add it to the total amount of written data.
199 if (bytesWritten > 0)
200 {
201 totalBytesWritten += bytesWritten;
202 socketTimedOut = false;
203 }
204
205 // All data written ? return amount of data written
206 if ((Uint32)bytesWritten == size)
207 {
|
208 gs.keenan 1.54 // exit the while loop
209 break;
|
210 marek 1.53 }
211 // If data has been written partially, we resume writing data
212 // this also accounts for the case of a signal interrupt
213 // (i.e. errno = EINTR)
214 if (bytesWritten > 0)
215 {
216 size -= bytesWritten;
217 ptr = (void *)((char *)ptr + bytesWritten);
218 continue;
219 }
220 // Something went wrong, SSL return with everything not > 0 is an error
221 if (bytesWritten <= 0)
222 {
223 // if we already waited for the socket to get ready, bail out
|
224 gs.keenan 1.54 if( socketTimedOut )
225 {
226 // bytesWritten contains the error indication
227 PEG_METHOD_EXIT();
228 return bytesWritten;
229 }
|
230 marek 1.53
231 // just interrupted by a signal, try again
232 #ifdef PEGASUS_OS_TYPE_WINDOWS
233 if (WSAGetLastError() == WSAEINTR) continue;
234 #else
235 if (errno == EINTR) continue;
236 #endif
237
238 // socket not ready ...
239 #ifdef PEGASUS_OS_TYPE_WINDOWS
240 if (WSAGetLastError() == WSAEWOULDBLOCK)
241 #else
242 if (errno == EAGAIN || errno == EWOULDBLOCK)
243 #endif
244 {
245 fd_set fdwrite;
246 // max. timeout seconds waiting for the socket to get ready
247 struct timeval tv = {socketWriteTimeout , 0 };
248 FD_ZERO(&fdwrite);
249 FD_SET(_socket, &fdwrite);
250 selreturn = select(FD_SETSIZE, NULL, &fdwrite, NULL, &tv);
251 marek 1.53 if (selreturn == 0) socketTimedOut = true; // ran out of time
252 continue;
253 }
|
254 gs.keenan 1.54 // bytesWritten contains the error indication
255 PEG_METHOD_EXIT();
|
256 marek 1.53 return bytesWritten;
257 }
258 }
|
259 kumpf 1.12 PEG_METHOD_EXIT();
|
260 gs.keenan 1.54 return totalBytesWritten;
|
261 mike 1.2 }
262
263 void SSLSocket::close()
264 {
|
265 kumpf 1.12 PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::close()");
266
|
267 mike 1.2 SSL_shutdown(_SSLConnection);
268 Socket::close(_socket);
|
269 kumpf 1.12
270 PEG_METHOD_EXIT();
|
271 mike 1.2 }
272
273 void SSLSocket::enableBlocking()
274 {
275 Socket::enableBlocking(_socket);
276 }
277
278 void SSLSocket::disableBlocking()
279 {
280 Socket::disableBlocking(_socket);
281 }
282
283 void SSLSocket::initializeInterface()
284 {
285 Socket::initializeInterface();
|
286 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: initialized SSL");
|
287 mike 1.2 }
288
289 void SSLSocket::uninitializeInterface()
290 {
291 Socket::uninitializeInterface();
292 }
293
294 Sint32 SSLSocket::accept()
295 {
|
296 kumpf 1.8 PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::accept()");
|
297 kumpf 1.6
|
298 mike 1.2 Sint32 ssl_rc,ssl_rsn;
299
|
300 h.sterling 1.24 //ATTN: these methods get implicitly done with the SSL_accept call
301 //SSL_do_handshake(_SSLConnection);
302 //SSL_set_accept_state(_SSLConnection);
|
303 mike 1.2
|
304 kumpf 1.40 // Make sure the SSLContext object is not updated during this operation.
305 ReadLock rlock(*_sslContextObjectLock);
306
|
307 mike 1.2 ssl_rc = SSL_accept(_SSLConnection);
308
309 if (ssl_rc < 0)
310 {
311 ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc);
|
312 david.dillard 1.43 Tracer::trace(TRC_SSL, Tracer::LEVEL3, "---> SSL: Not accepted %d", ssl_rsn );
|
313 mike 1.2
314 if ((ssl_rsn == SSL_ERROR_WANT_READ) ||
315 (ssl_rsn == SSL_ERROR_WANT_WRITE))
|
316 kumpf 1.12 {
|
317 kumpf 1.40 PEG_METHOD_EXIT();
318 return 0;
|
319 kumpf 1.12 }
|
320 mike 1.2 else
|
321 kumpf 1.12 {
322 PEG_METHOD_EXIT();
323 return -1;
324 }
|
325 mike 1.2 }
326 else if (ssl_rc == 0)
327 {
|
328 kumpf 1.3 ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc);
|
329 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "Shutdown SSL_accept()");
|
330 david.dillard 1.43 Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Error Code: %d", ssl_rsn );
|
331 david.dillard 1.41 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
|
332 kumpf 1.12 "Error string: " + String(ERR_error_string(ssl_rc, NULL)));
|
333 kumpf 1.3
|
334 kumpf 1.12 PEG_METHOD_EXIT();
|
335 mike 1.2 return -1;
336 }
|
337 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Accepted");
338
|
339 kumpf 1.25 //
340 // If peer certificate verification is enabled or request received on
|
341 david.dillard 1.41 // export connection, get the peer certificate and verify the trust
|
342 kumpf 1.25 // store validation result.
343 //
|
344 sushma.fernandes 1.58 if (_SSLContext->isPeerVerificationEnabled())
|
345 mike 1.2 {
|
346 h.sterling 1.24 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "Attempting to certify client");
|
347 kumpf 1.13
|
348 kumpf 1.25 //
|
349 h.sterling 1.24 // get client's certificate
|
350 kumpf 1.25 //
|
351 h.sterling 1.24 X509 * client_cert = SSL_get_peer_certificate(_SSLConnection);
352 if (client_cert != NULL)
353 {
|
354 kumpf 1.25 //
355 // get certificate verification result
356 //
|
357 h.sterling 1.24 int verifyResult = SSL_get_verify_result(_SSLConnection);
358 Tracer::trace(TRC_SSL, Tracer::LEVEL3, "Verification Result: %d", verifyResult );
|
359 david.dillard 1.41
|
360 h.sterling 1.24 if (verifyResult == X509_V_OK)
361 {
|
362 david.dillard 1.41 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
|
363 h.sterling 1.24 "---> SSL: Client Certificate verified.");
|
364 kumpf 1.25 //
365 // set flag to indicate that the certificate was verified in
366 // the trust store.
367 //
368 _certificateVerified = true;
|
369 h.sterling 1.24 }
370 else
371 {
|
372 david.dillard 1.41 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
373 "---> SSL: Client Certificate not verified");
|
374 h.sterling 1.24 }
375
376 X509_free(client_cert);
377 }
378 else
379 {
|
380 david.dillard 1.41 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
|
381 kumpf 1.25 "---> SSL: Client not certified, no certificate received");
|
382 h.sterling 1.24 }
|
383 mike 1.2 }
|
384 kumpf 1.13 else
385 {
|
386 kumpf 1.25 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Client certification disabled");
|
387 kumpf 1.13 }
|
388 mike 1.2
|
389 kumpf 1.8 PEG_METHOD_EXIT();
|
390 kumpf 1.40 return 1;
|
391 mike 1.2 }
392
393 Sint32 SSLSocket::connect()
394 {
|
395 kumpf 1.12 PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::connect()");
396
|
397 mike 1.2 Sint32 ssl_rc,ssl_rsn;
398
399 SSL_set_connect_state(_SSLConnection);
400
401 redo_connect:
|
402 kumpf 1.3
|
403 mike 1.2 ssl_rc = SSL_connect(_SSLConnection);
404
405 if (ssl_rc < 0)
406 {
407 ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc);
|
408 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Not connected " + ssl_rsn );
|
409 mike 1.2
410 if ((ssl_rsn == SSL_ERROR_WANT_READ) ||
411 (ssl_rsn == SSL_ERROR_WANT_WRITE))
|
412 kumpf 1.12 {
413 goto redo_connect;
414 }
|
415 mike 1.2 else
|
416 kumpf 1.12 {
417 PEG_METHOD_EXIT();
418 return -1;
419 }
|
420 mike 1.2 }
421 else if (ssl_rc == 0)
422 {
|
423 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Shutdown SSL_connect()");
|
424 david.dillard 1.41 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
|
425 kumpf 1.13 "Error string: " + String(ERR_error_string(ssl_rc, NULL)));
|
426 kumpf 1.12 PEG_METHOD_EXIT();
|
427 mike 1.2 return -1;
428 }
|
429 kumpf 1.12 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Connected");
|
430 mike 1.2
|
431 h.sterling 1.24 if (_SSLContext->isPeerVerificationEnabled())
|
432 mike 1.2 {
|
433 h.sterling 1.24 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "Attempting to verify server certificate.");
|
434 kumpf 1.6
|
435 h.sterling 1.24 X509 * server_cert = SSL_get_peer_certificate(_SSLConnection);
436 if (server_cert != NULL)
437 {
|
438 h.sterling 1.26 //
439 // Do not check the verification result using SSL_get_verify_result here to see whether or not to continue.
440 // The prepareForCallback does not reset the verification result, so it will still contain the original error.
|
441 david.dillard 1.41 // If the client chose to override the default error in the callback and return true, we got here and
|
442 h.sterling 1.26 // should proceed with the transaction. Otherwise, the handshake was already terminated.
443 //
|
444 david.dillard 1.41
|
445 h.sterling 1.24 if (SSL_get_verify_result(_SSLConnection) == X509_V_OK)
446 {
447 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "--->SSL: Server Certificate verified.");
448 }
449 else
450 {
|
451 h.sterling 1.26 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "--->SSL: Server Certificate not verified, but the callback overrode the default error.");
|
452 h.sterling 1.24 }
453
454 X509_free (server_cert);
455 }
456 else
457 {
458 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "-->SSL: Server not certified, no certificate received.");
459 PEG_METHOD_EXIT();
460 return -1;
461 }
|
462 david.dillard 1.43 }
|
463 mike 1.2 else
464 {
|
465 david.dillard 1.43 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Server certification disabled");
|
466 mike 1.2 }
467
|
468 kumpf 1.12 PEG_METHOD_EXIT();
|
469 mike 1.2 return ssl_rc;
470 }
471
|
472 h.sterling 1.24 Boolean SSLSocket::isPeerVerificationEnabled()
|
473 david.dillard 1.41 {
474 return (_SSLContext->isPeerVerificationEnabled());
|
475 h.sterling 1.24 }
476
|
477 h.sterling 1.45 Array<SSLCertificateInfo*> SSLSocket::getPeerCertificateChain()
|
478 david.dillard 1.41 {
|
479 carolann.graves 1.47 Array<SSLCertificateInfo*> peerCertificate;
480
|
481 david.dillard 1.41 if (_SSLCallbackInfo.get())
|
482 h.sterling 1.26 {
|
483 carolann.graves 1.47 peerCertificate = _SSLCallbackInfo->_rep->peerCertificate;
|
484 h.sterling 1.26 }
485
|
486 carolann.graves 1.47 return peerCertificate;
|
487 h.sterling 1.24 }
488
489 Boolean SSLSocket::isCertificateVerified()
|
490 david.dillard 1.41 {
491 return _certificateVerified;
|
492 h.sterling 1.24 }
493
|
494 mike 1.2
495 //
|
496 carolann.graves 1.47 // MP_Socket (Multi-purpose Socket class)
|
497 mike 1.2 //
498
499
500
|
501 mike 1.52 MP_Socket::MP_Socket(SocketHandle socket)
|
502 marek 1.53 : _socket(socket), _isSecure(false), _socketWriteTimeout(20) {}
|
503 mike 1.2
|
504 kumpf 1.40 MP_Socket::MP_Socket(
|
505 mike 1.52 SocketHandle socket,
|
506 kumpf 1.40 SSLContext * sslcontext,
|
507 sushma.fernandes 1.58 ReadWriteSem * sslContextObjectLock)
|
508 mike 1.2 {
|
509 kumpf 1.12 PEG_METHOD_ENTER(TRC_SSL, "MP_Socket::MP_Socket()");
|
510 mike 1.2 if (sslcontext != NULL)
511 {
512 _isSecure = true;
|
513 kumpf 1.40 _sslsock = new SSLSocket(
|
514 sushma.fernandes 1.58 socket, sslcontext, sslContextObjectLock);
|
515 mike 1.2 }
|
516 david.dillard 1.41 else
|
517 mike 1.2 {
518 _isSecure = false;
519 _socket = socket;
520 }
|
521 marek 1.53 // 20 seconds are the default for client timeouts
522 _socketWriteTimeout = 20;
|
523 kumpf 1.12 PEG_METHOD_EXIT();
|
524 mike 1.2 }
525
526 MP_Socket::~MP_Socket()
527 {
|
528 kumpf 1.12 PEG_METHOD_ENTER(TRC_SSL, "MP_Socket::~MP_Socket()");
|
529 mike 1.2 if (_isSecure)
|
530 h.sterling 1.24 {
|
531 mike 1.2 delete _sslsock;
|
532 h.sterling 1.24 }
|
533 kumpf 1.12 PEG_METHOD_EXIT();
|
534 david.dillard 1.41 }
535
|
536 mike 1.2 Boolean MP_Socket::isSecure() {return _isSecure;}
537
|
538 kumpf 1.17 Boolean MP_Socket::incompleteReadOccurred(Sint32 retCode)
539 {
540 if (_isSecure)
541 return(_sslsock->incompleteReadOccurred(retCode));
542 return (retCode <= 0);
543 }
544
|
545 mike 1.52 SocketHandle MP_Socket::getSocket()
|
546 mike 1.2 {
547 if (_isSecure)
548 return _sslsock->getSocket();
549 else
550 return _socket;
551 }
552
553 Sint32 MP_Socket::read(void * ptr, Uint32 size)
554 {
555 if (_isSecure)
556 return _sslsock->read(ptr,size);
557 else
558 return Socket::read(_socket,ptr,size);
559 }
560
561 Sint32 MP_Socket::write(const void * ptr, Uint32 size)
562 {
563 if (_isSecure)
|
564 marek 1.53 return _sslsock->timedWrite(ptr,size,_socketWriteTimeout);
|
565 mike 1.2 else
|
566 marek 1.53 return Socket::timedWrite(_socket,ptr,size,_socketWriteTimeout);
|
567 mike 1.2 }
568
569 void MP_Socket::close()
570 {
571 if (_isSecure)
|
572 tony 1.23 _sslsock->close();
|
573 mike 1.2 else
|
574 tony 1.23 Socket::close(_socket);
|
575 mike 1.2 }
576
577 void MP_Socket::enableBlocking()
578 {
579 if (_isSecure)
|
580 tony 1.23 _sslsock->enableBlocking();
|
581 mike 1.2 else
|
582 tony 1.23 Socket::enableBlocking(_socket);
|
583 mike 1.2 }
584
585 void MP_Socket::disableBlocking()
586 {
587 if (_isSecure)
|
588 tony 1.23 _sslsock->disableBlocking();
|
589 mike 1.2 else
|
590 tony 1.23 Socket::disableBlocking(_socket);
|
591 mike 1.2 }
592
593 Sint32 MP_Socket::accept()
594 {
595 if (_isSecure)
|
596 kumpf 1.40 {
597 return (_sslsock->accept());
598 }
599 return 1;
|
600 mike 1.2 }
601
602 Sint32 MP_Socket::connect()
603 {
604 if (_isSecure)
605 if (_sslsock->connect() < 0) return -1;
606 return 0;
607 }
608
|
609 h.sterling 1.24 Boolean MP_Socket::isPeerVerificationEnabled()
610 {
611 if (_isSecure)
612 {
613 return (_sslsock->isPeerVerificationEnabled());
614 }
615 return false;
616 }
617
|
618 h.sterling 1.45 Array<SSLCertificateInfo*> MP_Socket::getPeerCertificateChain()
|
619 h.sterling 1.24 {
|
620 carolann.graves 1.49 Array<SSLCertificateInfo*> peerCertificate;
621
|
622 h.sterling 1.24 if (_isSecure)
623 {
|
624 carolann.graves 1.49 peerCertificate = _sslsock->getPeerCertificateChain();
|
625 h.sterling 1.24 }
|
626 carolann.graves 1.49 return peerCertificate;
|
627 h.sterling 1.24 }
628
629 Boolean MP_Socket::isCertificateVerified()
630 {
631 if (_isSecure)
632 {
633 return (_sslsock->isCertificateVerified());
634 }
635 return false;
636 }
637
|
638 marek 1.53 void MP_Socket::setSocketWriteTimeout(Uint32 socketWriteTimeout)
639 {
640 _socketWriteTimeout = socketWriteTimeout;
641 }
642
|
643 mike 1.2 PEGASUS_NAMESPACE_END
644
645 #else
646
647 PEGASUS_NAMESPACE_BEGIN
648
|
649 thilo.boehm 1.57 #ifndef PEGASUS_OS_ZOS
|
650 mike 1.2
|
651 mike 1.52 MP_Socket::MP_Socket(SocketHandle socket)
|
652 marek 1.55 : _socket(socket), _isSecure(false), _socketWriteTimeout(20) {}
|
653 mike 1.2
|
654 kumpf 1.40 MP_Socket::MP_Socket(
|
655 mike 1.52 SocketHandle socket,
|
656 kumpf 1.40 SSLContext * sslcontext,
|
657 sushma.fernandes 1.58 ReadWriteSem * sslContextObjectLock)
|
658 marek 1.55 : _socket(socket), _isSecure(false), _socketWriteTimeout(20) {}
|
659 mike 1.2
|
660 thilo.boehm 1.57 #endif
661
|
662 mike 1.2 MP_Socket::~MP_Socket() {}
663
664 Boolean MP_Socket::isSecure() {return _isSecure;}
|
665 kumpf 1.17
|
666 david.dillard 1.41 Boolean MP_Socket::incompleteReadOccurred(Sint32 retCode)
|
667 kumpf 1.17 {
668 return (retCode <= 0);
669 }
|
670 mike 1.2
|
671 mike 1.52 SocketHandle MP_Socket::getSocket()
|
672 mike 1.2 {
673 return _socket;
674 }
675
676 Sint32 MP_Socket::read(void * ptr, Uint32 size)
677 {
678 return Socket::read(_socket,ptr,size);
679 }
680
681 Sint32 MP_Socket::write(const void * ptr, Uint32 size)
682 {
|
683 marek 1.53 return Socket::timedWrite(_socket,ptr,size,_socketWriteTimeout);
|
684 mike 1.2 }
685
686 void MP_Socket::close()
687 {
688 Socket::close(_socket);
689 }
690
691 void MP_Socket::enableBlocking()
692 {
693 Socket::enableBlocking(_socket);
694 }
695
696 void MP_Socket::disableBlocking()
697 {
698 Socket::disableBlocking(_socket);
699 }
700
|
701 thilo.boehm 1.57 Sint32 MP_Socket::accept()
702 {
703 #ifndef PEGASUS_OS_ZOS
704 return 1;
705 #else
706 PEG_METHOD_ENTER(TRC_SSL, "MP_Socket::accept()");
707 // ****************************************************************************
708 // This is a z/OS speciffic section. No other platform can port this.
709 // Pegsus on z/OS has no OpenSSL but cat use a transparent layer called
710 // AT-TLS ( Applicatin Transparent Transport Layer Security ) to handel
711 // HTTTPS connections.
712 // ****************************************************************************
713
714 int rc;
715
716 if(isSecure())
717 {
718 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> HTTPS processing.");
719 rc = ATTLS_zOS_query();
720 } else
721 {
722 thilo.boehm 1.57 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> Normal HTTP processing.");
723 rc = 1;
724 }
725 PEG_METHOD_EXIT();
726 return rc;
727
728 #endif
729
730 }
|
731 mike 1.2
732 Sint32 MP_Socket::connect() { return 0; }
|
733 mday 1.19
|
734 h.sterling 1.24 Boolean MP_Socket::isPeerVerificationEnabled() { return false; }
735
|
736 carolann.graves 1.47 Array<SSLCertificateInfo*> MP_Socket::getPeerCertificateChain()
737 {
738 //
739 // Return empty array
740 //
741 return Array<SSLCertificateInfo*>();
742 }
|
743 h.sterling 1.24
744 Boolean MP_Socket::isCertificateVerified() { return false; }
745
|
746 marek 1.53 void MP_Socket::setSocketWriteTimeout(Uint32 socketWriteTimeout)
747 {
748 _socketWriteTimeout = socketWriteTimeout;
749 }
750
751
|
752 mike 1.2 PEGASUS_NAMESPACE_END
753
|
754 kumpf 1.9 #endif // end of PEGASUS_HAS_SSL
|