gloox
1.0
|
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 if( !m_tls->init( m_clientKey, m_clientCerts, m_cacerts ) ) 00069 return ConnTlsFailed; 00070 00071 // m_tls->setCACerts( m_cacerts ); 00072 // m_tls->setClientCert( m_clientKey, m_clientCerts ); 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* /*connection*/, const std::string& data ) 00149 { 00150 if( m_tls ) 00151 m_tls->decrypt( data ); 00152 } 00153 00154 void ConnectionTLS::handleConnect( const ConnectionBase* /*connection*/ ) 00155 { 00156 if( m_tls ) 00157 m_tls->handshake(); 00158 } 00159 00160 void ConnectionTLS::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError reason ) 00161 { 00162 if( m_handler ) 00163 m_handler->handleDisconnect( this, reason ); 00164 00165 cleanup(); 00166 } 00167 00168 void ConnectionTLS::handleEncryptedData( const TLSBase* /*tls*/, const std::string& data ) 00169 { 00170 if( m_connection ) 00171 m_connection->send( data ); 00172 } 00173 00174 void ConnectionTLS::handleDecryptedData( const TLSBase* /*tls*/, 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 }