gloox  1.0
connectiontls.cpp
1 /*
2  * Copyright (c) 2007-2009 by Jakob Schroeter <js@camaya.net>
3  * This file is part of the gloox library. http://camaya.net/gloox
4  *
5  * This software is distributed under a license. The full license
6  * agreement can be found in the file LICENSE in this distribution.
7  * This software may not be copied, modified, sold or distributed
8  * other than expressed in the named license agreement.
9  *
10  * This software is distributed without any warranty.
11  */
12 
13 
14 #include "connectiontls.h"
15 #include "tlsdefault.h"
16 
17 namespace gloox
18 {
19 
21  : ConnectionBase( cdh ),
22  m_connection( conn ), m_tls( 0 ), m_tlsHandler( 0 ),
23  m_log( log )
24  {
25  if( m_connection )
26  m_connection->registerConnectionDataHandler( this );
27  }
28 
30  : ConnectionBase( 0 ),
31  m_connection( conn ), m_tls( 0 ), m_tlsHandler( 0 ), m_log( log )
32  {
33  if( m_connection )
34  m_connection->registerConnectionDataHandler( this );
35  }
36 
38  {
39  delete m_connection;
40  delete m_tls;
41  }
42 
44  {
45  if( m_connection )
46  m_connection->registerConnectionDataHandler( 0 );
47 
48  m_connection = connection;
49 
50  if( m_connection )
51  m_connection->registerConnectionDataHandler( this );
52  }
53 
55  {
56  if( !m_connection )
57  return ConnNotConnected;
58 
59  if( m_state == StateConnected )
60  return ConnNoError;
61 
62  if( !m_tls )
63  m_tls = getTLSBase( this, m_connection->server() );
64 
65  if( !m_tls )
66  return ConnTlsNotAvailable;
67 
68  if( !m_tls->init( m_clientKey, m_clientCerts, m_cacerts ) )
69  return ConnTlsFailed;
70 
71 // m_tls->setCACerts( m_cacerts );
72 // m_tls->setClientCert( m_clientKey, m_clientCerts );
73 
75 
76  if( m_connection->state() != StateConnected )
77  return m_connection->connect();
78 
79  if( m_tls->handshake() )
80  return ConnNoError;
81  else
82  return ConnTlsFailed;
83  }
84 
86  {
87  if( m_connection->state() == StateConnected )
88  {
89  return m_connection->recv( timeout );
90  }
91  else
92  {
94  "Attempt to receive data on a connection that is not connected (or is connecting)" );
95  return ConnNotConnected;
96  }
97  }
98 
99  bool ConnectionTLS::send( const std::string& data )
100  {
101  if( m_state != StateConnected )
102  return false;
103 
104  m_tls->encrypt( data );
105  return true;
106  }
107 
109  {
110  if( m_connection )
111  return m_connection->receive();
112  else
113  return ConnNotConnected;
114  }
115 
117  {
118  if( m_connection )
119  m_connection->disconnect();
120 
121  cleanup();
122  }
123 
125  {
126  if( m_connection )
127  m_connection->cleanup();
128  if( m_tls )
129  m_tls->cleanup();
130 
132  }
133 
134  void ConnectionTLS::getStatistics( long int& totalIn, long int& totalOut )
135  {
136  if( m_connection )
137  m_connection->getStatistics( totalIn, totalOut );
138  }
139 
141  {
142  ConnectionBase* newConn = 0;
143  if( m_connection )
144  newConn = m_connection->newInstance();
145  return new ConnectionTLS( m_handler, newConn, m_log );
146  }
147 
148  void ConnectionTLS::handleReceivedData( const ConnectionBase* /*connection*/, const std::string& data )
149  {
150  if( m_tls )
151  m_tls->decrypt( data );
152  }
153 
154  void ConnectionTLS::handleConnect( const ConnectionBase* /*connection*/ )
155  {
156  if( m_tls )
157  m_tls->handshake();
158  }
159 
160  void ConnectionTLS::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError reason )
161  {
162  if( m_handler )
163  m_handler->handleDisconnect( this, reason );
164 
165  cleanup();
166  }
167 
168  void ConnectionTLS::handleEncryptedData( const TLSBase* /*tls*/, const std::string& data )
169  {
170  if( m_connection )
171  m_connection->send( data );
172  }
173 
174  void ConnectionTLS::handleDecryptedData( const TLSBase* /*tls*/, const std::string& data )
175  {
176  if( m_handler )
177  m_handler->handleReceivedData( this, data );
178  else
179  {
180  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "Data received and decrypted but no handler" );
181  }
182  }
183 
184  void ConnectionTLS::handleHandshakeResult( const TLSBase* tls, bool success, CertInfo& certinfo )
185  {
186  if( success )
187  {
189  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "TLS handshake succeeded" );
190  if( m_tlsHandler )
191  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
192  if( m_handler )
193  m_handler->handleConnect( this );
194  }
195  else
196  {
198  m_log.log( LogLevelWarning, LogAreaClassConnectionTLS, "TLS handshake failed" );
199  if( m_tlsHandler )
200  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
201  }
202  }
203 
204 }