version 1.59, 2006/11/10 18:14:58
|
version 1.59.4.4, 2008/01/04 19:52:55
|
|
|
SSLCallbackInfo::SSL_CALLBACK_INDEX, | SSLCallbackInfo::SSL_CALLBACK_INDEX, |
_SSLCallbackInfo.get())) | _SSLCallbackInfo.get())) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, |
"--->SSL: Set callback info"); | "--->SSL: Set callback info"); |
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"--->SSL: Error setting callback info"); | "--->SSL: Error setting callback info"); |
} | } |
| |
|
|
throw; | throw; |
} | } |
| |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: Created SSL socket"); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: Created SSL socket"); |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
|
|
| |
SSL_free(_SSLConnection); | SSL_free(_SSLConnection); |
| |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Deleted SSL socket"); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Deleted SSL socket"); |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
| |
Boolean SSLSocket::incompleteReadOccurred(Sint32 retCode) |
Boolean SSLSocket::incompleteSecureReadOccurred(Sint32 retCode) |
{ | { |
Sint32 err = SSL_get_error(_SSLConnection, retCode); | Sint32 err = SSL_get_error(_SSLConnection, retCode); |
| |
Tracer::trace(TRC_SSL, Tracer::LEVEL4, |
PEG_TRACE((TRC_SSL, Tracer::LEVEL4, |
"In SSLSocket::incompleteReadOccurred : err = %d", err); |
"In SSLSocket::incompleteSecureReadOccurred : err = %d", err)); |
| |
return ((err == SSL_ERROR_SYSCALL) && | return ((err == SSL_ERROR_SYSCALL) && |
(_sslReadErrno == EAGAIN || _sslReadErrno == EINTR)) || | (_sslReadErrno == EAGAIN || _sslReadErrno == EINTR)) || |
|
|
PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::read()"); | PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::read()"); |
Sint32 rc; | Sint32 rc; |
| |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (r) "); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (r) "); |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, |
SSL_state_string_long(_SSLConnection)); | SSL_state_string_long(_SSLConnection)); |
rc = SSL_read(_SSLConnection, (char *)ptr, size); | rc = SSL_read(_SSLConnection, (char *)ptr, size); |
| |
|
|
| |
while (1) | while (1) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (w) "); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: (w) "); |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, |
SSL_state_string_long(_SSLConnection) ); | SSL_state_string_long(_SSLConnection) ); |
bytesWritten = SSL_write(_SSLConnection, (char *)ptr, size); | bytesWritten = SSL_write(_SSLConnection, (char *)ptr, size); |
| |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
void SSLSocket::enableBlocking() |
|
{ |
|
Socket::enableBlocking(_socket); |
|
} |
|
|
|
void SSLSocket::disableBlocking() | void SSLSocket::disableBlocking() |
{ | { |
Socket::disableBlocking(_socket); | Socket::disableBlocking(_socket); |
|
|
void SSLSocket::initializeInterface() | void SSLSocket::initializeInterface() |
{ | { |
Socket::initializeInterface(); | Socket::initializeInterface(); |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: initialized SSL"); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: initialized SSL"); |
} | } |
| |
void SSLSocket::uninitializeInterface() | void SSLSocket::uninitializeInterface() |
|
|
if (ssl_rc < 0) | if (ssl_rc < 0) |
{ | { |
ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc); | ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc); |
Tracer::trace(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE((TRC_SSL, Tracer::LEVEL3, |
"---> SSL: Not accepted %d", ssl_rsn ); |
"---> SSL: Not accepted %d", ssl_rsn)); |
| |
if ((ssl_rsn == SSL_ERROR_WANT_READ) || | if ((ssl_rsn == SSL_ERROR_WANT_READ) || |
(ssl_rsn == SSL_ERROR_WANT_WRITE)) | (ssl_rsn == SSL_ERROR_WANT_WRITE)) |
|
|
else if (ssl_rc == 0) | else if (ssl_rc == 0) |
{ | { |
ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc); | ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc); |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "Shutdown SSL_accept()"); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "Shutdown SSL_accept()"); |
Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Error Code: %d", ssl_rsn ); |
PEG_TRACE((TRC_SSL, Tracer::LEVEL4, "Error Code: %d", ssl_rsn )); |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, | PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, |
"Error string: " + String(ERR_error_string(ssl_rc, NULL))); | "Error string: " + String(ERR_error_string(ssl_rc, NULL))); |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return -1; | return -1; |
} | } |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Accepted"); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Accepted"); |
| |
// | // |
// If peer certificate verification is enabled or request received on | // If peer certificate verification is enabled or request received on |
|
|
// | // |
if (_SSLContext->isPeerVerificationEnabled()) | if (_SSLContext->isPeerVerificationEnabled()) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"Attempting to certify client"); | "Attempting to certify client"); |
| |
// | // |
|
|
// get certificate verification result | // get certificate verification result |
// | // |
int verifyResult = SSL_get_verify_result(_SSLConnection); | int verifyResult = SSL_get_verify_result(_SSLConnection); |
Tracer::trace(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE((TRC_SSL, Tracer::LEVEL3, |
"Verification Result: %d", verifyResult ); |
"Verification Result: %d", verifyResult )); |
| |
if (verifyResult == X509_V_OK) | if (verifyResult == X509_V_OK) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL2, |
"---> SSL: Client Certificate verified."); | "---> SSL: Client Certificate verified."); |
// | // |
// set flag to indicate that the certificate was verified in | // set flag to indicate that the certificate was verified in |
|
|
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL2, |
"---> SSL: Client Certificate not verified"); | "---> SSL: Client Certificate not verified"); |
} | } |
| |
|
|
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"---> SSL: Client not certified, no certificate received"); | "---> SSL: Client not certified, no certificate received"); |
} | } |
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"---> SSL: Client certification disabled"); | "---> SSL: Client certification disabled"); |
} | } |
| |
|
|
return 1; | return 1; |
} | } |
| |
Sint32 SSLSocket::connect() |
Sint32 SSLSocket::connect(Uint32 timeoutMilliseconds) |
{ | { |
PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::connect()"); | PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::connect()"); |
| |
Sint32 ssl_rc,ssl_rsn; |
PEG_TRACE((TRC_SSL, Tracer::LEVEL4, |
|
"Connection timeout in milliseconds is : %d", timeoutMilliseconds)); |
| |
SSL_set_connect_state(_SSLConnection); | SSL_set_connect_state(_SSLConnection); |
| |
redo_connect: |
while (1) |
|
{ |
|
int ssl_rc = SSL_connect(_SSLConnection); |
| |
ssl_rc = SSL_connect(_SSLConnection); |
if (ssl_rc > 0) |
|
{ |
|
// Connected! |
|
break; |
|
} |
| |
if (ssl_rc < 0) |
if (ssl_rc == 0) |
{ | { |
ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
|
"---> SSL: Shutdown SSL_connect()"); |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, | PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
"---> SSL: Not connected " + ssl_rsn); |
"Error string: " + String(ERR_error_string(ssl_rc, NULL))); |
|
PEG_METHOD_EXIT(); |
|
return -1; |
|
} |
| |
if ((ssl_rsn == SSL_ERROR_WANT_READ) || |
// Error case: ssl_rc < 0 |
(ssl_rsn == SSL_ERROR_WANT_WRITE)) |
|
|
int ssl_rsn = SSL_get_error(_SSLConnection, ssl_rc); |
|
|
|
if ((ssl_rsn == SSL_ERROR_SYSCALL) && |
|
((errno == EAGAIN) || (errno == EINTR))) |
{ | { |
goto redo_connect; |
// Temporary error; retry the SSL_connect() |
|
continue; |
} | } |
else |
|
|
if ((ssl_rsn != SSL_ERROR_WANT_READ) && |
|
(ssl_rsn != SSL_ERROR_WANT_WRITE)) |
{ | { |
|
// Error, connection failed |
|
if (Tracer::isTraceOn()) |
|
{ |
|
unsigned long rc = ERR_get_error (); |
|
char buff[256]; |
|
// added in OpenSSL 0.9.6: |
|
ERR_error_string_n(rc, buff, sizeof(buff)); |
|
PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL3, |
|
"---> SSL: Not connected %d %s", ssl_rsn, buff)); |
|
} |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return -1; | return -1; |
} | } |
|
|
|
// Wait until the socket is ready for reading or writing (as |
|
// appropriate) and then retry the SSL_connect() |
|
|
|
fd_set fd; |
|
FD_ZERO(&fd); |
|
FD_SET(_socket, &fd); |
|
struct timeval timeoutValue = |
|
{ timeoutMilliseconds/1000, timeoutMilliseconds%1000*1000 }; |
|
int selectResult = -1; |
|
|
|
if (ssl_rsn == SSL_ERROR_WANT_READ) |
|
{ |
|
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, |
|
"---> SSL: Retry WANT_READ"); |
|
PEGASUS_RETRY_SYSTEM_CALL( |
|
select(FD_SETSIZE, &fd, NULL, NULL, &timeoutValue), |
|
selectResult); |
|
} |
|
else // (ssl_rsn == SSL_ERROR_WANT_WRITE) |
|
{ |
|
PEGASUS_ASSERT(ssl_rsn == SSL_ERROR_WANT_WRITE); |
|
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, |
|
"---> SSL: Retry WANT_WRITE"); |
|
PEGASUS_RETRY_SYSTEM_CALL( |
|
select(FD_SETSIZE, NULL, &fd, NULL, &timeoutValue), |
|
selectResult); |
} | } |
else if (ssl_rc == 0) |
|
|
// Check the result of select. |
|
if (selectResult == 0) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL3, |
"---> SSL: Shutdown SSL_connect()"); |
"---> SSL: Failed to connect, connection timed out."); |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_METHOD_EXIT(); |
"Error string: " + String(ERR_error_string(ssl_rc, NULL))); |
return -1; |
|
} |
|
else if (selectResult == PEGASUS_SOCKET_ERROR) |
|
{ |
|
PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL3, |
|
"---> SSL: Failed to connect, select error, return code = %d", |
|
selectResult)); |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return -1; | return -1; |
} | } |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Connected"); |
// else retry the SSL_connect() |
|
} |
|
|
|
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Connected"); |
| |
if (_SSLContext->isPeerVerificationEnabled()) | if (_SSLContext->isPeerVerificationEnabled()) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"Attempting to verify server certificate."); | "Attempting to verify server certificate."); |
| |
X509* server_cert = SSL_get_peer_certificate(_SSLConnection); | X509* server_cert = SSL_get_peer_certificate(_SSLConnection); |
|
|
| |
if (SSL_get_verify_result(_SSLConnection) == X509_V_OK) | if (SSL_get_verify_result(_SSLConnection) == X509_V_OK) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"--->SSL: Server Certificate verified."); | "--->SSL: Server Certificate verified."); |
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"--->SSL: Server Certificate not verified, but the " | "--->SSL: Server Certificate not verified, but the " |
"callback overrode the default error."); | "callback overrode the default error."); |
} | } |
|
|
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"-->SSL: Server not certified, no certificate received."); | "-->SSL: Server not certified, no certificate received."); |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return -1; | return -1; |
|
|
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, |
"---> SSL: Server certification disabled"); | "---> SSL: Server certification disabled"); |
} | } |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return ssl_rc; |
return 1; |
} | } |
| |
Boolean SSLSocket::isPeerVerificationEnabled() | Boolean SSLSocket::isPeerVerificationEnabled() |
|
|
| |
Boolean MP_Socket::isSecure() {return _isSecure;} | Boolean MP_Socket::isSecure() {return _isSecure;} |
| |
Boolean MP_Socket::incompleteReadOccurred(Sint32 retCode) |
Boolean MP_Socket::incompleteSecureReadOccurred(Sint32 retCode) |
{ | { |
if (_isSecure) | if (_isSecure) |
return _sslsock->incompleteReadOccurred(retCode); |
return _sslsock->incompleteSecureReadOccurred(retCode); |
return (retCode <= 0); |
return false; |
} | } |
| |
SocketHandle MP_Socket::getSocket() | SocketHandle MP_Socket::getSocket() |
|
|
Socket::close(_socket); | Socket::close(_socket); |
} | } |
| |
void MP_Socket::enableBlocking() |
|
{ |
|
if (_isSecure) |
|
_sslsock->enableBlocking(); |
|
else |
|
Socket::enableBlocking(_socket); |
|
} |
|
|
|
void MP_Socket::disableBlocking() | void MP_Socket::disableBlocking() |
{ | { |
if (_isSecure) | if (_isSecure) |
|
|
return 1; | return 1; |
} | } |
| |
Sint32 MP_Socket::connect() |
Sint32 MP_Socket::connect(Uint32 timeoutMilliseconds) |
{ | { |
if (_isSecure) | if (_isSecure) |
if (_sslsock->connect() < 0) return -1; |
if (_sslsock->connect(timeoutMilliseconds) < 0) return -1; |
return 0; | return 0; |
} | } |
| |
|
|
| |
Boolean MP_Socket::isSecure() {return _isSecure;} | Boolean MP_Socket::isSecure() {return _isSecure;} |
| |
Boolean MP_Socket::incompleteReadOccurred(Sint32 retCode) |
Boolean MP_Socket::incompleteSecureReadOccurred(Sint32 retCode) |
{ | { |
return (retCode <= 0); |
return false; |
} | } |
| |
SocketHandle MP_Socket::getSocket() | SocketHandle MP_Socket::getSocket() |
|
|
Socket::close(_socket); | Socket::close(_socket); |
} | } |
| |
void MP_Socket::enableBlocking() |
|
{ |
|
Socket::enableBlocking(_socket); |
|
} |
|
|
|
void MP_Socket::disableBlocking() | void MP_Socket::disableBlocking() |
{ | { |
Socket::disableBlocking(_socket); | Socket::disableBlocking(_socket); |
|
|
| |
if (isSecure()) | if (isSecure()) |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> HTTPS processing."); |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> HTTPS processing."); |
rc = ATTLS_zOS_query(); | rc = ATTLS_zOS_query(); |
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, |
PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, |
"---> Normal HTTP processing."); | "---> Normal HTTP processing."); |
rc = 1; | rc = 1; |
} | } |
|
|
#endif | #endif |
} | } |
| |
Sint32 MP_Socket::connect() { return 0; } |
Sint32 MP_Socket::connect(Uint32 timeoutMilliseconds) { return 0; } |
| |
Boolean MP_Socket::isPeerVerificationEnabled() { return false; } | Boolean MP_Socket::isPeerVerificationEnabled() { return false; } |
| |