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 m_tls->setSubject( m_subject );
00069
00070 if( !m_tls->init( m_clientKey, m_clientCerts, m_cacerts ) )
00071 return ConnTlsFailed;
00072
00073 m_state = StateConnecting;
00074
00075 if( m_connection->state() != StateConnected )
00076 return m_connection->connect();
00077
00078 if( m_tls->handshake() )
00079 return ConnNoError;
00080 else
00081 return ConnTlsFailed;
00082 }
00083
00084 ConnectionError ConnectionTLS::recv( int timeout )
00085 {
00086 if( m_connection->state() == StateConnected )
00087 {
00088 return m_connection->recv( timeout );
00089 }
00090 else
00091 {
00092 m_log.log( LogLevelWarning, LogAreaClassConnectionTLS,
00093 "Attempt to receive data on a connection that is not connected (or is connecting)" );
00094 return ConnNotConnected;
00095 }
00096 }
00097
00098 bool ConnectionTLS::send( const std::string& data )
00099 {
00100 if( m_state != StateConnected )
00101 return false;
00102
00103 m_tls->encrypt( data );
00104 return true;
00105 }
00106
00107 ConnectionError ConnectionTLS::receive()
00108 {
00109 if( m_connection )
00110 return m_connection->receive();
00111 else
00112 return ConnNotConnected;
00113 }
00114
00115 void ConnectionTLS::disconnect()
00116 {
00117 if( m_connection )
00118 m_connection->disconnect();
00119
00120 cleanup();
00121 }
00122
00123 void ConnectionTLS::cleanup()
00124 {
00125 if( m_connection )
00126 m_connection->cleanup();
00127 if( m_tls )
00128 m_tls->cleanup();
00129
00130 m_state = StateDisconnected;
00131 }
00132
00133 void ConnectionTLS::getStatistics( long int& totalIn, long int& totalOut )
00134 {
00135 if( m_connection )
00136 m_connection->getStatistics( totalIn, totalOut );
00137 }
00138
00139 ConnectionBase* ConnectionTLS::newInstance() const
00140 {
00141 ConnectionBase* newConn = 0;
00142 if( m_connection )
00143 newConn = m_connection->newInstance();
00144 return new ConnectionTLS( m_handler, newConn, m_log );
00145 }
00146
00147 void ConnectionTLS::handleReceivedData( const ConnectionBase* , const std::string& data )
00148 {
00149 if( m_tls )
00150 m_tls->decrypt( data );
00151 }
00152
00153 void ConnectionTLS::handleConnect( const ConnectionBase* )
00154 {
00155 if( m_tls )
00156 m_tls->handshake();
00157 }
00158
00159 void ConnectionTLS::handleDisconnect( const ConnectionBase* , ConnectionError reason )
00160 {
00161 if( m_handler )
00162 m_handler->handleDisconnect( this, reason );
00163
00164 cleanup();
00165 }
00166
00167 void ConnectionTLS::handleEncryptedData( const TLSBase* , const std::string& data )
00168 {
00169 if( m_connection )
00170 m_connection->send( data );
00171 }
00172
00173 void ConnectionTLS::handleDecryptedData( const TLSBase* , const std::string& data )
00174 {
00175 if( m_handler )
00176 m_handler->handleReceivedData( this, data );
00177 else
00178 {
00179 m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "Data received and decrypted but no handler" );
00180 }
00181 }
00182
00183 void ConnectionTLS::handleHandshakeResult( const TLSBase* tls, bool success, CertInfo& certinfo )
00184 {
00185 if( success )
00186 {
00187 m_state = StateConnected;
00188 m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "TLS handshake succeeded" );
00189 if( m_tlsHandler )
00190 m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
00191 if( m_handler )
00192 m_handler->handleConnect( this );
00193 }
00194 else
00195 {
00196 m_state = StateDisconnected;
00197 m_log.log( LogLevelWarning, LogAreaClassConnectionTLS, "TLS handshake failed" );
00198 if( m_tlsHandler )
00199 m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
00200 }
00201 }
00202
00203 }