Skip to content

Commit 0adc587

Browse files
committed
Merge branch '18-ssl-WIP'
2 parents e057519 + 4ef827b commit 0adc587

File tree

6 files changed

+138
-22
lines changed

6 files changed

+138
-22
lines changed

Cargo.lock

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ serde_json = "1.0"
3232
serde_yaml = "0.8"
3333

3434
ratel = "0.7.0"
35+
tempdir = "0.3.7"

src/lib/bs.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern crate serde_derive;
2121

2222
#[macro_use]
2323
extern crate serde_json;
24+
extern crate tempdir;
2425

2526
pub mod config;
2627
pub mod from_file;
@@ -33,5 +34,6 @@ pub mod proxy_utils;
3334
pub mod replacer;
3435
pub mod rewrites;
3536
pub mod setup;
37+
pub mod ssl;
3638
pub mod with_body;
3739
pub mod without_body;

src/lib/config.rs

+15
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ pub enum ProgramStartError {
3636
ConfigCliError(ConfigError),
3737
InvalidArgs(Error),
3838
FromFile(FromFileError),
39+
BindHttp(std::io::Error),
40+
BindHttps(std::io::Error),
41+
SslFailed,
42+
SslTempDir,
43+
SslTempDirClose,
3944
}
4045

4146
impl std::fmt::Display for ProgramStartError {
@@ -58,6 +63,16 @@ impl std::fmt::Display for ProgramStartError {
5863
ProgramStartError::ConfigFileRead => write!(f, "config file content could not be read"),
5964
ProgramStartError::FromFile(e) => write!(f, "{}", e),
6065
ProgramStartError::InvalidArgs(e) => write!(f, "{}", e),
66+
ProgramStartError::SslFailed => write!(f, "could not create self-signed ssl certs"),
67+
ProgramStartError::SslTempDir => write!(
68+
f,
69+
"could not create the temp dir to hold self-signed ssl certs"
70+
),
71+
ProgramStartError::SslTempDirClose => write!(f, "could not clean up the temp dir"),
72+
ProgramStartError::BindHttp(e) => write!(f, "could not bind over http, reason: {}", e),
73+
ProgramStartError::BindHttps(e) => {
74+
write!(f, "could not bind over https, reason: {}", e)
75+
}
6176
}
6277
}
6378
}

src/lib/ssl.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use config::ProgramStartError;
2+
use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod};
3+
use std::fs::File;
4+
use std::io::{Error, Write};
5+
use std::path::PathBuf;
6+
use tempdir::TempDir;
7+
8+
const TMP_DIR_NAME: &'static str = "config-gen";
9+
10+
const TMP_KEY: &'static [u8] = include_bytes!("../key.pem");
11+
const TMP_KEY_NAME: &'static str = "key.pem";
12+
13+
const TMP_CERT: &'static [u8] = include_bytes!("../cert.pem");
14+
const TMP_CERT_NAME: &'static str = "cert.pem";
15+
16+
///
17+
/// Create an SslAcceptorBuilder by using self-signed
18+
/// certificates that exist inside this binary
19+
///
20+
/// This is acceptable since this is a development only
21+
/// tool and nothing this runs should be anywhere near anything
22+
/// that's shared, or in production.
23+
///
24+
pub fn builder() -> Result<SslAcceptorBuilder, ProgramStartError> {
25+
let (key_path, cert_path, tmp_dir) = ssl_paths().map_err(|_e| ProgramStartError::SslTempDir)?;
26+
27+
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls())
28+
.map_err(|_e| ProgramStartError::SslFailed)?;
29+
30+
builder
31+
.set_private_key_file(key_path, SslFiletype::PEM)
32+
.map_err(|_e| ProgramStartError::SslFailed)?;
33+
34+
builder
35+
.set_certificate_chain_file(cert_path)
36+
.map_err(|_e| ProgramStartError::SslFailed)?;
37+
38+
tmp_dir
39+
.close()
40+
.map_err(|_e| ProgramStartError::SslTempDirClose)?;
41+
42+
Ok(builder)
43+
}
44+
45+
#[test]
46+
fn test_ssl_builder() {
47+
builder().unwrap();
48+
}
49+
50+
///
51+
/// Takes the self-signed bundled key & cert
52+
/// and places them in a temporary directory so that they
53+
/// can be used by openSSL
54+
///
55+
/// # Examples
56+
///
57+
/// ```
58+
/// use bs::ssl::*;
59+
/// let (key_path, cert_path, tmp_dir) = ssl_paths().unwrap();
60+
/// println!("key={:?}, cert={:?}", key_path, cert_path);
61+
/// tmp_dir.close().unwrap();
62+
/// ```
63+
///
64+
pub fn ssl_paths() -> Result<(PathBuf, PathBuf, TempDir), Error> {
65+
let tmp_dir = TempDir::new(TMP_DIR_NAME)?;
66+
let key_path = tmp_dir.path().join(TMP_KEY_NAME);
67+
let cert_path = tmp_dir.path().join(TMP_CERT_NAME);
68+
69+
let mut key_file = File::create(&key_path)?;
70+
key_file.write_all(TMP_KEY)?;
71+
key_file.sync_all()?;
72+
73+
let mut cert_file = File::create(&cert_path)?;
74+
cert_file.write_all(TMP_CERT)?;
75+
cert_file.sync_all()?;
76+
77+
Ok((key_path, cert_path, tmp_dir))
78+
}
79+
80+
#[test]
81+
fn test_ssl_paths() {
82+
let (_file_key, _file_cert, tmp_dir) = ssl_paths().unwrap();
83+
assert_eq!(tmp_dir.path().exists(), true);
84+
}

