Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

connectiontls.cpp

00001 /*
00002  * Copyright (c) 2007-2009 by Jakob Schroeter <js@camaya.net>
00003  * This file is part of the gloox library. http://camaya.net/gloox
00004  *
00005  * This software is distributed under a license. The full license
00006  * agreement can be found in the file LICENSE in this distribution.
00007  * This software may not be copied, modified, sold or distributed
00008  * other than expressed in the named license agreement.
00009  *
00010  * This software is distributed without any warranty.
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* /*connection*/, const std::string& data )
00148   {
00149     if( m_tls )
00150       m_tls->decrypt( data );
00151   }
00152 
00153   void ConnectionTLS::handleConnect( const ConnectionBase* /*connection*/ )
00154   {
00155     if( m_tls )
00156       m_tls->handshake();
00157   }
00158 
00159   void ConnectionTLS::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError reason )
00160   {
00161     if( m_handler )
00162       m_handler->handleDisconnect( this, reason );
00163 
00164     cleanup();
00165   }
00166 
00167   void ConnectionTLS::handleEncryptedData( const TLSBase* /*tls*/, const std::string& data )
00168   {
00169     if( m_connection )
00170       m_connection->send( data );
00171   }
00172 
00173   void ConnectionTLS::handleDecryptedData( const TLSBase* /*tls*/, 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 }

Generated on Tue May 4 16:35:12 2010 for gloox by  doxygen 1.4.1