diff --git a/README.md b/README.md index 3cdc04c0..5f842723 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ on other systems use their respective package managers. Then run: ``` -cargo run --bin bitwarden_rs +cargo run # or cargo build ``` diff --git a/src/bin/proxy.rs b/src/bin/proxy.rs deleted file mode 100644 index 572a5f1e..00000000 --- a/src/bin/proxy.rs +++ /dev/null @@ -1,167 +0,0 @@ -#![feature(plugin)] - -#![plugin(rocket_codegen)] -extern crate rocket; -extern crate rocket_contrib; -extern crate reqwest; - -use std::io::{self, Cursor}; -use std::str::FromStr; -use std::path::{Path, PathBuf}; - -use rocket::{Request, Response}; -use rocket::config::Config; -use rocket::fairing::{Fairing, Info, Kind}; -use rocket::http; -use rocket::response::NamedFile; - -use reqwest::header::{self, Headers}; - -/** -** These routes are here to avoid showing errors in the console, -** redirect the body data to the fairing and show the web vault. -**/ -#[get("/")] -fn index() -> io::Result { - NamedFile::open(Path::new("web-vault").join("index.html")) -} - -#[get("/")] // Only match this if the other routes don't match -fn get(p: PathBuf) -> io::Result { - NamedFile::open(Path::new("web-vault").join(p)) -} - -#[delete("/<_p..>")] -fn delete(_p: PathBuf) {} - -#[put("/<_p..>", data = "")] -fn put(_p: PathBuf, d: Vec) -> Vec { d } - -#[post("/<_p..>", data = "")] -fn post(_p: PathBuf, d: Vec) -> Vec { d } - - -fn main() { - let config = Config::development().unwrap(); - - rocket::custom(config, false) - .mount("/", routes![get, put, post, delete, index]) - .attach(ProxyFairing { client: reqwest::Client::new() }) - .launch(); -} - -struct ProxyFairing { - client: reqwest::Client -} - -impl Fairing for ProxyFairing { - fn info(&self) -> Info { - Info { - name: "Proxy Fairing", - kind: Kind::Launch | Kind::Response, - } - } - - fn on_launch(&self, _rocket: &rocket::Rocket) { - println!("Started proxy on locahost:8000"); - } - - fn on_response(&self, req: &Request, res: &mut Response) { - // Prepare the data to make the request - // ------------------------------------- - - let url = { - let url = req.uri().as_str(); - - // Check if we are outside the API paths - if !url.starts_with("/api/") - && !url.starts_with("/identity/") { - return; - } - - // Replace the path with the real server URL - url.replacen("/api/", "https://api.bitwarden.com/", 1) - .replacen("/identity/", "https://identity.bitwarden.com/", 1) - }; - - let host = url.split("/").collect::>()[2]; - let headers = headers_rocket_to_reqwest(req.headers(), host); - let method = reqwest::Method::from_str(req.method().as_str()).unwrap(); - let body = res.body_bytes(); - - println!("\n\nREQ. {} {}", req.method().as_str(), url); - println!("HEADERS. {:#?}", headers); - if let Some(ref body) = body { - let body_string = String::from_utf8_lossy(body); - if !body_string.contains("") { - println!("BODY. {:?}", body_string); - } - } - - - // Execute the request - // ------------------------------------- - let mut client = self.client.request(method, &url); - let request_builder = client.headers(headers); - - if let Some(body_vec) = body { - request_builder.body(body_vec); - } - - let mut server_res = match request_builder.send() { - Ok(response) => response, - Err(e) => { - res.set_status(http::Status::BadRequest); - res.set_sized_body(Cursor::new(e.to_string())); - return; - } - }; - - // Get the response values - // ------------------------------------- - let mut res_body: Vec = vec![]; - server_res.copy_to(&mut res_body).unwrap(); - - let res_status = server_res.status().as_u16(); - let mut res_headers = server_res.headers().clone(); - - // These headers break stuff - res_headers.remove::(); - res_headers.remove::(); - - println!("\n\nRES. {} {}", res_status, url); - // Nothing interesting here - // println!("HEADERS. {:#?}", res_headers); - println!("BODY. {:?}", String::from_utf8_lossy(&res_body)); - - // Prepare the response - // ------------------------------------- - res.set_status(http::Status::from_code(res_status).unwrap_or(http::Status::BadRequest)); - - headers_reqwest_to_rocket(&res_headers, res); - res.set_sized_body(Cursor::new(res_body)); - } -} - -fn headers_rocket_to_reqwest(headers: &http::HeaderMap, host: &str) -> Headers { - let mut new_headers = Headers::new(); - - for header in headers.iter() { - let name = header.name().to_string(); - - let value = if name.to_lowercase() != "host" { - header.value().to_string() - } else { - host.to_string() - }; - - new_headers.set_raw(name, value); - } - new_headers -} - -fn headers_reqwest_to_rocket(headers: &Headers, res: &mut Response) { - for header in headers.iter() { - res.set_raw_header(header.name().to_string(), header.value_string()); - } -}