mirror of
git://git.proxmox.com/git/proxmox-backup.git
synced 2025-02-09 09:57:40 +03:00
adapt to rest-server 0.3 and http 0.8 changes
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
26f03f9e53
commit
5aeeb44a32
23
Cargo.toml
23
Cargo.toml
@ -59,12 +59,12 @@ proxmox-async = "0.4"
|
||||
proxmox-borrow = "1"
|
||||
proxmox-compression = "0.1.1"
|
||||
proxmox-fuse = "0.1.3"
|
||||
proxmox-http = { version = "0.7", features = [ "client", "http-helpers", "websocket" ] } # see below
|
||||
proxmox-http = { version = "0.8.0", features = [ "client", "http-helpers", "websocket" ] } # see below
|
||||
proxmox-io = "1.0.1" # tools and client use "tokio" feature
|
||||
proxmox-lang = "1.1"
|
||||
proxmox-ldap = "0.1"
|
||||
proxmox-metrics = "0.2"
|
||||
proxmox-rest-server = "0.2.2"
|
||||
proxmox-rest-server = { version = "0.3.0", features = [ "templates" ] }
|
||||
# some use "cli", some use "cli" and "server", pbs-config uses nothing
|
||||
proxmox-router = { version = "1.3.1", default_features = false }
|
||||
# everything but pbs-config and pbs-client ues "api-macro"
|
||||
@ -204,12 +204,12 @@ zstd.workspace = true
|
||||
|
||||
proxmox-async.workspace = true
|
||||
proxmox-compression.workspace = true
|
||||
proxmox-http = { workspace = true, features = [ "client-trait", "proxmox-async" ] } # pbs-client doesn't use these
|
||||
proxmox-http = { workspace = true, features = [ "client-trait", "proxmox-async", "rate-limited-stream" ] } # pbs-client doesn't use these
|
||||
proxmox-io.workspace = true
|
||||
proxmox-lang.workspace = true
|
||||
proxmox-ldap.workspace = true
|
||||
proxmox-metrics.workspace = true
|
||||
proxmox-rest-server.workspace = true
|
||||
proxmox-rest-server = { workspace = true, features = [ "rate-limited-stream" ] }
|
||||
proxmox-router = { workspace = true, features = [ "cli", "server"] }
|
||||
proxmox-schema = { workspace = true, features = [ "api-macro" ] }
|
||||
proxmox-section-config.workspace = true
|
||||
@ -243,25 +243,28 @@ proxmox-rrd.workspace = true
|
||||
# NOTE: You must run `cargo update` after changing this for it to take effect!
|
||||
[patch.crates-io]
|
||||
#proxmox-acme-rs = { path = "../proxmox-acme-rs" }
|
||||
#proxmox-apt = { path = "../proxmox-apt" }
|
||||
#proxmox-async = { path = "../proxmox/proxmox-async" }
|
||||
#proxmox-compression = { path = "../proxmox/proxmox-compression" }
|
||||
#proxmox-borrow = { path = "../proxmox/proxmox-borrow" }
|
||||
#proxmox-compression = { path = "../proxmox/proxmox-compression" }
|
||||
#proxmox-fuse = { path = "../proxmox-fuse" }
|
||||
#proxmox-http = { path = "../proxmox/proxmox-http" }
|
||||
#proxmox-io = { path = "../proxmox/proxmox-io" }
|
||||
#proxmox-lang = { path = "../proxmox/proxmox-lang" }
|
||||
#proxmox-openid = { path = "../proxmox-openid-rs" }
|
||||
#proxmox-router = { path = "../proxmox/proxmox-rest-server" }
|
||||
#proxmox-rest-server = { path = "../proxmox/proxmox-rest-server" }
|
||||
#proxmox-router = { path = "../proxmox/proxmox-router" }
|
||||
#proxmox-schema = { path = "../proxmox/proxmox-schema" }
|
||||
#proxmox-section-config = { path = "../proxmox/proxmox-section-config" }
|
||||
#proxmox-shared-memory = { path = "../proxmox/proxmox-shared-memory" }
|
||||
#proxmox-sys = { path = "../proxmox/proxmox-sys" }
|
||||
#proxmox-serde = { path = "../proxmox/proxmox-serde" }
|
||||
#proxmox-shared-memory = { path = "../proxmox/proxmox-shared-memory" }
|
||||
#proxmox-subscription = { path = "../proxmox/proxmox-subscription" }
|
||||
#proxmox-sys = { path = "../proxmox/proxmox-sys" }
|
||||
#proxmox-tfa = { path = "../proxmox/proxmox-tfa" }
|
||||
#proxmox-time = { path = "../proxmox/proxmox-time" }
|
||||
#proxmox-uuid = { path = "../proxmox/proxmox-uuid" }
|
||||
|
||||
#proxmox-apt = { path = "../proxmox-apt" }
|
||||
#proxmox-openid = { path = "../proxmox-openid-rs" }
|
||||
|
||||
#pxar = { path = "../pxar" }
|
||||
|
||||
[features]
|
||||
|
18
debian/control
vendored
18
debian/control
vendored
@ -47,19 +47,23 @@ Build-Depends: debhelper (>= 12),
|
||||
librust-proxmox-borrow-1+default-dev,
|
||||
librust-proxmox-compression-0.1+default-dev (>= 0.1.1-~~),
|
||||
librust-proxmox-fuse-0.1+default-dev (>= 0.1.3-~~),
|
||||
librust-proxmox-http-0.7+client-dev,
|
||||
librust-proxmox-http-0.7+client-trait-dev,
|
||||
librust-proxmox-http-0.7+default-dev,
|
||||
librust-proxmox-http-0.7+http-helpers-dev,
|
||||
librust-proxmox-http-0.7+proxmox-async-dev,
|
||||
librust-proxmox-http-0.7+websocket-dev,
|
||||
librust-proxmox-http-0.8+client-dev,
|
||||
librust-proxmox-http-0.8+client-trait-dev,
|
||||
librust-proxmox-http-0.8+default-dev,
|
||||
librust-proxmox-http-0.8+http-helpers-dev,
|
||||
librust-proxmox-http-0.8+proxmox-async-dev,
|
||||
librust-proxmox-http-0.8+rate-limited-stream-dev,
|
||||
librust-proxmox-http-0.8+rate-limiter-dev,
|
||||
librust-proxmox-http-0.8+websocket-dev,
|
||||
librust-proxmox-io-1+default-dev (>= 1.0.1-~~),
|
||||
librust-proxmox-io-1+tokio-dev (>= 1.0.1-~~),
|
||||
librust-proxmox-lang-1+default-dev (>= 1.1-~~),
|
||||
librust-proxmox-ldap-0.1+default-dev,
|
||||
librust-proxmox-metrics-0.2+default-dev,
|
||||
librust-proxmox-openid-0.9+default-dev (>= 0.9.9-~~),
|
||||
librust-proxmox-rest-server-0.2+default-dev (>= 0.2.2-~~),
|
||||
librust-proxmox-rest-server-0.3+default-dev,
|
||||
librust-proxmox-rest-server-0.3+rate-limited-stream-dev,
|
||||
librust-proxmox-rest-server-0.3+templates-dev,
|
||||
librust-proxmox-router-1+cli-dev (>= 1.3.1-~~),
|
||||
librust-proxmox-router-1+default-dev (>= 1.3.1-~~),
|
||||
librust-proxmox-router-1+server-dev (>= 1.3.1-~~),
|
||||
|
@ -35,7 +35,7 @@ pathpatterns.workspace = true
|
||||
|
||||
proxmox-async.workspace = true
|
||||
proxmox-compression.workspace = true
|
||||
proxmox-http.workspace = true
|
||||
proxmox-http = { workspace = true, features = [ "rate-limiter" ] }
|
||||
proxmox-io = { workspace = true, features = [ "tokio" ] }
|
||||
proxmox-lang.workspace = true
|
||||
proxmox-router = { workspace = true, features = [ "cli", "server" ] }
|
||||
|
@ -22,9 +22,9 @@ use proxmox_sys::fs::{file_get_json, replace_file, CreateOptions};
|
||||
use proxmox_sys::linux::tty;
|
||||
|
||||
use proxmox_async::broadcast_future::BroadcastFuture;
|
||||
use proxmox_http::client::{HttpsConnector, RateLimiter};
|
||||
use proxmox_http::client::HttpsConnector;
|
||||
use proxmox_http::uri::{build_authority, json_object_to_query};
|
||||
use proxmox_http::ProxyConfig;
|
||||
use proxmox_http::{ProxyConfig, RateLimiter};
|
||||
|
||||
use pbs_api_types::percent_encoding::DEFAULT_ENCODE_SET;
|
||||
use pbs_api_types::{Authid, RateLimitConfig, Userid};
|
||||
|
@ -107,10 +107,13 @@ async fn run() -> Result<(), Error> {
|
||||
}
|
||||
};
|
||||
|
||||
let adaptor = StaticAuthAdapter::new()
|
||||
.map_err(|err| format_err!("reading ticket file failed: {}", err))?;
|
||||
let ticket =
|
||||
auth::read_ticket().map_err(|err| format_err!("reading ticket file failed: {}", err))?;
|
||||
|
||||
let config = ApiConfig::new("", &ROUTER, RpcEnvironmentType::PUBLIC, adaptor)?;
|
||||
let config = ApiConfig::new("", RpcEnvironmentType::PUBLIC)
|
||||
.default_api2_handler(&ROUTER)
|
||||
.index_handler_func(|_, _| auth::get_index())
|
||||
.auth_handler_func(move |h, m| Box::pin(auth::check_auth(Arc::clone(&ticket), h, m)));
|
||||
let rest_server = RestServer::new(config);
|
||||
|
||||
let vsock_fd = get_vsock_fd()?;
|
||||
|
@ -3,15 +3,15 @@ use std::fs::File;
|
||||
use std::future::Future;
|
||||
use std::io::prelude::*;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{bail, format_err, Error};
|
||||
use http::request::Parts;
|
||||
use http::HeaderMap;
|
||||
use hyper::{Body, Method, Response, StatusCode};
|
||||
|
||||
use proxmox_router::UserInformation;
|
||||
|
||||
use proxmox_rest_server::{AuthError, RestEnvironment, ServerAdapter};
|
||||
use proxmox_rest_server::AuthError;
|
||||
|
||||
const TICKET_FILE: &str = "/ticket";
|
||||
|
||||
@ -29,61 +29,49 @@ impl UserInformation for SimpleUserInformation {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StaticAuthAdapter {
|
||||
ticket: String,
|
||||
}
|
||||
|
||||
impl StaticAuthAdapter {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
let mut ticket_file = File::open(TICKET_FILE)?;
|
||||
let mut ticket = String::new();
|
||||
let len = ticket_file.read_to_string(&mut ticket)?;
|
||||
if len == 0 {
|
||||
bail!("invalid ticket: cannot be empty");
|
||||
}
|
||||
Ok(StaticAuthAdapter { ticket })
|
||||
pub fn read_ticket() -> Result<Arc<str>, Error> {
|
||||
let mut ticket_file = File::open(TICKET_FILE)?;
|
||||
let mut ticket = String::new();
|
||||
let len = ticket_file.read_to_string(&mut ticket)?;
|
||||
if len == 0 {
|
||||
bail!("invalid ticket: cannot be empty");
|
||||
}
|
||||
Ok(ticket.into())
|
||||
}
|
||||
|
||||
impl ServerAdapter for StaticAuthAdapter {
|
||||
fn check_auth<'a>(
|
||||
&'a self,
|
||||
headers: &'a HeaderMap,
|
||||
_method: &'a Method,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>>
|
||||
+ Send
|
||||
+ 'a,
|
||||
>,
|
||||
> {
|
||||
Box::pin(async move {
|
||||
match headers.get(hyper::header::AUTHORIZATION) {
|
||||
Some(header) if header.to_str().unwrap_or("") == self.ticket => {
|
||||
let user_info: Box<dyn UserInformation + Send + Sync> =
|
||||
Box::new(SimpleUserInformation {});
|
||||
Ok((String::from("root@pam"), user_info))
|
||||
}
|
||||
_ => Err(AuthError::Generic(format_err!(
|
||||
"invalid file restore ticket provided"
|
||||
))),
|
||||
pub fn check_auth<'a>(
|
||||
ticket: Arc<str>,
|
||||
headers: &'a HeaderMap,
|
||||
_method: &'a Method,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>>
|
||||
+ Send
|
||||
+ 'a,
|
||||
>,
|
||||
> {
|
||||
Box::pin(async move {
|
||||
match headers.get(hyper::header::AUTHORIZATION) {
|
||||
Some(header) if header.to_str().unwrap_or("") == &*ticket => {
|
||||
let user_info: Box<dyn UserInformation + Send + Sync> =
|
||||
Box::new(SimpleUserInformation {});
|
||||
Ok((String::from("root@pam"), user_info))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn get_index(
|
||||
&self,
|
||||
_env: RestEnvironment,
|
||||
_parts: Parts,
|
||||
) -> Pin<Box<dyn Future<Output = http::Response<Body>> + Send>> {
|
||||
Box::pin(async move {
|
||||
let index = "<center><h1>Proxmox Backup Restore Daemon/h1></center>";
|
||||
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(hyper::header::CONTENT_TYPE, "text/html")
|
||||
.body(index.into())
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
_ => Err(AuthError::Generic(format_err!(
|
||||
"invalid file restore ticket provided"
|
||||
))),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_index() -> Pin<Box<dyn Future<Output = http::Response<Body>> + Send>> {
|
||||
Box::pin(async move {
|
||||
let index = "<center><h1>Proxmox Backup Restore Daemon/h1></center>";
|
||||
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(hyper::header::CONTENT_TYPE, "text/html")
|
||||
.body(index.into())
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
|
@ -3,18 +3,14 @@ use std::pin::Pin;
|
||||
|
||||
use anyhow::{bail, Error};
|
||||
use futures::*;
|
||||
use http::request::Parts;
|
||||
use http::HeaderMap;
|
||||
use http::Response;
|
||||
use hyper::{Body, Method, StatusCode};
|
||||
use hyper::{Body, StatusCode};
|
||||
|
||||
use proxmox_lang::try_block;
|
||||
use proxmox_router::{RpcEnvironmentType, UserInformation};
|
||||
use proxmox_router::RpcEnvironmentType;
|
||||
use proxmox_sys::fs::CreateOptions;
|
||||
|
||||
use proxmox_rest_server::{
|
||||
daemon, ApiConfig, AuthError, RestEnvironment, RestServer, ServerAdapter,
|
||||
};
|
||||
use proxmox_rest_server::{daemon, ApiConfig, RestServer};
|
||||
|
||||
use proxmox_backup::auth_helpers::*;
|
||||
use proxmox_backup::config;
|
||||
@ -31,38 +27,16 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
struct ProxmoxBackupApiAdapter;
|
||||
fn get_index() -> Pin<Box<dyn Future<Output = Response<Body>> + Send>> {
|
||||
Box::pin(async move {
|
||||
let index = "<center><h1>Proxmox Backup API Server</h1></center>";
|
||||
|
||||
impl ServerAdapter for ProxmoxBackupApiAdapter {
|
||||
fn get_index(
|
||||
&self,
|
||||
_env: RestEnvironment,
|
||||
_parts: Parts,
|
||||
) -> Pin<Box<dyn Future<Output = Response<Body>> + Send>> {
|
||||
Box::pin(async move {
|
||||
let index = "<center><h1>Proxmox Backup API Server</h1></center>";
|
||||
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(hyper::header::CONTENT_TYPE, "text/html")
|
||||
.body(index.into())
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
fn check_auth<'a>(
|
||||
&'a self,
|
||||
headers: &'a HeaderMap,
|
||||
method: &'a Method,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>>
|
||||
+ Send
|
||||
+ 'a,
|
||||
>,
|
||||
> {
|
||||
Box::pin(async move { check_pbs_auth(headers, method).await })
|
||||
}
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(hyper::header::CONTENT_TYPE, "text/html")
|
||||
.body(index.into())
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
async fn run() -> Result<(), Error> {
|
||||
@ -97,13 +71,6 @@ async fn run() -> Result<(), Error> {
|
||||
}
|
||||
let _ = csrf_secret(); // load with lazy_static
|
||||
|
||||
let mut config = ApiConfig::new(
|
||||
pbs_buildcfg::JS_DIR,
|
||||
&proxmox_backup::api2::ROUTER,
|
||||
RpcEnvironmentType::PRIVILEGED,
|
||||
ProxmoxBackupApiAdapter,
|
||||
)?;
|
||||
|
||||
let backup_user = pbs_config::backup_user()?;
|
||||
let mut commando_sock = proxmox_rest_server::CommandSocket::new(
|
||||
proxmox_rest_server::our_ctrl_sock(),
|
||||
@ -117,19 +84,22 @@ async fn run() -> Result<(), Error> {
|
||||
.owner(backup_user.uid)
|
||||
.group(backup_user.gid);
|
||||
|
||||
config.enable_access_log(
|
||||
pbs_buildcfg::API_ACCESS_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?;
|
||||
|
||||
config.enable_auth_log(
|
||||
pbs_buildcfg::API_AUTH_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?;
|
||||
let config = ApiConfig::new(pbs_buildcfg::JS_DIR, RpcEnvironmentType::PRIVILEGED)
|
||||
.index_handler_func(|_, _| get_index())
|
||||
.auth_handler_func(|h, m| Box::pin(check_pbs_auth(h, m)))
|
||||
.default_api2_handler(&proxmox_backup::api2::ROUTER)
|
||||
.enable_access_log(
|
||||
pbs_buildcfg::API_ACCESS_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?
|
||||
.enable_auth_log(
|
||||
pbs_buildcfg::API_AUTH_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?;
|
||||
|
||||
let rest_server = RestServer::new(config);
|
||||
proxmox_rest_server::init_worker_tasks(
|
||||
|
@ -1,7 +1,4 @@
|
||||
use std::future::Future;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::pin::Pin;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use anyhow::{bail, format_err, Error};
|
||||
@ -12,28 +9,22 @@ use hyper::header;
|
||||
use hyper::{Body, StatusCode};
|
||||
use url::form_urlencoded;
|
||||
|
||||
use http::{HeaderMap, Method};
|
||||
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
||||
use openssl::ssl::SslAcceptor;
|
||||
use serde_json::{json, Value};
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
|
||||
use proxmox_http::client::RateLimitedStream;
|
||||
use proxmox_lang::try_block;
|
||||
use proxmox_metrics::MetricsData;
|
||||
use proxmox_router::{RpcEnvironment, RpcEnvironmentType, UserInformation};
|
||||
use proxmox_router::{RpcEnvironment, RpcEnvironmentType};
|
||||
use proxmox_sys::fs::{CreateOptions, FileSystemInformation};
|
||||
use proxmox_sys::linux::{
|
||||
procfs::{Loadavg, ProcFsMemInfo, ProcFsNetDev, ProcFsStat},
|
||||
socket::set_tcp_keepalive,
|
||||
};
|
||||
use proxmox_sys::linux::procfs::{Loadavg, ProcFsMemInfo, ProcFsNetDev, ProcFsStat};
|
||||
use proxmox_sys::logrotate::LogRotate;
|
||||
use proxmox_sys::{task_log, task_warn};
|
||||
|
||||
use pbs_datastore::DataStore;
|
||||
|
||||
use proxmox_rest_server::{
|
||||
cleanup_old_tasks, cookie_from_header, rotate_task_log_archive, ApiConfig, AuthError,
|
||||
RestEnvironment, RestServer, ServerAdapter, WorkerTask,
|
||||
cleanup_old_tasks, cookie_from_header, rotate_task_log_archive, ApiConfig, RestEnvironment,
|
||||
RestServer, WorkerTask,
|
||||
};
|
||||
|
||||
use proxmox_backup::rrd_cache::{
|
||||
@ -89,32 +80,6 @@ fn main() -> Result<(), Error> {
|
||||
proxmox_async::runtime::main(run())
|
||||
}
|
||||
|
||||
struct ProxmoxBackupProxyAdapter;
|
||||
|
||||
impl ServerAdapter for ProxmoxBackupProxyAdapter {
|
||||
fn get_index(
|
||||
&self,
|
||||
env: RestEnvironment,
|
||||
parts: Parts,
|
||||
) -> Pin<Box<dyn Future<Output = Response<Body>> + Send>> {
|
||||
Box::pin(get_index_future(env, parts))
|
||||
}
|
||||
|
||||
fn check_auth<'a>(
|
||||
&'a self,
|
||||
headers: &'a HeaderMap,
|
||||
method: &'a Method,
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>>
|
||||
+ Send
|
||||
+ 'a,
|
||||
>,
|
||||
> {
|
||||
Box::pin(async move { check_pbs_auth(headers, method).await })
|
||||
}
|
||||
}
|
||||
|
||||
/// check for a cookie with the user-preferred language, fallback to the config one if not set or
|
||||
/// not existing
|
||||
fn get_language(headers: &http::HeaderMap) -> String {
|
||||
@ -217,29 +182,28 @@ async fn run() -> Result<(), Error> {
|
||||
let rrd_cache = initialize_rrd_cache()?;
|
||||
rrd_cache.apply_journal()?;
|
||||
|
||||
let mut config = ApiConfig::new(
|
||||
pbs_buildcfg::JS_DIR,
|
||||
&proxmox_backup::api2::ROUTER,
|
||||
RpcEnvironmentType::PUBLIC,
|
||||
ProxmoxBackupProxyAdapter,
|
||||
)?;
|
||||
|
||||
config.add_alias("novnc", "/usr/share/novnc-pve");
|
||||
config.add_alias("extjs", "/usr/share/javascript/extjs");
|
||||
config.add_alias("qrcodejs", "/usr/share/javascript/qrcodejs");
|
||||
config.add_alias("fontawesome", "/usr/share/fonts-font-awesome");
|
||||
config.add_alias("xtermjs", "/usr/share/pve-xtermjs");
|
||||
config.add_alias("locale", "/usr/share/pbs-i18n");
|
||||
config.add_alias(
|
||||
"widgettoolkit",
|
||||
"/usr/share/javascript/proxmox-widget-toolkit",
|
||||
);
|
||||
config.add_alias("docs", "/usr/share/doc/proxmox-backup/html");
|
||||
|
||||
let mut indexpath = PathBuf::from(pbs_buildcfg::JS_DIR);
|
||||
indexpath.push("index.hbs");
|
||||
config.register_template("index", &indexpath)?;
|
||||
config.register_template("console", "/usr/share/pve-xtermjs/index.html.hbs")?;
|
||||
|
||||
let mut config = ApiConfig::new(pbs_buildcfg::JS_DIR, RpcEnvironmentType::PUBLIC)
|
||||
.index_handler_func(|e, p| Box::pin(get_index_future(e, p)))
|
||||
.auth_handler_func(|h, m| Box::pin(check_pbs_auth(h, m)))
|
||||
.register_template("index", &indexpath)?
|
||||
.register_template("console", "/usr/share/pve-xtermjs/index.html.hbs")?
|
||||
.default_api2_handler(&proxmox_backup::api2::ROUTER)
|
||||
.aliases([
|
||||
("novnc", "/usr/share/novnc-pve"),
|
||||
("extjs", "/usr/share/javascript/extjs"),
|
||||
("qrcodejs", "/usr/share/javascript/qrcodejs"),
|
||||
("fontawesome", "/usr/share/fonts-font-awesome"),
|
||||
("xtermjs", "/usr/share/pve-xtermjs"),
|
||||
("locale", "/usr/share/pbs-i18n"),
|
||||
(
|
||||
"widgettoolkit",
|
||||
"/usr/share/javascript/proxmox-widget-toolkit",
|
||||
),
|
||||
("docs", "/usr/share/doc/proxmox-backup/html"),
|
||||
]);
|
||||
|
||||
let backup_user = pbs_config::backup_user()?;
|
||||
let mut commando_sock = proxmox_rest_server::CommandSocket::new(
|
||||
@ -254,19 +218,19 @@ async fn run() -> Result<(), Error> {
|
||||
.owner(backup_user.uid)
|
||||
.group(backup_user.gid);
|
||||
|
||||
config.enable_access_log(
|
||||
pbs_buildcfg::API_ACCESS_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?;
|
||||
|
||||
config.enable_auth_log(
|
||||
pbs_buildcfg::API_AUTH_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?;
|
||||
config = config
|
||||
.enable_access_log(
|
||||
pbs_buildcfg::API_ACCESS_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?
|
||||
.enable_auth_log(
|
||||
pbs_buildcfg::API_AUTH_LOG_FN,
|
||||
Some(dir_opts.clone()),
|
||||
Some(file_opts.clone()),
|
||||
&mut commando_sock,
|
||||
)?;
|
||||
|
||||
let rest_server = RestServer::new(config);
|
||||
proxmox_rest_server::init_worker_tasks(
|
||||
@ -304,11 +268,14 @@ async fn run() -> Result<(), Error> {
|
||||
Ok(Value::Null)
|
||||
})?;
|
||||
|
||||
let connections = proxmox_rest_server::connection::AcceptBuilder::with_acceptor(acceptor)
|
||||
.debug(debug)
|
||||
.rate_limiter_lookup(Arc::new(lookup_rate_limiter))
|
||||
.tcp_keepalive_time(PROXMOX_BACKUP_TCP_KEEPALIVE_TIME);
|
||||
let server = daemon::create_daemon(
|
||||
([0, 0, 0, 0, 0, 0, 0, 0], 8007).into(),
|
||||
move |listener| {
|
||||
let connections = accept_connections(listener, acceptor, debug);
|
||||
let connections = hyper::server::accept::from_stream(ReceiverStream::new(connections));
|
||||
let connections = connections.accept(listener);
|
||||
|
||||
Ok(async {
|
||||
daemon::systemd_notify(daemon::SystemdNotify::Ready)?;
|
||||
@ -368,128 +335,18 @@ fn make_tls_acceptor() -> Result<SslAcceptor, Error> {
|
||||
let ciphers_tls_1_3 = config.ciphers_tls_1_3;
|
||||
let ciphers_tls_1_2 = config.ciphers_tls_1_2;
|
||||
|
||||
let mut acceptor = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).unwrap();
|
||||
let mut acceptor = proxmox_rest_server::connection::TlsAcceptorBuilder::new()
|
||||
.certificate_paths_pem(key_path, cert_path);
|
||||
|
||||
//let mut acceptor = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).unwrap();
|
||||
if let Some(ciphers) = ciphers_tls_1_3.as_deref() {
|
||||
acceptor.set_ciphersuites(ciphers)?;
|
||||
acceptor = acceptor.cipher_suites(ciphers.to_string());
|
||||
}
|
||||
if let Some(ciphers) = ciphers_tls_1_2.as_deref() {
|
||||
acceptor.set_cipher_list(ciphers)?;
|
||||
acceptor = acceptor.cipher_list(ciphers.to_string());
|
||||
}
|
||||
acceptor
|
||||
.set_private_key_file(key_path, SslFiletype::PEM)
|
||||
.map_err(|err| format_err!("unable to read proxy key {key_path} - {err}"))?;
|
||||
acceptor
|
||||
.set_certificate_chain_file(cert_path)
|
||||
.map_err(|err| format_err!("unable to read proxy cert {cert_path} - {err}"))?;
|
||||
acceptor.set_options(openssl::ssl::SslOptions::NO_RENEGOTIATION);
|
||||
acceptor.check_private_key().unwrap();
|
||||
|
||||
Ok(acceptor.build())
|
||||
}
|
||||
|
||||
type ClientStreamResult = Result<
|
||||
std::pin::Pin<Box<tokio_openssl::SslStream<RateLimitedStream<tokio::net::TcpStream>>>>,
|
||||
Error,
|
||||
>;
|
||||
const MAX_PENDING_ACCEPTS: usize = 1024;
|
||||
|
||||
fn accept_connections(
|
||||
listener: tokio::net::TcpListener,
|
||||
acceptor: Arc<Mutex<openssl::ssl::SslAcceptor>>,
|
||||
debug: bool,
|
||||
) -> tokio::sync::mpsc::Receiver<ClientStreamResult> {
|
||||
let (sender, receiver) = tokio::sync::mpsc::channel(MAX_PENDING_ACCEPTS);
|
||||
|
||||
tokio::spawn(accept_connection(listener, acceptor, debug, sender));
|
||||
|
||||
receiver
|
||||
}
|
||||
|
||||
async fn accept_connection(
|
||||
listener: tokio::net::TcpListener,
|
||||
acceptor: Arc<Mutex<openssl::ssl::SslAcceptor>>,
|
||||
debug: bool,
|
||||
sender: tokio::sync::mpsc::Sender<ClientStreamResult>,
|
||||
) {
|
||||
let accept_counter = Arc::new(());
|
||||
let mut shutdown_future = proxmox_rest_server::shutdown_future().fuse();
|
||||
|
||||
loop {
|
||||
let (sock, peer) = select! {
|
||||
res = listener.accept().fuse() => match res {
|
||||
Ok(conn) => conn,
|
||||
Err(err) => {
|
||||
eprintln!("error accepting tcp connection: {err}");
|
||||
continue;
|
||||
}
|
||||
},
|
||||
_ = shutdown_future => break,
|
||||
};
|
||||
|
||||
sock.set_nodelay(true).unwrap();
|
||||
let _ = set_tcp_keepalive(sock.as_raw_fd(), PROXMOX_BACKUP_TCP_KEEPALIVE_TIME);
|
||||
|
||||
let sock =
|
||||
RateLimitedStream::with_limiter_update_cb(sock, move || lookup_rate_limiter(peer));
|
||||
|
||||
let ssl = {
|
||||
// limit acceptor_guard scope
|
||||
// Acceptor can be reloaded using the command socket "reload-certificate" command
|
||||
let acceptor_guard = acceptor.lock().unwrap();
|
||||
|
||||
match openssl::ssl::Ssl::new(acceptor_guard.context()) {
|
||||
Ok(ssl) => ssl,
|
||||
Err(err) => {
|
||||
eprintln!("failed to create Ssl object from Acceptor context - {err}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let stream = match tokio_openssl::SslStream::new(ssl, sock) {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => {
|
||||
eprintln!("failed to create SslStream using ssl and connection socket - {err}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let mut stream = Box::pin(stream);
|
||||
let sender = sender.clone();
|
||||
|
||||
if Arc::strong_count(&accept_counter) > MAX_PENDING_ACCEPTS {
|
||||
eprintln!("connection rejected - to many open connections");
|
||||
continue;
|
||||
}
|
||||
|
||||
let accept_counter = Arc::clone(&accept_counter);
|
||||
tokio::spawn(async move {
|
||||
let accept_future =
|
||||
tokio::time::timeout(Duration::new(10, 0), stream.as_mut().accept());
|
||||
|
||||
let result = accept_future.await;
|
||||
|
||||
match result {
|
||||
Ok(Ok(())) => {
|
||||
if sender.send(Ok(stream)).await.is_err() && debug {
|
||||
eprintln!("detect closed connection channel");
|
||||
}
|
||||
}
|
||||
Ok(Err(err)) => {
|
||||
if debug {
|
||||
eprintln!("https handshake failed - {err}");
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
if debug {
|
||||
eprintln!("https handshake timeout");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop(accept_counter); // decrease reference count
|
||||
});
|
||||
}
|
||||
acceptor.build()
|
||||
}
|
||||
|
||||
fn start_stat_generator() {
|
||||
|
@ -11,7 +11,7 @@ use proxmox_schema::{api, ApiType, ParameterSchema, Schema};
|
||||
|
||||
use pbs_api_types::PROXMOX_UPID_REGEX;
|
||||
use pbs_client::view_task_result;
|
||||
use proxmox_rest_server::normalize_uri_path;
|
||||
use proxmox_rest_server::normalize_path_with_components;
|
||||
|
||||
use proxmox_backup::client_helpers::connect_to_localhost;
|
||||
|
||||
@ -94,7 +94,7 @@ async fn get_child_links(
|
||||
path: &str,
|
||||
rpcenv: &mut dyn RpcEnvironment,
|
||||
) -> Result<Vec<String>, Error> {
|
||||
let (path, components) = normalize_uri_path(path)?;
|
||||
let (path, components) = normalize_path_with_components(path)?;
|
||||
|
||||
let info = &proxmox_backup::api2::ROUTER
|
||||
.find_route(&components, &mut HashMap::new())
|
||||
@ -132,7 +132,7 @@ fn get_api_method(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let mut uri_param = HashMap::new();
|
||||
let (path, components) = normalize_uri_path(path)?;
|
||||
let (path, components) = normalize_path_with_components(path)?;
|
||||
if let Some(method) =
|
||||
&proxmox_backup::api2::ROUTER.find_method(&components, method.clone(), &mut uri_param)
|
||||
{
|
||||
@ -384,7 +384,7 @@ async fn get_api_children(
|
||||
let mut res = Vec::new();
|
||||
for link in get_child_links(&path, rpcenv).await? {
|
||||
let path = format!("{}/{}", path, link);
|
||||
let (path, _) = normalize_uri_path(&path)?;
|
||||
let (path, _) = normalize_path_with_components(&path)?;
|
||||
let mut cap = String::new();
|
||||
|
||||
if get_child_links(&path, rpcenv).await.is_ok() {
|
||||
|
@ -7,7 +7,7 @@ use nix::sys::stat::Mode;
|
||||
|
||||
use proxmox_sys::fs::{create_path, CreateOptions};
|
||||
|
||||
use proxmox_http::client::{RateLimit, RateLimiter, ShareableRateLimit};
|
||||
use proxmox_http::{RateLimit, RateLimiter, ShareableRateLimit};
|
||||
use proxmox_shared_memory::{check_subtype, initialize_subtype};
|
||||
use proxmox_shared_memory::{Init, SharedMemory, SharedMutex};
|
||||
|
||||
|
@ -8,7 +8,7 @@ use std::time::Instant;
|
||||
use anyhow::Error;
|
||||
use cidr::IpInet;
|
||||
|
||||
use proxmox_http::client::{RateLimiter, ShareableRateLimit};
|
||||
use proxmox_http::{RateLimiter, ShareableRateLimit};
|
||||
use proxmox_section_config::SectionConfigData;
|
||||
|
||||
use proxmox_time::{parse_daily_duration, DailyDuration, TmEditor};
|
||||
|
Loading…
x
Reference in New Issue
Block a user