2
2
extern crate log;
3
3
4
4
use serde:: { Deserialize , Serialize } ;
5
- use std:: { net:: SocketAddr , sync:: Arc } ;
6
5
use std:: time:: Duration ;
7
6
use std:: { io, thread} ;
7
+ use std:: { net:: SocketAddr , sync:: Arc } ;
8
8
9
9
use mqttbytes:: v4:: Packet ;
10
10
use rumqttlog:: * ;
@@ -15,12 +15,25 @@ use crate::remotelink::RemoteLink;
15
15
use tokio:: io:: { AsyncRead , AsyncWrite } ;
16
16
use tokio:: net:: TcpListener ;
17
17
use tokio:: { task, time} ;
18
+
19
+ // All requirements for `rustls`
20
+ #[ cfg( feature = "use-rustls" ) ]
18
21
use tokio_rustls:: rustls:: internal:: pemfile:: { certs, rsa_private_keys} ;
22
+ #[ cfg( feature = "use-rustls" ) ]
19
23
use tokio_rustls:: rustls:: {
20
24
AllowAnyAuthenticatedClient , NoClientAuth , RootCertStore , ServerConfig , TLSError ,
21
25
} ;
26
+ #[ cfg( feature = "use-rustls" ) ]
22
27
use tokio_rustls:: TlsAcceptor ;
23
28
29
+ // All requirements for `native-tls`
30
+ #[ cfg( feature = "use-native-tls" ) ]
31
+ use std:: io:: Read ;
32
+ #[ cfg( feature = "use-native-tls" ) ]
33
+ use tokio_native_tls:: native_tls:: Error as TLSError ;
34
+ #[ cfg( feature = "use-native-tls" ) ]
35
+ use tokio_native_tls:: { native_tls, TlsAcceptor } ;
36
+
24
37
pub mod async_locallink;
25
38
mod consolelink;
26
39
mod locallink;
@@ -31,9 +44,11 @@ mod state;
31
44
use crate :: consolelink:: ConsoleLink ;
32
45
pub use crate :: locallink:: { LinkError , LinkRx , LinkTx } ;
33
46
use crate :: network:: Network ;
47
+ #[ cfg( feature = "use-rustls" ) ]
34
48
use crate :: Error :: ServerKeyNotFound ;
35
49
use std:: collections:: HashMap ;
36
50
use std:: fs:: File ;
51
+ #[ cfg( feature = "use-rustls" ) ]
37
52
use std:: io:: BufReader ;
38
53
39
54
#[ derive( Debug , thiserror:: Error ) ]
@@ -87,6 +102,10 @@ pub struct Config {
87
102
#[ derive( Debug , Serialize , Deserialize , Clone ) ]
88
103
pub struct ServerSettings {
89
104
pub listen : SocketAddr ,
105
+ /// Used only for native-tls implementation
106
+ pub pkcs12_path : Option < String > ,
107
+ /// Used only for native-tls implementation
108
+ pub pkcs12_pass : Option < String > ,
90
109
pub ca_path : Option < String > ,
91
110
pub cert_path : Option < String > ,
92
111
pub key_path : Option < String > ,
@@ -215,6 +234,40 @@ impl Server {
215
234
}
216
235
}
217
236
237
+ #[ cfg( feature = "use-native-tls" ) ]
238
+ fn tls ( & self ) -> Result < Option < TlsAcceptor > , Error > {
239
+ match (
240
+ self . config . pkcs12_path . clone ( ) ,
241
+ self . config . pkcs12_pass . clone ( ) ,
242
+ ) {
243
+ ( Some ( cert) , Some ( password) ) => {
244
+ // Get certificates
245
+ let cert_file = File :: open ( & cert) ;
246
+ let mut cert_file =
247
+ cert_file. map_err ( |_| Error :: ServerCertNotFound ( cert. clone ( ) ) ) ?;
248
+
249
+ // Read cert into memory
250
+ let mut buf = Vec :: new ( ) ;
251
+ cert_file
252
+ . read_to_end ( & mut buf)
253
+ . map_err ( |_| Error :: InvalidServerCert ( cert. clone ( ) ) ) ?;
254
+
255
+ // Get the identity
256
+ let identity = native_tls:: Identity :: from_pkcs12 ( & buf, & password)
257
+ . map_err ( |_| Error :: InvalidServerCert ( cert. clone ( ) ) ) ?;
258
+
259
+ // Builder
260
+ let builder = native_tls:: TlsAcceptor :: builder ( identity) . build ( ) ?;
261
+
262
+ // Create acceptor
263
+ let acceptor = TlsAcceptor :: from ( builder) ;
264
+ Ok ( Some ( acceptor) )
265
+ }
266
+ _ => Ok ( None ) ,
267
+ }
268
+ }
269
+
270
+ #[ cfg( feature = "use-rustls" ) ]
218
271
fn tls ( & self ) -> Result < Option < TlsAcceptor > , Error > {
219
272
let ( certs, key) = match self . config . cert_path . clone ( ) {
220
273
Some ( cert) => {
@@ -271,13 +324,35 @@ impl Server {
271
324
let acceptor = self . tls ( ) ?;
272
325
let max_incoming_size = config. max_payload_size ;
273
326
274
- info ! ( "Waiting for connections on {}. Server = {}" , self . config. listen, self . id) ;
327
+ info ! (
328
+ "Waiting for connections on {}. Server = {}" ,
329
+ self . config. listen, self . id
330
+ ) ;
275
331
loop {
276
- let ( stream, addr) = listener. accept ( ) . await ?;
332
+ // Await new network connection.
333
+ let ( stream, addr) = match listener. accept ( ) . await {
334
+ Ok ( ( s, r) ) => ( s, r) ,
335
+ Err ( _e) => {
336
+ error ! ( "Unable to accept socket." ) ;
337
+ continue ;
338
+ }
339
+ } ;
340
+
341
+ // Depending on TLS or not create a new Network
277
342
let network = match & acceptor {
278
343
Some ( acceptor) => {
279
344
info ! ( "{}. Accepting TLS connection from: {}" , count, addr) ;
280
- Network :: new ( acceptor. accept ( stream) . await ?, max_incoming_size)
345
+ let sock = match acceptor. accept ( stream) . await {
346
+ Ok ( s) => s,
347
+ Err ( _e) => {
348
+ error ! (
349
+ "{} Unable to accept incoming TLS connection from {}" ,
350
+ count, addr
351
+ ) ;
352
+ continue ;
353
+ }
354
+ } ;
355
+ Network :: new ( sock, max_incoming_size)
281
356
}
282
357
None => {
283
358
info ! ( "{}. Accepting TCP connection from: {}" , count, addr) ;
@@ -289,6 +364,8 @@ impl Server {
289
364
290
365
let config = config. clone ( ) ;
291
366
let router_tx = self . router_tx . clone ( ) ;
367
+
368
+ // Spawn a new thread to handle this connection.
292
369
task:: spawn ( async {
293
370
let connector = Connector :: new ( config, router_tx) ;
294
371
if let Err ( e) = connector. new_connection ( network) . await {
0 commit comments