connectiontls.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "connectiontls.h"
00015 #include "tlsdefault.h"
00016
00017 namespace gloox
00018 {
00019
00020 ConnectionTLS::ConnectionTLS( ConnectionDataHandler* cdh, ConnectionBase* conn, const LogSink& log )
00021 : ConnectionBase( cdh ),
00022 m_connection( conn ), m_tls( 0 ), m_tlsHandler( 0 ),
00023 m_log( log )
00024 {
00025 if( m_connection )
00026 m_connection->registerConnectionDataHandler( this );
00027 }
00028
00029 ConnectionTLS::ConnectionTLS( ConnectionBase* conn, const LogSink& log )
00030 : ConnectionBase( 0 ),
00031 m_connection( conn ), m_tls( 0 ), m_tlsHandler( 0 ), m_log( log )
00032 {
00033 if( m_connection )
00034 m_connection->registerConnectionDataHandler( this );
00035 }
00036
00037 ConnectionTLS::~ConnectionTLS()
00038 {
00039 delete m_connection;
00040 delete m_tls;
00041 }
00042
00043 void ConnectionTLS::setConnectionImpl( ConnectionBase* connection )
00044 {
00045 if( m_connection )
00046 m_connection->registerConnectionDataHandler( 0 );
00047
00048 m_connection = connection;
00049
00050 if( m_connection )
00051 m_connection->registerConnectionDataHandler( this );
00052 }
00053
00054 ConnectionError ConnectionTLS::connect()
00055 {
00056 if( !m_connection )
00057 return ConnNotConnected;
00058
00059 if( m_state == StateConnected )
00060 return ConnNoError;
00061
00062 if( !m_tls )
00063 m_tls = getTLSBase( this, m_connection->server() );
00064
00065 if( !m_tls )
00066 return ConnTlsNotAvailable;
00067
00068 if( !m_tls->init( m_clientKey, m_clientCerts, m_cacerts ) )
00069 return ConnTlsFailed;
00070
00071
00072
00073
00074 m_state = StateConnecting;
00075
00076 if( m_connection->state() != StateConnected )
00077 return m_connection->connect();
00078
00079 if( m_tls->handshake() )
00080 return ConnNoError;
00081 else
00082 return ConnTlsFailed;
00083 }
00084
00085 ConnectionError ConnectionTLS::recv( int timeout )
00086 {
00087 if( m_connection->state() == StateConnected )
00088 {
00089 return m_connection->recv( timeout );
00090 }
00091 else
00092 {
00093 m_log.log( LogLevelWarning, LogAreaClassConnectionTLS,
00094 "Attempt to receive data on a connection that is not connected (or is connecting)" );
00095 return ConnNotConnected;
00096 }
00097 }
00098
00099 bool ConnectionTLS::send( const std::string& data )
00100 {
00101 if( m_state != StateConnected )
00102 return false;
00103
00104 m_tls->encrypt( data );
00105 return true;
00106 }
00107
00108 ConnectionError ConnectionTLS::receive()
00109 {
00110 if( m_connection )
00111 return m_connection->receive();
00112 else
00113 return ConnNotConnected;
00114 }
00115
00116 void ConnectionTLS::disconnect()
00117 {
00118 if( m_connection )
00119 m_connection->disconnect();
00120
00121 cleanup();
00122 }
00123
00124 void ConnectionTLS::cleanup()
00125 {
00126 if( m_connection )
00127 m_connection->cleanup();
00128 if( m_tls )
00129 m_tls->cleanup();
00130
00131 m_state = StateDisconnected;
00132 }
00133
00134 void ConnectionTLS::getStatistics( long int& totalIn, long int& totalOut )
00135 {
00136 if( m_connection )
00137 m_connection->getStatistics( totalIn, totalOut );
00138 }
00139
00140 ConnectionBase* ConnectionTLS::newInstance() const
00141 {
00142 ConnectionBase* newConn = 0;
00143 if( m_connection )
00144 newConn = m_connection->newInstance();
00145 return new ConnectionTLS( m_handler, newConn, m_log );
00146 }
00147
00148 void ConnectionTLS::handleReceivedData( const ConnectionBase* , const std::string& data )
00149 {
00150 if( m_tls )
00151 m_tls->decrypt( data );
00152 }
00153
00154 void ConnectionTLS::handleConnect( const ConnectionBase* )
00155 {
00156 if( m_tls )
00157 m_tls->handshake();
00158 }
00159
00160 void ConnectionTLS::handleDisconnect( const ConnectionBase* , ConnectionError reason )
00161 {
00162 if( m_handler )
00163 m_handler->handleDisconnect( this, reason );
00164
00165 cleanup();
00166 }
00167
00168 void ConnectionTLS::handleEncryptedData( const TLSBase* , const std::string& data )
00169 {
00170 if( m_connection )
00171 m_connection->send( data );
00172 }
00173
00174 void ConnectionTLS::handleDecryptedData( const TLSBase* , const std::string& data )
00175 {
00176 if( m_handler )
00177 m_handler->handleReceivedData( this, data );
00178 else
00179 {
00180 m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "Data received and decrypted but no handler" );
00181 }
00182 }
00183
00184 void ConnectionTLS::handleHandshakeResult( const TLSBase* tls, bool success, CertInfo& certinfo )
00185 {
00186 if( success )
00187 {
00188 m_state = StateConnected;
00189 m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "TLS handshake succeeded" );
00190 if( m_tlsHandler )
00191 m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
00192 if( m_handler )
00193 m_handler->handleConnect( this );
00194 }
00195 else
00196 {
00197 m_state = StateDisconnected;
00198 m_log.log( LogLevelWarning, LogAreaClassConnectionTLS, "TLS handshake failed" );
00199 if( m_tlsHandler )
00200 m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
00201 }
00202 }
00203
00204 }