diff options
author | Anthony Neal <aneal@zeroc.com> | 2002-09-11 12:33:02 +0000 |
---|---|---|
committer | Anthony Neal <aneal@zeroc.com> | 2002-09-11 12:33:02 +0000 |
commit | 22056550f5f34cc2ee1cd28a23fd40545c566c4b (patch) | |
tree | dcd27d328d2e11f09924a407cc5fb08dfac32d8d /cpp/src/IceSSL/SslTransceiver.h | |
parent | fixed retry bug (diff) | |
download | ice-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.h | 174 |
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; }; } |