Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TSSLSocket.cxx
Go to the documentation of this file.
1// @(#)root/net:$Id: TSSLSocket.cxx
2// Author: Alejandro Alvarez 16/09/2011
3
4/*************************************************************************
5 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**
13\file TSSLSocket.cxx
14\class TSSLSocket
15\brief A TSocket wrapped in by SSL.
16\note This class deals with sockets: the user is entirely responsible for the security of their usage, for example, but
17not limited to, the management of the connections to said sockets.
18**/
19
20
21#include <openssl/ssl.h>
22#include "TSSLSocket.h"
23#include "TSystem.h"
24#include <iostream>
25#include <cstdio>
26#include "strlcpy.h"
27
28// Static properties
33
34////////////////////////////////////////////////////////////////////////////////
35// SSL debugging
36
37static void ssl_info_callback(const SSL *ssl, int where, int ret)
38{
39 if (ret == 0) {
40 std::cout << "-- ssl_info_callback: error occurred.\n";
41 return;
42 }
43 if (where) {
44 std::cout << " - " << SSL_state_string_long(ssl);
45 std::cout << " - " << SSL_state_string(ssl);
46 std::cout << std::endl;
47 }
48}
49
50////////////////////////////////////////////////////////////////////////////////
51/// Wraps the socket with OpenSSL.
52
54{
56
57 // New context
58 if (!(fSSLCtx = SSL_CTX_new(SSLv23_method()))) {
59 Error("WrapWithSSL", "the context could not be created");
60 goto wrapFailed;
61 }
62
64 Error("WrapWithSSL", "could not set the CA file and/or the CA path");
65 goto wrapFailed;
66 }
67
69 Error("WrapWithSSL", "could not set the client certificate");
70 goto wrapFailed;
71 }
72
74 Error("WrapWithSSL", "could not set the client private key");
75 goto wrapFailed;
76 }
77
78 // New SSL structure
79 if (!(fSSL = SSL_new(fSSLCtx))) {
80 Error("WrapWithSSL", "cannot create the ssl struct");
81 goto wrapFailed;
82 }
83
84 if (gDebug > 0)
86
87 // Bind to the socket
88 if (SSL_set_fd(fSSL, fSocket) != 1) {
89 Error("WrapWithSSL", "cannot bind to the socket %d", fSocket);
90 goto wrapFailed;
91 }
92
93 // Open connection
94 if (SSL_connect(fSSL) != 1) {
95 Error("WrapWithSSL", "cannot connect");
96 goto wrapFailed;
97 }
98
99 return;
100
102 Close();
103 return;
104}
105
106////////////////////////////////////////////////////////////////////////////////
107
108
109////////////////////////////////////////////////////////////////////////////////
110
116
117////////////////////////////////////////////////////////////////////////////////
118
124
125////////////////////////////////////////////////////////////////////////////////
126
132
133////////////////////////////////////////////////////////////////////////////////
134
140
141////////////////////////////////////////////////////////////////////////////////
142
147
148////////////////////////////////////////////////////////////////////////////////
149
154
155////////////////////////////////////////////////////////////////////////////////
156
161
162////////////////////////////////////////////////////////////////////////////////
163
168
169////////////////////////////////////////////////////////////////////////////////
170/// Close gracefully the connection, and free SSL structures.
171
173{
174 Close();
175 if (fSSL)
176 SSL_free(fSSL);
177 if (fSSLCtx)
178 SSL_CTX_free(fSSLCtx);
179}
180
181////////////////////////////////////////////////////////////////////////////////
182/// Close the SSL connection.
183
185{
186 if (fSSL)
187 SSL_shutdown(fSSL);
189}
190
191////////////////////////////////////////////////////////////////////////////////
192/// Set up the static configuration variables.
193
194void ROOT::Deprecated::TSSLSocket::SetUpSSL(const char *cafile, const char *capath, const char *ucert, const char *ukey)
195{
196 if (cafile)
197 strlcpy(fgSSLCAFile, cafile, FILENAME_MAX);
198 if (capath)
199 strlcpy(fgSSLCAPath, capath, FILENAME_MAX);
200 if (ucert)
201 strlcpy(fgSSLUCert, ucert, FILENAME_MAX);
202 if (ukey)
203 strlcpy(fgSSLUKey, ukey, FILENAME_MAX);
204}
205
206////////////////////////////////////////////////////////////////////////////////
207
209{
210 Error("Recv", "not implemented");
211 return -1;
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// Receive a raw buffer of specified length bytes.
216
218{
220
221 if (fSocket == -1) return -1;
222 if (length == 0) return 0;
223
224 ResetBit(TSocket::kBrokenConn);
225
226 Int_t n;
227 Int_t offset = 0;
229
230 // SSL_read/SSL_peek may not return the total length at once
231 while (remain > 0) {
232 if (opt == kPeek)
233 n = SSL_peek(fSSL, (char*)buffer + offset, (int)remain);
234 else
235 n = SSL_read(fSSL, (char*)buffer + offset, (int)remain);
236
237 if (n <= 0) {
238 if (gDebug > 0)
239 Error("RecvRaw", "failed to read from the socket");
240
242 // Connection closed, reset or broken
243 SetBit(TSocket::kBrokenConn);
244 SSL_set_quiet_shutdown(fSSL, 1); // Socket is gone, sending "close notify" will fail
245 Close();
246 }
247 return n;
248 }
249
250 // When peeking, just return the available data, don't loop. Otherwise,
251 // we may copy the same chunk of data multiple times into the
252 // output buffer, for instance when there is no more recent data
253 // in the socket's internal reception buffers.
254 // Note that in this case we don't update the counters of data received
255 // through this socket. They will be updated when the data is actually
256 // read. This avoids double counting.
257 if (opt == kPeek) return n;
258
259 offset += n;
260 remain -= n;
261 }
262
263 fBytesRecv += length;
264 fgBytesRecv += length;
265
266 Touch(); // update usage timestamp
267
268 return offset;
269}
270
271////////////////////////////////////////////////////////////////////////////////
272
274{
275 Error("Send", "not implemented");
276 return -1;
277}
278
279////////////////////////////////////////////////////////////////////////////////
280/// Send a raw buffer of specified length.
281
283{
285
286 if (fSocket == -1) return -1;
287
288 ResetBit(TSocket::kBrokenConn);
289
290 Int_t nsent;
291 if ((nsent = SSL_write(fSSL, buffer, (int)length)) <= 0) {
293 // Connection reset or broken: close
294 SetBit(TSocket::kBrokenConn);
295 Close();
296 }
297 return nsent;
298 }
299
300 fBytesSent += nsent;
301 fgBytesSent += nsent;
302
303 Touch(); // update usage timestamp
304
305 return nsent;
306}
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:777
static void ssl_info_callback(const SSL *ssl, int where, int ret)
ESendRecvOptions
Definition TSystem.h:242
@ kPeek
Definition TSystem.h:245
static void ssl_info_callback(const SSL *ssl, int what, int ret)
Definition civetweb.c:17485
Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault) override
Send a raw buffer of specified length.
Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault) override
Receive a raw buffer of specified length bytes.
void Close(Option_t *option="") override
Close the SSL connection.
Int_t Recv(TMessage *&mess) override
Receive a TMessage object.
void WrapWithSSL()
Wraps the socket with OpenSSL.
virtual ~TSSLSocket()
Close gracefully the connection, and free SSL structures.
Int_t Send(const TMessage &mess) override
Send a TMessage object.
static void SetUpSSL(const char *cafile, const char *capath, const char *ucert, const char *ukey)
Set up the static configuration variables.
This class represents an Internet Protocol (IP) address.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
This class implements client sockets.
Definition TSocket.h:39
Int_t fSocket
Definition TSocket.h:71
@ kBrokenConn
Definition TSocket.h:45
virtual void Close(Option_t *opt="")
Close the socket.
Definition TSocket.cxx:378
static void ResetErrno()
Static function resetting system error number.
Definition TSystem.cxx:286
const Int_t n
Definition legend1.C:16
#define SSL_ERROR_SYSCALL
struct ssl_st SSL
#define SSL_ERROR_ZERO_RETURN