]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/bin/proxmox-backup-proxy.rs
rename src/api to src/api_schema
[proxmox-backup.git] / src / bin / proxmox-backup-proxy.rs
index 5d3455e7068633400ceab388ac9bf14cef9aeba2..38b9ac69c1714cbdd9288c8bdbc113d204c07935 100644 (file)
@@ -1,89 +1,46 @@
+#[macro_use]
 extern crate proxmox_backup;
 
-use std::sync::Arc;
-
-use proxmox_backup::api::schema::*;
-use proxmox_backup::api::router::*;
-use proxmox_backup::api::config::*;
+use proxmox_backup::tools;
+use proxmox_backup::api_schema::router::*;
+use proxmox_backup::api_schema::config::*;
 use proxmox_backup::server::rest::*;
-use proxmox_backup::getopts;
 use proxmox_backup::auth_helpers::*;
 
-//use failure::*;
+use failure::*;
 use lazy_static::lazy_static;
 
 use futures::future::Future;
+use futures::stream::Stream;
 
 use hyper;
 
 fn main() {
 
+    if let Err(err) = run() {
+        eprintln!("Error: {}", err);
+        std::process::exit(-1);
+    }
+}
+
+fn run() -> Result<(), Error> {
+
     if let Err(err) = syslog::init(
         syslog::Facility::LOG_DAEMON,
         log::LevelFilter::Info,
         Some("proxmox-backup-proxy")) {
-        eprintln!("unable to inititialize syslog: {}", err);
-        std::process::exit(-1);
+        bail!("unable to inititialize syslog - {}", err);
     }
 
     let _ = public_auth_key(); // load with lazy_static
     let _ = csrf_secret(); // load with lazy_static
 
-    let command : Arc<Schema> = StringSchema::new("Command.")
-        .format(Arc::new(ApiStringFormat::Enum(vec![
-            "start".into(),
-            "status".into(),
-            "stop".into()
-        ])))
-        .into();
-
-    let schema = ObjectSchema::new("Parameters.")
-        .required("command", command);
-
-    let args: Vec<String> = std::env::args().skip(1).collect();
-
-    let options = match getopts::parse_arguments(&args, &vec!["command"], &schema) {
-        Ok((options, rest)) => {
-            if !rest.is_empty() {
-                eprintln!("Error: got additional arguments: {:?}", rest);
-                std::process::exit(-1);
-            }
-            options
-        }
-        Err(err) => {
-            eprintln!("Error: unable to parse arguments:\n{}", err);
-            std::process::exit(-1);
-        }
-    };
-
-    let command = options["command"].as_str().unwrap();
-
-    match command {
-        "start" => {
-            println!("Starting server.");
-        },
-        "stop" => {
-            println!("Stopping server.");
-            std::process::exit(0);
-        },
-        "status" => {
-            println!("Server status.");
-             std::process::exit(0);
-       },
-        _ => {
-            eprintln!("got unexpected command {}", command);
-            std::process::exit(-1);
-        },
-    }
-
-    let addr = ([0,0,0,0,0,0,0,0], 8007).into();
-
     lazy_static!{
        static ref ROUTER: Router = proxmox_backup::api2::router();
     }
 
     let mut config = ApiConfig::new(
-        "/usr/share/javascript/proxmox-backup", &ROUTER, RpcEnvironmentType::PUBLIC);
+        env!("PROXMOX_JSDIR"), &ROUTER, RpcEnvironmentType::PUBLIC);
 
     // add default dirs which includes jquery and bootstrap
     // my $base = '/usr/share/libpve-http-server-perl';
@@ -98,11 +55,40 @@ fn main() {
 
     let rest_server = RestServer::new(config);
 
-    let server = hyper::Server::bind(&addr)
+    let cert_path = configdir!("/proxy.pfx");
+    let raw_cert = tools::file_get_contents(cert_path)?;
+
+    let identity = match native_tls::Identity::from_pkcs12(&raw_cert, "") {
+        Ok(data) => data,
+        Err(err) => bail!("unabled to decode pkcs12 identity {} - {}", cert_path, err),
+    };
+
+    let addr = ([0,0,0,0,0,0,0,0], 8007).into();
+    let listener = tokio::net::TcpListener::bind(&addr)?;
+    let acceptor = native_tls::TlsAcceptor::new(identity)?;
+    let acceptor = std::sync::Arc::new(tokio_tls::TlsAcceptor::from(acceptor));
+    let connections = listener
+        .incoming()
+        .map_err(|e| Error::from(e))
+        .and_then(move |sock| acceptor.accept(sock).map_err(|e| e.into()))
+        .then(|r| match r {
+            // accept()s can fail here with an Err() when eg. the client rejects
+            // the cert and closes the connection, so we follow up with mapping
+            // it to an option and then filtering None with filter_map
+            Ok(c) => Ok::<_, Error>(Some(c)),
+            Err(_) => Ok(None),
+        })
+        .filter_map(|r| {
+            // Filter out the Nones
+            r
+        });
+
+    let server = hyper::Server::builder(connections)
         .serve(rest_server)
         .map_err(|e| eprintln!("server error: {}", e));
 
-
     // Run this server for... forever!
     hyper::rt::run(server);
+
+    Ok(())
 }