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