gloox  1.0.9
connectiontls.cpp
1 /*
2  * Copyright (c) 2007-2013 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 #include <cstdio>
18 
19 namespace gloox
20 {
21 
23  : ConnectionBase( cdh ),
24  m_connection( conn ), m_tls( 0 ), m_tlsHandler( 0 ),
25  m_log( log )
26  {
27  if( m_connection )
28  m_connection->registerConnectionDataHandler( this );
29  }
30 
32  : ConnectionBase( 0 ),
33  m_connection( conn ), m_tls( 0 ), m_tlsHandler( 0 ), m_log( log )
34  {
35  if( m_connection )
36  m_connection->registerConnectionDataHandler( this );
37  }
38 
40  {
41  delete m_connection;
42  delete m_tls;
43  }
44 
46  {
47  if( m_connection )
48  m_connection->registerConnectionDataHandler( 0 );
49 
50  m_connection = connection;
51 
52  if( m_connection )
53  m_connection->registerConnectionDataHandler( this );
54  }
55 
57  {
58  if( !m_connection )
59  return ConnNotConnected;
60 
61  if( m_state == StateConnected )
62  return ConnNoError;
63 
64  if( !m_tls )
65  m_tls = getTLSBase( this, m_connection->server() );
66 
67  if( !m_tls )
68  return ConnTlsNotAvailable;
69 
70  if( !m_tls->init( m_clientKey, m_clientCerts, m_cacerts ) )
71  return ConnTlsFailed;
72 
73 // m_tls->setCACerts( m_cacerts );
74 // m_tls->setClientCert( m_clientKey, m_clientCerts );
75 
77 
78  if( m_connection->state() != StateConnected )
79  return m_connection->connect();
80 
81  if( m_tls->handshake() )
82  return ConnNoError;
83  else
84  return ConnTlsFailed;
85  }
86 
88  {
89  return m_connection ? m_connection->recv( timeout ) : ConnNotConnected;
90  }
91 
92  bool ConnectionTLS::send( const std::string& data )
93  {
94  if( m_state != StateConnected )
95  return false;
96 
97  m_tls->encrypt( data );
98  return true;
99  }
100 
102  {
103  if( m_connection )
104  return m_connection->receive();
105  else
106  return ConnNotConnected;
107  }
108 
110  {
111  if( m_connection )
112  m_connection->disconnect();
113 
114  cleanup();
115  }
116 
118  {
119  if( m_connection )
120  m_connection->cleanup();
121  if( m_tls )
122  m_tls->cleanup();
123 
125  }
126 
127  void ConnectionTLS::getStatistics( long int& totalIn, long int& totalOut )
128  {
129  if( m_connection )
130  m_connection->getStatistics( totalIn, totalOut );
131  }
132 
134  {
135  ConnectionBase* newConn = 0;
136  if( m_connection )
137  newConn = m_connection->newInstance();
138  return new ConnectionTLS( m_handler, newConn, m_log );
139  }
140 
141  void ConnectionTLS::handleReceivedData( const ConnectionBase* /*connection*/, const std::string& data )
142  {
143  if( m_tls )
144  m_tls->decrypt( data );
145  }
146 
147  void ConnectionTLS::handleConnect( const ConnectionBase* /*connection*/ )
148  {
149  if( m_tls )
150  m_tls->handshake();
151  }
152 
153  void ConnectionTLS::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError reason )
154  {
155  if( m_handler )
156  m_handler->handleDisconnect( this, reason );
157 
158  cleanup();
159  }
160 
161  void ConnectionTLS::handleEncryptedData( const TLSBase* /*tls*/, const std::string& data )
162  {
163  if( m_connection )
164  m_connection->send( data );
165  }
166 
167  void ConnectionTLS::handleDecryptedData( const TLSBase* /*tls*/, const std::string& data )
168  {
169  if( m_handler )
170  m_handler->handleReceivedData( this, data );
171  else
172  {
173  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "Data received and decrypted but no handler" );
174  }
175  }
176 
177  void ConnectionTLS::handleHandshakeResult( const TLSBase* tls, bool success, CertInfo& certinfo )
178  {
179  if( success )
180  {
182  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "TLS handshake succeeded" );
183  if( m_tlsHandler )
184  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
185  if( m_handler )
186  m_handler->handleConnect( this );
187  }
188  else
189  {
191  m_log.log( LogLevelWarning, LogAreaClassConnectionTLS, "TLS handshake failed" );
192  if( m_tlsHandler )
193  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
194  cleanup();
195  if( m_handler )
197  }
198  }
199 
200 }