gloox  1.0.28
connectiontls.cpp
1 /*
2  * Copyright (c) 2007-2023 by Jakob Schröter <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  {
49  m_connection->registerConnectionDataHandler( 0 );
50  delete m_connection;
51  }
52 
53  m_connection = connection;
54 
55  if( m_connection )
56  m_connection->registerConnectionDataHandler( this );
57  }
58 
60  {
61  if( !m_connection )
62  return ConnNotConnected;
63 
64  if( m_state == StateConnected )
65  return ConnNoError;
66 
67  if( !m_tls )
68  m_tls = getTLSBase( this, m_connection->server() );
69 
70  if( !m_tls )
71  return ConnTlsNotAvailable;
72 
73  if( !m_tls->init( m_clientKey, m_clientCerts, m_cacerts ) )
74  return ConnTlsFailed;
75 
76 // m_tls->setCACerts( m_cacerts );
77 // m_tls->setClientCert( m_clientKey, m_clientCerts );
78 
80 
81  if( m_connection->state() != StateConnected )
82  return m_connection->connect();
83 
84  if( m_tls->handshake() )
85  return ConnNoError;
86  else
87  return ConnTlsFailed;
88  }
89 
91  {
92  return m_connection ? m_connection->recv( timeout ) : ConnNotConnected;
93  }
94 
95  bool ConnectionTLS::send( const std::string& data )
96  {
97  if( m_state != StateConnected )
98  return false;
99 
100  m_tls->encrypt( data );
101  return true;
102  }
103 
105  {
106  if( m_connection )
107  return m_connection->receive();
108  else
109  return ConnNotConnected;
110  }
111 
113  {
114  if( m_connection )
115  m_connection->disconnect();
116 
117  cleanup();
118  }
119 
121  {
122  if( m_connection )
123  m_connection->cleanup();
124  if( m_tls )
125  m_tls->cleanup();
126 
128  }
129 
130  void ConnectionTLS::getStatistics( long int& totalIn, long int& totalOut )
131  {
132  if( m_connection )
133  m_connection->getStatistics( totalIn, totalOut );
134  }
135 
137  {
138  ConnectionBase* newConn = 0;
139  if( m_connection )
140  newConn = m_connection->newInstance();
141  return new ConnectionTLS( m_handler, newConn, m_log );
142  }
143 
144  void ConnectionTLS::handleReceivedData( const ConnectionBase* /*connection*/, const std::string& data )
145  {
146  if( m_tls )
147  m_tls->decrypt( data );
148  }
149 
150  void ConnectionTLS::handleConnect( const ConnectionBase* /*connection*/ )
151  {
152  if( m_tls )
153  m_tls->handshake();
154  }
155 
156  void ConnectionTLS::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError reason )
157  {
158  if( m_handler )
159  m_handler->handleDisconnect( this, reason );
160 
161  cleanup();
162  }
163 
164  void ConnectionTLS::handleEncryptedData( const TLSBase* /*tls*/, const std::string& data )
165  {
166  if( m_connection )
167  m_connection->send( data );
168  }
169 
170  void ConnectionTLS::handleDecryptedData( const TLSBase* /*tls*/, const std::string& data )
171  {
172  if( m_handler )
173  m_handler->handleReceivedData( this, data );
174  else
175  {
176  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "Data received and decrypted but no handler" );
177  }
178  }
179 
180  void ConnectionTLS::handleHandshakeResult( const TLSBase* tls, bool success, CertInfo& certinfo )
181  {
182  if( success )
183  {
185  m_log.log( LogLevelDebug, LogAreaClassConnectionTLS, "TLS handshake succeeded" );
186  if( m_tlsHandler )
187  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
188  if( m_handler )
189  m_handler->handleConnect( this );
190  }
191  else
192  {
194  m_log.log( LogLevelWarning, LogAreaClassConnectionTLS, "TLS handshake failed" );
195  if( m_tlsHandler )
196  m_tlsHandler->handleHandshakeResult( tls, success, certinfo );
197  cleanup();
198  if( m_handler )
200  }
201  }
202 
203 }
An abstract base class for a connection.
virtual void cleanup()
const std::string & server() const
ConnectionState m_state
ConnectionState state() const
virtual ConnectionError recv(int timeout=-1)=0
virtual bool send(const std::string &data)=0
ConnectionDataHandler * m_handler
virtual ConnectionError connect()=0
virtual ConnectionError receive()=0
virtual void getStatistics(long int &totalIn, long int &totalOut)=0
virtual void disconnect()=0
virtual ConnectionBase * newInstance() const =0
void registerConnectionDataHandler(ConnectionDataHandler *cdh)
This is an abstract base class to receive events from a ConnectionBase-derived object.
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)=0
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)=0
virtual void handleConnect(const ConnectionBase *connection)=0
virtual void handleEncryptedData(const TLSBase *, const std::string &data)
ConnectionTLS(ConnectionDataHandler *cdh, ConnectionBase *conn, const LogSink &log)
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)
virtual ConnectionError recv(int timeout=-1)
virtual void cleanup()
virtual void handleConnect(const ConnectionBase *connection)
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)
virtual void disconnect()
virtual void handleDecryptedData(const TLSBase *, const std::string &data)
virtual ConnectionBase * newInstance() const
virtual ConnectionError connect()
virtual TLSBase * getTLSBase(TLSHandler *th, const std::string server)
void setConnectionImpl(ConnectionBase *connection)
virtual void handleHandshakeResult(const TLSBase *base, bool success, CertInfo &certinfo)
virtual bool send(const std::string &data)
virtual ConnectionError receive()
virtual void getStatistics(long int &totalIn, long int &totalOut)
An implementation of log sink and source.
Definition: logsink.h:39
void log(LogLevel level, LogArea area, const std::string &message) const
Definition: logsink.cpp:28
An abstract base class for TLS implementations.
Definition: tlsbase.h:32
virtual bool encrypt(const std::string &data)=0
virtual int decrypt(const std::string &data)=0
virtual bool init(const std::string &clientKey=EmptyString, const std::string &clientCerts=EmptyString, const StringList &cacerts=StringList())=0
virtual bool handshake()=0
virtual void cleanup()=0
virtual void handleHandshakeResult(const TLSBase *base, bool success, CertInfo &certinfo)=0
The namespace for the gloox library.
Definition: adhoc.cpp:28
ConnectionError
Definition: gloox.h:684
@ ConnNotConnected
Definition: gloox.h:715
@ ConnTlsFailed
Definition: gloox.h:705
@ ConnNoError
Definition: gloox.h:685
@ ConnTlsNotAvailable
Definition: gloox.h:707
@ LogAreaClassConnectionTLS
Definition: gloox.h:1067
@ LogLevelWarning
Definition: gloox.h:1082
@ LogLevelDebug
Definition: gloox.h:1081
@ StateDisconnected
Definition: gloox.h:642
@ StateConnected
Definition: gloox.h:644
@ StateConnecting
Definition: gloox.h:643