]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/netcore/Thrift/Transports/Client/TTlsSocketClientTransport.cs
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / netcore / Thrift / Transports / Client / TTlsSocketClientTransport.cs
1 // Licensed to the Apache Software Foundation(ASF) under one
2 // or more contributor license agreements.See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17
18 using System;
19 using System.Net;
20 using System.Net.Security;
21 using System.Net.Sockets;
22 using System.Security.Authentication;
23 using System.Security.Cryptography.X509Certificates;
24 using System.Threading;
25 using System.Threading.Tasks;
26
27 namespace Thrift.Transports.Client
28 {
29 //TODO: check for correct work
30
31 // ReSharper disable once InconsistentNaming
32 public class TTlsSocketClientTransport : TStreamClientTransport
33 {
34 private readonly X509Certificate2 _certificate;
35 private readonly RemoteCertificateValidationCallback _certValidator;
36 private readonly IPAddress _host;
37 private readonly bool _isServer;
38 private readonly LocalCertificateSelectionCallback _localCertificateSelectionCallback;
39 private readonly int _port;
40 private readonly SslProtocols _sslProtocols;
41 private TcpClient _client;
42 private SslStream _secureStream;
43 private int _timeout;
44
45 public TTlsSocketClientTransport(TcpClient client, X509Certificate2 certificate, bool isServer = false,
46 RemoteCertificateValidationCallback certValidator = null,
47 LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
48 SslProtocols sslProtocols = SslProtocols.Tls12)
49 {
50 _client = client;
51 _certificate = certificate;
52 _certValidator = certValidator;
53 _localCertificateSelectionCallback = localCertificateSelectionCallback;
54 _sslProtocols = sslProtocols;
55 _isServer = isServer;
56
57 if (isServer && certificate == null)
58 {
59 throw new ArgumentException("TTlsSocketClientTransport needs certificate to be used for server",
60 nameof(certificate));
61 }
62
63 if (IsOpen)
64 {
65 InputStream = client.GetStream();
66 OutputStream = client.GetStream();
67 }
68 }
69
70 public TTlsSocketClientTransport(IPAddress host, int port, string certificatePath,
71 RemoteCertificateValidationCallback certValidator = null,
72 LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
73 SslProtocols sslProtocols = SslProtocols.Tls12)
74 : this(host, port, 0,
75 new X509Certificate2(certificatePath),
76 certValidator,
77 localCertificateSelectionCallback,
78 sslProtocols)
79 {
80 }
81
82 public TTlsSocketClientTransport(IPAddress host, int port,
83 X509Certificate2 certificate = null,
84 RemoteCertificateValidationCallback certValidator = null,
85 LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
86 SslProtocols sslProtocols = SslProtocols.Tls12)
87 : this(host, port, 0,
88 certificate,
89 certValidator,
90 localCertificateSelectionCallback,
91 sslProtocols)
92 {
93 }
94
95 public TTlsSocketClientTransport(IPAddress host, int port, int timeout,
96 X509Certificate2 certificate,
97 RemoteCertificateValidationCallback certValidator = null,
98 LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
99 SslProtocols sslProtocols = SslProtocols.Tls12)
100 {
101 _host = host;
102 _port = port;
103 _timeout = timeout;
104 _certificate = certificate;
105 _certValidator = certValidator;
106 _localCertificateSelectionCallback = localCertificateSelectionCallback;
107 _sslProtocols = sslProtocols;
108
109 InitSocket();
110 }
111
112 public int Timeout
113 {
114 set { _client.ReceiveTimeout = _client.SendTimeout = _timeout = value; }
115 }
116
117 public TcpClient TcpClient => _client;
118
119 public IPAddress Host => _host;
120
121 public int Port => _port;
122
123 public override bool IsOpen
124 {
125 get
126 {
127 if (_client == null)
128 {
129 return false;
130 }
131
132 return _client.Connected;
133 }
134 }
135
136 private void InitSocket()
137 {
138 _client = new TcpClient();
139 _client.ReceiveTimeout = _client.SendTimeout = _timeout;
140 _client.Client.NoDelay = true;
141 }
142
143 private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain,
144 SslPolicyErrors sslValidationErrors)
145 {
146 return sslValidationErrors == SslPolicyErrors.None;
147 }
148
149 public override async Task OpenAsync(CancellationToken cancellationToken)
150 {
151 if (IsOpen)
152 {
153 throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
154 }
155
156 if (_host == null)
157 {
158 throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
159 }
160
161 if (_port <= 0)
162 {
163 throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
164 }
165
166 if (_client == null)
167 {
168 InitSocket();
169 }
170
171 if (_client != null)
172 {
173 await _client.ConnectAsync(_host, _port);
174 await SetupTlsAsync();
175 }
176 }
177
178 public async Task SetupTlsAsync()
179 {
180 var validator = _certValidator ?? DefaultCertificateValidator;
181
182 if (_localCertificateSelectionCallback != null)
183 {
184 _secureStream = new SslStream(_client.GetStream(), false, validator, _localCertificateSelectionCallback);
185 }
186 else
187 {
188 _secureStream = new SslStream(_client.GetStream(), false, validator);
189 }
190
191 try
192 {
193 if (_isServer)
194 {
195 // Server authentication
196 await
197 _secureStream.AuthenticateAsServerAsync(_certificate, _certValidator != null, _sslProtocols,
198 true);
199 }
200 else
201 {
202 // Client authentication
203 var certs = _certificate != null
204 ? new X509CertificateCollection {_certificate}
205 : new X509CertificateCollection();
206
207 var targetHost = _host.ToString();
208 await _secureStream.AuthenticateAsClientAsync(targetHost, certs, _sslProtocols, true);
209 }
210 }
211 catch (Exception)
212 {
213 Close();
214 throw;
215 }
216
217 InputStream = _secureStream;
218 OutputStream = _secureStream;
219 }
220
221 public override void Close()
222 {
223 base.Close();
224 if (_client != null)
225 {
226 _client.Dispose();
227 _client = null;
228 }
229
230 if (_secureStream != null)
231 {
232 _secureStream.Dispose();
233 _secureStream = null;
234 }
235 }
236 }
237 }