gloox  1.1-svn
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  m_tls->setSubject( m_subject );
69 
70  if( !m_tls->init( m_clientKey, m_clientCerts, m_cacerts ) )
71  return ConnTlsFailed;
72 
74 
75  if( m_connection->state() != StateConnected )
76  return m_connection->connect();
77 
78  if( m_tls->handshake() )
79  return ConnNoError;
80  else
81  return ConnTlsFailed;
82  }
83 
85  {
86  if( m_connection->state() == StateConnected )
87  {
88  return m_connection->recv( timeout );
89  }
90  else
91  {
93  "Attempt to receive data on a connection that is not connected (or is connecting)" );
94  return ConnNotConnected;
95  }
96  }
97 
98  bool ConnectionTLS::send( const std::string& data )
99  {
100  if( m_state != StateConnected )
101  return false;
102 
103  m_tls->encrypt( data );
104  return true;
105  }
106 
108  {
109  if( m_connection )
110  return m_connection->receive();
111  else
112  return ConnNotConnected;
113  }
114 
116  {
117  if( m_connection )
118  m_connection->disconnect();
119 
120  cleanup();
121  }
122 
124  {
125  if( m_connection )
126  m_connection->cleanup();
127  if( m_tls )
128  m_tls->cleanup();
129 
131  }
132 
133  void ConnectionTLS::getStatistics( long int& totalIn, long int& totalOut )
134  {
135  if( m_connection )
136  m_connection->getStatistics( totalIn, totalOut );
137  }
138 
140  {
141  ConnectionBase* newConn = 0;
142  if( m_connection )
143  newConn = m_connection->newInstance();
144  return new ConnectionTLS( m_handler, newConn, m_log );
145  }
146 
147  void ConnectionTLS::handleReceivedData( const ConnectionBase* /*connection*/, const std::string& data )
148  {
149  if( m_tls )
150  m_tls->decrypt( data );
151  }
152 
153  void ConnectionTLS::handleConnect( const ConnectionBase* /*connection*/ )
154  {
155  if( m_tls )
156  m_tls->handshake();
157  }
158 
159  void ConnectionTLS::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError reason )
160  {
161  if( m_handler )
162  m_handler->handleDisconnect( this, reason );
163 
164  cleanup();
165  }
166 
167  void ConnectionTLS::handleEncryptedData( const TLSBase* /*tls*/, const std::string& data )
168  {
169  if( m_connection )
170  m_connection->send( data );
171  }
172 
173  void ConnectionTLS::handleDecryptedData( const TLSBase* /*tls*/, const std::string& data )
174  {
175  if( m_handler )
176  m_handler->handleReceivedData( this, data );
177  else
178  {
179  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "Data received and decrypted but no handler" );
180  }
181  }
182 
183  void ConnectionTLS::handleHandshakeResult( const TLSBase* tls, bool success, CertInfo& certinfo )
184  {
185  if( success )
186  {
188  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "TLS handshake succeeded" );
189  if( m_tlsHandler )
190  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
191  if( m_handler )
192  m_handler->handleConnect( this );
193  }
194  else
195  {
197  m_log.log( LogLevelWarning, LogAreaClassConnectionTLS, "TLS handshake failed" );
198  if( m_tlsHandler )
199  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
200  }
201  }
202 
203 }