1 use crate::flowgger::config::Config;
2 use openssl::bn::BigNum;
3 use openssl::dh::Dh;
4 use openssl::ssl::*;
5 use std::path::{Path, PathBuf};
6
7 pub mod tls_input;
8 #[cfg(feature = "coroutines")]
9 pub mod tlsco_input;
10
11 pub use super::Input;
12
13 const DEFAULT_CERT: &str = "flowgger.pem";
14 const DEFAULT_CIPHERS: &str =
15 "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:\
16 ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:\
17 ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:\
18 ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:\
19 ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:\
20 AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:\
21 ECDHE-RSA-DES-CBC3-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:\
22 !EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
23 const DEFAULT_COMPRESSION: bool = false;
24 const DEFAULT_FRAMING: &str = "line";
25 const DEFAULT_KEY: &str = "flowgger.pem";
26 const DEFAULT_LISTEN: &str = "0.0.0.0:6514";
27 #[cfg(feature = "coroutines")]
28 const DEFAULT_THREADS: usize = 1;
29 const DEFAULT_TIMEOUT: u64 = 3600;
30 const DEFAULT_TLS_COMPATIBILITY_LEVEL: &str = "default";
31 const DEFAULT_VERIFY_PEER: bool = false;
32 const TLS_VERIFY_DEPTH: u32 = 6;
33
34 #[derive(Clone)]
35 pub struct TlsConfig {
36 framing: String,
37 threads: usize,
38 acceptor: SslAcceptor,
39 }
40
set_fs(ctx: &mut SslContextBuilder)41 fn set_fs(ctx: &mut SslContextBuilder) {
42 let p = BigNum::from_hex_str("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597").unwrap();
43 let g = BigNum::from_hex_str("3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659").unwrap();
44 let q =
45 BigNum::from_hex_str("8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3")
46 .unwrap();
47 let dh = Dh::from_params(p, g, q).unwrap();
48 ctx.set_tmp_dh(&dh).unwrap();
49 }
50
51 #[cfg(feature = "coroutines")]
get_default_threads(config: &Config) -> usize52 fn get_default_threads(config: &Config) -> usize {
53 config
54 .lookup("input.tls_threads")
55 .map_or(DEFAULT_THREADS, |x| {
56 x.as_integer()
57 .expect("input.tls_threads must be an unsigned integer") as usize
58 })
59 }
60
61 #[cfg(not(feature = "coroutines"))]
get_default_threads(_config: &Config) -> usize62 fn get_default_threads(_config: &Config) -> usize {
63 1
64 }
65
config_parse(config: &Config) -> (TlsConfig, String, u64)66 pub fn config_parse(config: &Config) -> (TlsConfig, String, u64) {
67 let listen = config
68 .lookup("input.listen")
69 .map_or(DEFAULT_LISTEN, |x| {
70 x.as_str().expect("input.listen must be an ip:port string")
71 })
72 .to_owned();
73 let threads = get_default_threads(config);
74 let cert = config
75 .lookup("input.tls_cert")
76 .map_or(DEFAULT_CERT, |x| {
77 x.as_str()
78 .expect("input.tls_cert must be a path to a .pem file")
79 })
80 .to_owned();
81 let key = config
82 .lookup("input.tls_key")
83 .map_or(DEFAULT_KEY, |x| {
84 x.as_str()
85 .expect("input.tls_key must be a path to a .pem file")
86 })
87 .to_owned();
88 let ciphers = config
89 .lookup("input.tls_ciphers")
90 .map_or(DEFAULT_CIPHERS, |x| {
91 x.as_str()
92 .expect("input.tls_ciphers must be a string with a cipher suite")
93 })
94 .to_owned();
95
96 let tls_modern = match config
97 .lookup("input.tls_compatibility_level")
98 .map_or(DEFAULT_TLS_COMPATIBILITY_LEVEL, |x| {
99 x.as_str().expect(
100 "input.tls_compatibility_level must be a string with the comptibility level",
101 )
102 })
103 .to_lowercase()
104 .as_ref()
105 {
106 "default" | "any" | "intermediate" => false,
107 "modern" => true,
108 _ => panic!(r#"TLS compatibility level must be "intermediate" or "modern""#),
109 };
110 let verify_peer = config
111 .lookup("input.tls_verify_peer")
112 .map_or(DEFAULT_VERIFY_PEER, |x| {
113 x.as_bool()
114 .expect("input.tls_verify_peer must be a boolean")
115 });
116 let ca_file: Option<PathBuf> = config.lookup("input.tls_ca_file").and_then(|x| {
117 Some(PathBuf::from(
118 x.as_str()
119 .expect("input.tls_ca_file must be a path to a file"),
120 ))
121 });
122 let compression = config
123 .lookup("input.tls_compression")
124 .map_or(DEFAULT_COMPRESSION, |x| {
125 x.as_bool()
126 .expect("input.tls_compression must be a boolean")
127 });
128 let timeout = config.lookup("input.timeout").map_or(DEFAULT_TIMEOUT, |x| {
129 x.as_integer().expect("input.timeout must be an integer") as u64
130 });
131 let framing = if config.lookup("input.framed").map_or(false, |x| {
132 x.as_bool().expect("input.framed must be a boolean")
133 }) {
134 "syslen"
135 } else {
136 DEFAULT_FRAMING
137 };
138 let framing = config
139 .lookup("input.framing")
140 .map_or(framing, |x| {
141 x.as_str()
142 .expect(r#"input.framing must be a string set to "line", "nul" or "syslen""#)
143 })
144 .to_owned();
145 let mut acceptor_builder = (if tls_modern {
146 SslAcceptor::mozilla_modern(SslMethod::tls())
147 } else {
148 SslAcceptor::mozilla_intermediate(SslMethod::tls())
149 })
150 .unwrap();
151 {
152 let mut ctx = &mut acceptor_builder;
153 if let Some(ca_file) = ca_file {
154 ctx.set_ca_file(&ca_file)
155 .expect("Unable to read the trusted CA file");
156 }
157 if !verify_peer {
158 ctx.set_verify(SslVerifyMode::NONE);
159 } else {
160 ctx.set_verify_depth(TLS_VERIFY_DEPTH);
161 ctx.set_verify(SslVerifyMode::PEER | SslVerifyMode::FAIL_IF_NO_PEER_CERT);
162 }
163 let mut opts = SslOptions::CIPHER_SERVER_PREFERENCE
164 | SslOptions::NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
165 if !compression {
166 opts |= SslOptions::NO_COMPRESSION;
167 }
168 ctx.set_options(opts);
169 set_fs(&mut ctx);
170 ctx.set_certificate_chain_file(&Path::new(&cert))
171 .expect("Unable to read the TLS certificate chain");
172 ctx.set_private_key_file(&Path::new(&key), SslFiletype::PEM)
173 .expect("Unable to read the TLS key");
174 ctx.set_cipher_list(&ciphers)
175 .expect("Unsupported cipher suite");
176 }
177 let acceptor = acceptor_builder.build();
178 let tls_config = TlsConfig {
179 framing,
180 threads,
181 acceptor,
182 };
183 (tls_config, listen, timeout)
184 }
185