src/main.rs

+16-22
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ extern crate mime;
1111
extern crate openssl;
1212
extern crate regex;
1313
extern crate serde_yaml;
14+
extern crate tempdir;
1415
extern crate url;
1516

1617
use actix_web::{server, App};
17-
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
1818

1919
use bs::config::{ProgramConfig, ProgramStartError};
2020
use bs::from_file::FromFile;
2121
use bs::options::{ProgramOptions, ProxyScheme};
2222
use bs::setup::{apply_presets, state_and_presets};
23-
use openssl::ssl::SslAcceptorBuilder;
23+
use bs::ssl;
2424

2525
fn main() {
2626
match ProgramOptions::from_vec(&mut std::env::args_os()).and_then(run_with_opts) {
27-
Ok(opts) => println!("Running!"),
27+
Ok(..) => { /* Running! */ }
2828
Err(e) => {
2929
eprintln!("{}", e);
3030
std::process::exit(1);
@@ -87,31 +87,25 @@ fn run_with_opts(opts: ProgramOptions) -> Result<(), ProgramStartError> {
8787
// target URL's scheme
8888
//
8989
let s = match server_opts.scheme {
90-
ProxyScheme::Http => s.bind(&local_addr),
91-
ProxyScheme::Https => s.bind_ssl(&local_addr, get_ssl_builder()),
90+
ProxyScheme::Http => s.bind(&local_addr).map_err(ProgramStartError::BindHttp)?,
91+
ProxyScheme::Https => {
92+
let builder = ssl::builder()?;
93+
s.bind_ssl(&local_addr, builder)
94+
.map_err(ProgramStartError::BindHttps)?
95+
}
9296
};
9397

94-
s.expect("Couldn't start the application")
95-
.shutdown_timeout(0)
96-
.start();
98+
//
99+
// Start the server
100+
//
101+
s.shutdown_timeout(0).start();
97102

103+
//
104+
// Output the proxy URL only
105+
//
98106
println!("{}://{}", server_opts.scheme, local_addr);
99107

100108
let _ = sys.run();
101109

102110
Ok(())
103111
}
104-
105-
///
106-
/// SSL builder
107-
///
108-
/// Todo: allow key/cert options
109-
///
110-
fn get_ssl_builder() -> SslAcceptorBuilder {
111-
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
112-
builder
113-
.set_private_key_file("src/key.pem", SslFiletype::PEM)
114-
.unwrap();
115-
builder.set_certificate_chain_file("src/cert.pem").unwrap();
116-
builder
117-
}

0 commit comments

Comments
 (0)