summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Ice/SslConnectionOpenSSLServer.cpp')
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLServer.cpp858
1 files changed, 429 insertions, 429 deletions
diff --git a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
index 6fcf3d16de2..0306d5780ab 100644
--- a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
@@ -1,429 +1,429 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <string>
-#include <sstream>
-#include <Ice/Network.h>
-#include <Ice/Security.h>
-#include <Ice/SslException.h>
-#include <Ice/SslConnectionOpenSSLServer.h>
-
-using IceSecurity::Ssl::ReInitException;
-using IceSecurity::Ssl::ShutdownException;
-using IceSecurity::Ssl::InitException;
-using namespace IceInternal;
-using namespace std;
-
-//////////////////////////////////////
-////////// ServerConnection //////////
-//////////////////////////////////////
-
-//
-// Public Methods
-//
-
-IceSecurity::Ssl::OpenSSL::ServerConnection::ServerConnection(SSL* connection, string& systemID) :
- Connection(connection, systemID)
-{
-}
-
-IceSecurity::Ssl::OpenSSL::ServerConnection::~ServerConnection()
-{
- METHOD_INV("OpenSSL::ServerConnection::~ServerConnection()");
-
- shutdown();
-
- METHOD_RET("OpenSSL::ServerConnection::~ServerConnection()");
-}
-
-void
-IceSecurity::Ssl::OpenSSL::ServerConnection::shutdown()
-{
- METHOD_INV("OpenSSL::ServerConnection::shutdown()");
-
- if (_sslConnection != 0)
- {
- // NOTE: This call is how the server application shuts down, but they are
- // also using SSL_CTX_set_quiet_shutdown().
- // SSL_set_shutdown(_sslConnection,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
-
- int shutdown = 0;
- int retries = 100;
-
- do
- {
- shutdown = SSL_shutdown(_sslConnection);
- retries--;
- }
- while ((shutdown == 0) && (retries > 0));
-
- if (shutdown <= 0)
- {
- ostringstream s;
- s << "SSL shutdown failure encountered: code[" << shutdown << "] retries[";
- s << retries << "]\n" << fdToString(SSL_get_fd(_sslConnection));
- PROTOCOL_DEBUG(s.str());
- }
- }
-
- Connection::shutdown();
-
- METHOD_RET("OpenSSL::ServerConnection::shutdown()");
-}
-
-int
-IceSecurity::Ssl::OpenSSL::ServerConnection::init(int timeout)
-{
- JTCSyncT<JTCMutex> sync(_initMutex);
-
- int retCode = 0;
-
- METHOD_INV("OpenSSL::ServerConnection::init()");
-
- if (!SSL_is_init_finished(_sslConnection))
- {
- int i = 0;
-
- if (initWantRead)
- {
- i = readSelect(timeout);
- }
- else if (initWantWrite)
- {
- i = writeSelect(timeout);
- }
-
- if (initWantRead && i == 0)
- {
- return 0;
- }
-
- if (initWantWrite && i == 0)
- {
- return 0;
- }
-
- initWantRead = 0;
- initWantWrite = 0;
-
- int result = accept();
-
- // Find out what the error was (if any).
- int code = getLastError();
-
- // We're doing an Accept and we don't get a retry on the socket.
- if ((result <= 0) && (BIO_sock_should_retry(result) == 0))
- {
- // Socket can't retry - bad scene, find out why.
- long verify_error = SSL_get_verify_result(_sslConnection);
-
- if (verify_error != X509_V_OK)
- {
- // SSL Protocol Error - Shutdown the Connection.
- string errorString = "SSL certificate verification error.";
-
- EXCEPTION(errorString);
-
- throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
- }
- else
- {
- // SSL Protocol Error - Shutdown the Connection.
- string errorString = "SSL Protocol Error.";
-
- EXCEPTION(errorString);
-
- throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
- }
- }
-
- switch (code)
- {
- case SSL_ERROR_WANT_READ:
- {
- initWantRead = 1;
- break;
- }
-
- case SSL_ERROR_WANT_WRITE:
- {
- initWantWrite = 1;
- break;
- }
-
-
- case SSL_ERROR_NONE:
- case SSL_ERROR_WANT_X509_LOOKUP:
- {
- // Do nothing, life is good!
- break;
- }
-
- case SSL_ERROR_SYSCALL:
- {
- // This is a SOCKET_ERROR, but we don't use
- // this define here as OpenSSL doesn't refer
- // to it as a SOCKET_ERROR (but that's what it is
- // if you look at their code).
- if(result == -1)
- {
- if (interrupted())
- {
- break;
- }
-
- if (wouldBlock())
- {
- readSelect(timeout);
- break;
- }
-
- if (connectionLost())
- {
- ConnectionLostException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
- else
- {
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
- }
- else
- {
- string errorString = "SSL_ERROR_SYSCALL: During init().";
-
- EXCEPTION(errorString);
-
- throw InitException(errorString.c_str(), __FILE__, __LINE__);
- }
- }
-
- case SSL_ERROR_SSL:
- {
- string errorString = "SSL_ERROR_SSL: During init().";
-
- EXCEPTION(errorString);
-
- throw InitException(errorString.c_str(), __FILE__, __LINE__);
- }
- }
-
- retCode = SSL_is_init_finished(_sslConnection);
-
- if (retCode > 0)
- {
- // Init finished, look at the connection information.
- showConnectionInfo();
- }
- }
- else
- {
- retCode = 1;
- }
-
- METHOD_RET("OpenSSL::ServerConnection::init()");
-
- return retCode;
-}
-
-int
-IceSecurity::Ssl::OpenSSL::ServerConnection::read(Buffer& buf, int timeout)
-{
- METHOD_INV("OpenSSL::ServerConnection::read(Buffer&, int)");
-
- int bytesRead = 1;
- int totalBytesRead = 0;
-
- // We keep reading until we're done.
- while ((buf.i != buf.b.end()) && bytesRead)
- {
- // Copy over bytes from _inBuffer to buf.
- bytesRead = readInBuffer(buf);
-
- // Nothing in the _inBuffer?
- if (!bytesRead)
- {
- // Read from SSL.
- bytesRead = readSSL(buf, timeout);
- }
-
- // Keep track of the total bytes read.
- totalBytesRead += bytesRead;
- }
-
- METHOD_RET("OpenSSL::ServerConnection::read(Buffer&, int)");
-
- return totalBytesRead;
-}
-
-int
-IceSecurity::Ssl::OpenSSL::ServerConnection::write(Buffer& buf, int timeout)
-{
- METHOD_INV("OpenSSL::ServerConnection::write(Buffer&, int)");
-
- int totalBytesWritten = 0;
- int bytesWritten = 0;
-
- int packetSize = buf.b.end() - buf.i;
-
-#ifdef WIN32
- //
- // Limit packet size to avoid performance problems on WIN32.
- //
- if (packetSize > 64 * 1024)
- {
- packetSize = 64 * 1024;
- }
-#endif
-
- // We keep writing until we're done.
- while (buf.i != buf.b.end())
- {
- // Ensure we're initialized.
- if (init(timeout))
- {
- // Perform a select on the socket.
- if (!writeSelect(timeout))
- {
- // We're done here.
- break;
- }
-
- bytesWritten = sslWrite((char *)buf.i, packetSize);
-
- switch (getLastError())
- {
- case SSL_ERROR_NONE:
- {
- ostringstream s;
-
- s << "sent " << bytesWritten << " of " << packetSize;
- s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection));
-
- PROTOCOL(s.str());
-
- totalBytesWritten += bytesWritten;
-
- buf.i += bytesWritten;
-
- if (packetSize > buf.b.end() - buf.i)
- {
- packetSize = buf.b.end() - buf.i;
- }
- continue;
- }
-
- case SSL_ERROR_WANT_WRITE: // Retry...
- {
- PROTOCOL("Error SSL_ERROR_WANT_WRITE: Repeating as per protocol.");
-
- continue;
- }
-
- case SSL_ERROR_WANT_READ: // The demo server ignores this error.
- {
- PROTOCOL("Error SSL_ERROR_WANT_READ: Ignoring as per protocol.");
-
- continue;
- }
-
- case SSL_ERROR_WANT_X509_LOOKUP: // The demo server ignores this error.
- {
- PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol.");
-
- continue;
- }
-
- case SSL_ERROR_SYSCALL:
- {
- if (bytesWritten == -1)
- {
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
- else
- {
- string errorString = "SSL_ERROR_SYSCALL";
-
- EXCEPTION(errorString);
-
- throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
- }
- }
-
- case SSL_ERROR_SSL:
- {
- string errorString = "SSL_ERROR_SSL";
-
- EXCEPTION(errorString);
-
- throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
- }
-
- case SSL_ERROR_ZERO_RETURN:
- {
- string errorString = "SSL_ERROR_ZERO_RETURN";
-
- EXCEPTION(errorString);
-
- throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
- }
- }
- }
- }
-
- METHOD_RET("OpenSSL::ServerConnection::write(Buffer&, int)");
-
- return totalBytesWritten;
-}
-
-//
-// Protected Methods
-//
-
-void
-IceSecurity::Ssl::OpenSSL::ServerConnection::showConnectionInfo()
-{
- METHOD_INV("OpenSSL::ServerConnection::showConnectionInfo()");
-
- // Only in extreme cases do we enable this, partially because it doesn't use the Logger.
- if (_traceLevels->security >= SECURITY_PROTOCOL_DEBUG)
- {
- PROTOCOL_DEBUG("Begin Connection Information");
-
- BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE);
-
- showCertificateChain(bio);
-
- showPeerCertificate(bio,"Server");
-
- showSharedCiphers(bio);
-
- showSelectedCipherInfo(bio);
-
- showHandshakeStats(bio);
-
- showSessionInfo(bio);
-
- PROTOCOL_DEBUG("End of Connection Information");
-
- if (bio != 0)
- {
- BIO_free(bio);
- bio = 0;
- }
- }
-
- METHOD_RET("OpenSSL::ServerConnection::showConnectionInfo()");
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <string>
+#include <sstream>
+#include <Ice/Network.h>
+#include <Ice/Security.h>
+#include <Ice/SslException.h>
+#include <Ice/SslConnectionOpenSSLServer.h>
+
+using IceSecurity::Ssl::ReInitException;
+using IceSecurity::Ssl::ShutdownException;
+using IceSecurity::Ssl::InitException;
+using namespace IceInternal;
+using namespace std;
+
+//////////////////////////////////////
+////////// ServerConnection //////////
+//////////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::OpenSSL::ServerConnection::ServerConnection(SSL* connection, string& systemID) :
+ Connection(connection, systemID)
+{
+}
+
+IceSecurity::Ssl::OpenSSL::ServerConnection::~ServerConnection()
+{
+ METHOD_INV("OpenSSL::ServerConnection::~ServerConnection()");
+
+ shutdown();
+
+ METHOD_RET("OpenSSL::ServerConnection::~ServerConnection()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::ServerConnection::shutdown()
+{
+ METHOD_INV("OpenSSL::ServerConnection::shutdown()");
+
+ if (_sslConnection != 0)
+ {
+ // NOTE: This call is how the server application shuts down, but they are
+ // also using SSL_CTX_set_quiet_shutdown().
+ // SSL_set_shutdown(_sslConnection,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+
+ int shutdown = 0;
+ int retries = 100;
+
+ do
+ {
+ shutdown = SSL_shutdown(_sslConnection);
+ retries--;
+ }
+ while ((shutdown == 0) && (retries > 0));
+
+ if (shutdown <= 0)
+ {
+ ostringstream s;
+ s << "SSL shutdown failure encountered: code[" << shutdown << "] retries[";
+ s << retries << "]\n" << fdToString(SSL_get_fd(_sslConnection));
+ PROTOCOL_DEBUG(s.str());
+ }
+ }
+
+ Connection::shutdown();
+
+ METHOD_RET("OpenSSL::ServerConnection::shutdown()");
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ServerConnection::init(int timeout)
+{
+ JTCSyncT<JTCMutex> sync(_initMutex);
+
+ int retCode = 0;
+
+ METHOD_INV("OpenSSL::ServerConnection::init()");
+
+ if (!SSL_is_init_finished(_sslConnection))
+ {
+ int i = 0;
+
+ if (initWantRead)
+ {
+ i = readSelect(timeout);
+ }
+ else if (initWantWrite)
+ {
+ i = writeSelect(timeout);
+ }
+
+ if (initWantRead && i == 0)
+ {
+ return 0;
+ }
+
+ if (initWantWrite && i == 0)
+ {
+ return 0;
+ }
+
+ initWantRead = 0;
+ initWantWrite = 0;
+
+ int result = accept();
+
+ // Find out what the error was (if any).
+ int code = getLastError();
+
+ // We're doing an Accept and we don't get a retry on the socket.
+ if ((result <= 0) && (BIO_sock_should_retry(result) == 0))
+ {
+ // Socket can't retry - bad scene, find out why.
+ long verify_error = SSL_get_verify_result(_sslConnection);
+
+ if (verify_error != X509_V_OK)
+ {
+ // SSL Protocol Error - Shutdown the Connection.
+ string errorString = "SSL certificate verification error.";
+
+ EXCEPTION(errorString);
+
+ throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ else
+ {
+ // SSL Protocol Error - Shutdown the Connection.
+ string errorString = "SSL Protocol Error.";
+
+ EXCEPTION(errorString);
+
+ throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ switch (code)
+ {
+ case SSL_ERROR_WANT_READ:
+ {
+ initWantRead = 1;
+ break;
+ }
+
+ case SSL_ERROR_WANT_WRITE:
+ {
+ initWantWrite = 1;
+ break;
+ }
+
+
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ {
+ // Do nothing, life is good!
+ break;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ {
+ // This is a SOCKET_ERROR, but we don't use
+ // this define here as OpenSSL doesn't refer
+ // to it as a SOCKET_ERROR (but that's what it is
+ // if you look at their code).
+ if(result == -1)
+ {
+ if (interrupted())
+ {
+ break;
+ }
+
+ if (wouldBlock())
+ {
+ readSelect(timeout);
+ break;
+ }
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ else
+ {
+ string errorString = "SSL_ERROR_SYSCALL: During init().";
+
+ EXCEPTION(errorString);
+
+ throw InitException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ case SSL_ERROR_SSL:
+ {
+ string errorString = "SSL_ERROR_SSL: During init().";
+
+ EXCEPTION(errorString);
+
+ throw InitException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ retCode = SSL_is_init_finished(_sslConnection);
+
+ if (retCode > 0)
+ {
+ // Init finished, look at the connection information.
+ showConnectionInfo();
+ }
+ }
+ else
+ {
+ retCode = 1;
+ }
+
+ METHOD_RET("OpenSSL::ServerConnection::init()");
+
+ return retCode;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ServerConnection::read(Buffer& buf, int timeout)
+{
+ METHOD_INV("OpenSSL::ServerConnection::read(Buffer&, int)");
+
+ int bytesRead = 1;
+ int totalBytesRead = 0;
+
+ // We keep reading until we're done.
+ while ((buf.i != buf.b.end()) && bytesRead)
+ {
+ // Copy over bytes from _inBuffer to buf.
+ bytesRead = readInBuffer(buf);
+
+ // Nothing in the _inBuffer?
+ if (!bytesRead)
+ {
+ // Read from SSL.
+ bytesRead = readSSL(buf, timeout);
+ }
+
+ // Keep track of the total bytes read.
+ totalBytesRead += bytesRead;
+ }
+
+ METHOD_RET("OpenSSL::ServerConnection::read(Buffer&, int)");
+
+ return totalBytesRead;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ServerConnection::write(Buffer& buf, int timeout)
+{
+ METHOD_INV("OpenSSL::ServerConnection::write(Buffer&, int)");
+
+ int totalBytesWritten = 0;
+ int bytesWritten = 0;
+
+ int packetSize = buf.b.end() - buf.i;
+
+#ifdef WIN32
+ //
+ // Limit packet size to avoid performance problems on WIN32.
+ //
+ if (packetSize > 64 * 1024)
+ {
+ packetSize = 64 * 1024;
+ }
+#endif
+
+ // We keep writing until we're done.
+ while (buf.i != buf.b.end())
+ {
+ // Ensure we're initialized.
+ if (init(timeout))
+ {
+ // Perform a select on the socket.
+ if (!writeSelect(timeout))
+ {
+ // We're done here.
+ break;
+ }
+
+ bytesWritten = sslWrite((char *)buf.i, packetSize);
+
+ switch (getLastError())
+ {
+ case SSL_ERROR_NONE:
+ {
+ ostringstream s;
+
+ s << "sent " << bytesWritten << " of " << packetSize;
+ s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection));
+
+ PROTOCOL(s.str());
+
+ totalBytesWritten += bytesWritten;
+
+ buf.i += bytesWritten;
+
+ if (packetSize > buf.b.end() - buf.i)
+ {
+ packetSize = buf.b.end() - buf.i;
+ }
+ continue;
+ }
+
+ case SSL_ERROR_WANT_WRITE: // Retry...
+ {
+ PROTOCOL("Error SSL_ERROR_WANT_WRITE: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_READ: // The demo server ignores this error.
+ {
+ PROTOCOL("Error SSL_ERROR_WANT_READ: Ignoring as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_X509_LOOKUP: // The demo server ignores this error.
+ {
+ PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ {
+ if (bytesWritten == -1)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ string errorString = "SSL_ERROR_SYSCALL";
+
+ EXCEPTION(errorString);
+
+ throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ case SSL_ERROR_SSL:
+ {
+ string errorString = "SSL_ERROR_SSL";
+
+ EXCEPTION(errorString);
+
+ throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ case SSL_ERROR_ZERO_RETURN:
+ {
+ string errorString = "SSL_ERROR_ZERO_RETURN";
+
+ EXCEPTION(errorString);
+
+ throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+ }
+ }
+
+ METHOD_RET("OpenSSL::ServerConnection::write(Buffer&, int)");
+
+ return totalBytesWritten;
+}
+
+//
+// Protected Methods
+//
+
+void
+IceSecurity::Ssl::OpenSSL::ServerConnection::showConnectionInfo()
+{
+ METHOD_INV("OpenSSL::ServerConnection::showConnectionInfo()");
+
+ // Only in extreme cases do we enable this, partially because it doesn't use the Logger.
+ if (_traceLevels->security >= SECURITY_PROTOCOL_DEBUG)
+ {
+ PROTOCOL_DEBUG("Begin Connection Information");
+
+ BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+ showCertificateChain(bio);
+
+ showPeerCertificate(bio,"Server");
+
+ showSharedCiphers(bio);
+
+ showSelectedCipherInfo(bio);
+
+ showHandshakeStats(bio);
+
+ showSessionInfo(bio);
+
+ PROTOCOL_DEBUG("End of Connection Information");
+
+ if (bio != 0)
+ {
+ BIO_free(bio);
+ bio = 0;
+ }
+ }
+
+ METHOD_RET("OpenSSL::ServerConnection::showConnectionInfo()");
+}