summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/SslTransceiver.h
diff options
context:
space:
mode:
authorAnthony Neal <aneal@zeroc.com>2002-09-11 12:33:02 +0000
committerAnthony Neal <aneal@zeroc.com>2002-09-11 12:33:02 +0000
commit22056550f5f34cc2ee1cd28a23fd40545c566c4b (patch)
treedcd27d328d2e11f09924a407cc5fb08dfac32d8d /cpp/src/IceSSL/SslTransceiver.h
parentfixed retry bug (diff)
downloadice-22056550f5f34cc2ee1cd28a23fd40545c566c4b.tar.bz2
ice-22056550f5f34cc2ee1cd28a23fd40545c566c4b.tar.xz
ice-22056550f5f34cc2ee1cd28a23fd40545c566c4b.zip
Removed the Connection classes, added the new SslTransceiver hierarchy,
cleaned up a lot of code.
Diffstat (limited to 'cpp/src/IceSSL/SslTransceiver.h')
-rw-r--r--cpp/src/IceSSL/SslTransceiver.h174
1 files changed, 165 insertions, 9 deletions
diff --git a/cpp/src/IceSSL/SslTransceiver.h b/cpp/src/IceSSL/SslTransceiver.h
index 17da4cb64dd..d2b6e3f2894 100644
--- a/cpp/src/IceSSL/SslTransceiver.h
+++ b/cpp/src/IceSSL/SslTransceiver.h
@@ -13,15 +13,115 @@
#include <Ice/LoggerF.h>
#include <Ice/Transceiver.h>
-#include <IceSSL/SslConnectionF.h>
+#include <Ice/Buffer.h>
+#include <IceUtil/Mutex.h>
+#include <IceSSL/SslTransceiverF.h>
#include <IceSSL/PluginBaseIF.h>
#include <IceSSL/TraceLevelsF.h>
+#include <IceSSL/CertificateVerifierF.h>
+#include <IceSSL/CertificateVerifierOpenSSL.h>
+
+#include <openssl/ssl.h>
+#include <map>
namespace IceSSL
{
-class SslConnector;
-class SslAcceptor;
+class SafeFlag
+{
+public:
+
+ SafeFlag(bool flagVal = false)
+ {
+ _flag = flagVal;
+ }
+
+ ~SafeFlag()
+ {
+ }
+
+ bool checkAndSet()
+ {
+ IceUtil::Mutex::Lock sync(_mutex);
+
+ if(_flag)
+ {
+ return false;
+ }
+ else
+ {
+ _flag = true;
+ return true;
+ }
+ }
+
+ bool check()
+ {
+ IceUtil::Mutex::Lock sync(_mutex);
+ return _flag;
+ }
+
+ void set()
+ {
+ IceUtil::Mutex::Lock sync(_mutex);
+ _flag = true;
+ }
+
+ void unset()
+ {
+ IceUtil::Mutex::Lock sync(_mutex);
+ _flag = false;
+ }
+
+private:
+
+ IceUtil::Mutex _mutex;
+ bool _flag;
+};
+
+class HandshakeSentinel
+{
+public:
+
+ HandshakeSentinel(SafeFlag& handshakeFlag) :
+ _flag(handshakeFlag)
+ {
+ _ownHandshake = _flag.checkAndSet();
+ }
+
+ ~HandshakeSentinel()
+ {
+ if(_ownHandshake)
+ {
+ _flag.unset();
+ }
+ }
+
+ bool ownHandshake()
+ {
+ return _ownHandshake;
+ }
+
+private:
+
+ bool _ownHandshake;
+ SafeFlag& _flag;
+};
+
+// NOTE: This is a mapping from SSL* to SslTransceiver*, for use with the verifyCallback.
+// I have purposely not used SslTransceiverPtr here, as connections register themselves
+// with this map on construction and unregister themselves in the destructor. If
+// this map used SslTransceiverPtr, SslTransceiver instances would never destruct as there
+// would always be a reference to them from the map.
+class SslTransceiver;
+typedef std::map<SSL*, SslTransceiver*> SslTransceiverMap;
+
+typedef enum
+{
+ Handshake, // The connection is negotiating a connection with the peer.
+ Shutdown, // The connection is in the process of shutting down.
+ Connected // The connection is connected - communication may continue.
+} ConnectPhase;
class SslTransceiver : public IceInternal::Transceiver
{
@@ -30,17 +130,73 @@ public:
virtual SOCKET fd();
virtual void close();
virtual void shutdown();
- virtual void write(IceInternal::Buffer&, int);
+ virtual void write(IceInternal::Buffer&, int) = 0;
virtual void read(IceInternal::Buffer&, int);
virtual std::string toString() const;
-private:
+ virtual int handshake(int timeout = 0) = 0;
+ void setHandshakeReadTimeout(int timeout);
+ static SslTransceiverPtr getTransceiver(SSL*);
+
+ // Callback from OpenSSL for purposes of certificate verification
+ int verifyCertificate(int, X509_STORE_CTX*);
+
+protected:
+
+ virtual int internalShutdown(int timeout = 0);
+
+ int connect();
+ int accept();
+ int renegotiate();
+ int initialize(int timeout);
+
+ int pending();
+ int getLastError() const;
+
+ int sslRead(char*, int);
+ int sslWrite(char*, int);
+
+ int select(int, bool);
+ int readSelect(int);
+ int writeSelect(int);
+
+ int readSSL(IceInternal::Buffer&, int);
+
+ static void addTransceiver(SSL*, SslTransceiver*);
+ static void removeTransceiver(SSL*);
+
+ virtual void showConnectionInfo() = 0;
+
+ void showCertificateChain(BIO*);
+ void showPeerCertificate(BIO*, const char*);
+ void showSharedCiphers(BIO*);
+ void showSessionInfo(BIO*);
+ void showSelectedCipherInfo(BIO*);
+ void showHandshakeStats(BIO*);
+ void showClientCAList(BIO*, const char*);
+
+ void setLastError(int errorCode) { _lastError = errorCode; };
+
+ static SslTransceiverMap _transceiverMap;
+ static IceUtil::Mutex _transceiverRepositoryMutex;
+
+ // Pointer to the OpenSSL Connection structure.
+ SSL* _sslConnection;
+
+ int _lastError;
+
+ IceUtil::Mutex _handshakeWaitMutex;
- SslTransceiver(const PluginBaseIPtr&, SOCKET, const ::IceSSL::ConnectionPtr&);
+ SafeFlag _handshakeFlag;
+ int _initWantRead;
+ int _initWantWrite;
+ int _handshakeReadTimeout;
+ int _readTimeout;
+ ConnectPhase _phase;
+
+ SslTransceiver(const PluginBaseIPtr&, SOCKET, const IceSSL::OpenSSL::CertificateVerifierPtr&, SSL*);
virtual ~SslTransceiver();
- friend class SslConnector;
- friend class SslAcceptor;
TraceLevelsPtr _traceLevels;
Ice::LoggerPtr _logger;
@@ -48,7 +204,7 @@ private:
fd_set _rFdSet;
fd_set _wFdSet;
- ::IceSSL::ConnectionPtr _sslConnection;
+ IceSSL::OpenSSL::CertificateVerifierPtr _certificateVerifier;
};
}