This commit is contained in:
Aiden McClelland
2025-10-30 13:37:52 -06:00
parent 5340c421e1
commit df27c0c629
9 changed files with 48 additions and 39 deletions

View File

@@ -156,7 +156,7 @@ results/$(REGISTRY_BASENAME).deb: dpkg-build.sh $(call ls-files,debian/start-reg
tunnel-deb: results/$(TUNNEL_BASENAME).deb tunnel-deb: results/$(TUNNEL_BASENAME).deb
results/$(TUNNEL_BASENAME).deb: dpkg-build.sh $(call ls-files,debian/start-tunnel) $(TUNNEL_TARGETS) results/$(TUNNEL_BASENAME).deb: dpkg-build.sh $(call ls-files,debian/start-tunnel) $(TUNNEL_TARGETS)
PROJECT=start-tunnel PLATFORM=$(ARCH) REQUIRES=debian DEPENDS=wireguard-tools,iptables,network-manager,augeas-tools ./build/os-compat/run-compat.sh ./dpkg-build.sh PROJECT=start-tunnel PLATFORM=$(ARCH) REQUIRES=debian DEPENDS=wireguard-tools,iptables ./build/os-compat/run-compat.sh ./dpkg-build.sh
$(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE) $(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE)

View File

@@ -234,23 +234,28 @@ impl CliContext {
&self, &self,
method: &str, method: &str,
params: Value, params: Value,
) -> Result<Value, RpcError> ) -> Result<Value, Error>
where where
Self: CallRemote<RemoteContext>, Self: CallRemote<RemoteContext>,
{ {
<Self as CallRemote<RemoteContext, Empty>>::call_remote(&self, method, params, Empty {}) <Self as CallRemote<RemoteContext, Empty>>::call_remote(&self, method, params, Empty {})
.await .await
.map_err(Error::from)
.with_ctx(|e| (e.kind, method))
} }
pub async fn call_remote_with<RemoteContext, T>( pub async fn call_remote_with<RemoteContext, T>(
&self, &self,
method: &str, method: &str,
params: Value, params: Value,
extra: T, extra: T,
) -> Result<Value, RpcError> ) -> Result<Value, Error>
where where
Self: CallRemote<RemoteContext, T>, Self: CallRemote<RemoteContext, T>,
{ {
<Self as CallRemote<RemoteContext, T>>::call_remote(&self, method, params, extra).await <Self as CallRemote<RemoteContext, T>>::call_remote(&self, method, params, extra)
.await
.map_err(Error::from)
.with_ctx(|e| (e.kind, method))
} }
} }
impl AsRef<Jwk> for CliContext { impl AsRef<Jwk> for CliContext {

View File

@@ -21,12 +21,12 @@ use http::header::{
use http::request::Parts as RequestParts; use http::request::Parts as RequestParts;
use http::{HeaderValue, Method, StatusCode}; use http::{HeaderValue, Method, StatusCode};
use imbl_value::InternedString; use imbl_value::InternedString;
use include_dir::{Dir, include_dir}; use include_dir::Dir;
use models::PackageId; use models::PackageId;
use new_mime_guess::MimeGuess; use new_mime_guess::MimeGuess;
use openssl::hash::MessageDigest; use openssl::hash::MessageDigest;
use openssl::x509::X509; use openssl::x509::X509;
use rpc_toolkit::{Context, HttpServer, Server}; use rpc_toolkit::{Context, HttpServer, ParentHandler, Server};
use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeekExt, BufReader}; use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeekExt, BufReader};
use tokio_util::io::ReaderStream; use tokio_util::io::ReaderStream;
use url::Url; use url::Url;
@@ -80,6 +80,7 @@ const EMBEDDED_UI_ROOT: Dir<'_> = else_empty_dir!(
pub trait UiContext: Context + AsRef<RpcContinuations> + Clone + Sized { pub trait UiContext: Context + AsRef<RpcContinuations> + Clone + Sized {
const UI_DIR: &'static Dir<'static>; const UI_DIR: &'static Dir<'static>;
fn api() -> ParentHandler<Self>;
fn middleware(server: Server<Self>) -> HttpServer<Self>; fn middleware(server: Server<Self>) -> HttpServer<Self>;
fn extend_router(self, router: Router) -> Router { fn extend_router(self, router: Router) -> Router {
router router
@@ -91,7 +92,9 @@ impl UiContext for RpcContext {
feature = "startd" => feature = "startd" =>
include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/ui") include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/ui")
); );
fn api() -> ParentHandler<Self> {
main_api()
}
fn middleware(server: Server<Self>) -> HttpServer<Self> { fn middleware(server: Server<Self>) -> HttpServer<Self> {
server server
.middleware(Cors::new()) .middleware(Cors::new())
@@ -155,7 +158,9 @@ impl UiContext for InitContext {
feature = "startd" => feature = "startd" =>
include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/ui") include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/ui")
); );
fn api() -> ParentHandler<Self> {
main_api()
}
fn middleware(server: Server<Self>) -> HttpServer<Self> { fn middleware(server: Server<Self>) -> HttpServer<Self> {
server.middleware(Cors::new()) server.middleware(Cors::new())
} }
@@ -166,7 +171,9 @@ impl UiContext for DiagnosticContext {
feature = "startd" => feature = "startd" =>
include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/ui") include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/ui")
); );
fn api() -> ParentHandler<Self> {
main_api()
}
fn middleware(server: Server<Self>) -> HttpServer<Self> { fn middleware(server: Server<Self>) -> HttpServer<Self> {
server.middleware(Cors::new()) server.middleware(Cors::new())
} }
@@ -177,7 +184,9 @@ impl UiContext for SetupContext {
feature = "startd" => feature = "startd" =>
include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/setup-wizard") include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/setup-wizard")
); );
fn api() -> ParentHandler<Self> {
main_api()
}
fn middleware(server: Server<Self>) -> HttpServer<Self> { fn middleware(server: Server<Self>) -> HttpServer<Self> {
server.middleware(Cors::new()) server.middleware(Cors::new())
} }
@@ -188,7 +197,9 @@ impl UiContext for InstallContext {
feature = "startd" => feature = "startd" =>
include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/install-wizard") include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/install-wizard")
); );
fn api() -> ParentHandler<Self> {
main_api()
}
fn middleware(server: Server<Self>) -> HttpServer<Self> { fn middleware(server: Server<Self>) -> HttpServer<Self> {
server.middleware(Cors::new()) server.middleware(Cors::new())
} }
@@ -256,7 +267,7 @@ pub fn ui_router<C: UiContext>(ctx: C) -> Router {
ctx.clone() ctx.clone()
.extend_router(rpc_router( .extend_router(rpc_router(
ctx.clone(), ctx.clone(),
C::middleware(Server::new(move || ready(Ok(ctx.clone())), main_api())), C::middleware(Server::new(move || ready(Ok(ctx.clone())), C::api())),
)) ))
.fallback(any(|request: Request| async move { .fallback(any(|request: Request| async move {
serve_ui::<C>(request).unwrap_or_else(server_error) serve_ui::<C>(request).unwrap_or_else(server_error)

View File

@@ -251,8 +251,8 @@ pub async fn set_password_cli(
.. ..
}: HandlerArgs<CliContext>, }: HandlerArgs<CliContext>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let password = rpassword::prompt_password("New Password")?; let password = rpassword::prompt_password("New Password: ")?;
let confirm = rpassword::prompt_password("Confirm Password")?; let confirm = rpassword::prompt_password("Confirm Password: ")?;
if password != confirm { if password != confirm {
return Err(Error::new( return Err(Error::new(

View File

@@ -13,7 +13,7 @@ use include_dir::Dir;
use models::GatewayId; use models::GatewayId;
use patch_db::PatchDb; use patch_db::PatchDb;
use rpc_toolkit::yajrc::RpcError; use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{CallRemote, Context, Empty}; use rpc_toolkit::{CallRemote, Context, Empty, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::process::Command; use tokio::process::Command;
use tokio::sync::broadcast::Sender; use tokio::sync::broadcast::Sender;
@@ -33,6 +33,7 @@ use crate::net::static_server::UiContext;
use crate::prelude::*; use crate::prelude::*;
use crate::rpc_continuations::{OpenAuthedContinuations, RpcContinuations}; use crate::rpc_continuations::{OpenAuthedContinuations, RpcContinuations};
use crate::tunnel::TUNNEL_DEFAULT_LISTEN; use crate::tunnel::TUNNEL_DEFAULT_LISTEN;
use crate::tunnel::api::tunnel_api;
use crate::tunnel::db::{GatewayPort, TunnelDatabase}; use crate::tunnel::db::{GatewayPort, TunnelDatabase};
use crate::tunnel::wg::WIREGUARD_INTERFACE_NAME; use crate::tunnel::wg::WIREGUARD_INTERFACE_NAME;
use crate::util::Invoke; use crate::util::Invoke;
@@ -311,7 +312,10 @@ impl UiContext for TunnelContext {
feature = "tunnel" => feature = "tunnel" =>
include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/start-tunnel") include_dir::include_dir!("$CARGO_MANIFEST_DIR/../../web/dist/static/start-tunnel")
); );
fn api() -> ParentHandler<Self> {
tracing::info!("loading tunnel api...");
tunnel_api()
}
fn middleware(server: rpc_toolkit::Server<Self>) -> rpc_toolkit::HttpServer<Self> { fn middleware(server: rpc_toolkit::Server<Self>) -> rpc_toolkit::HttpServer<Self> {
server.middleware(Cors::new()).middleware(Auth::new()) server.middleware(Cors::new()).middleware(Auth::new())
} }

View File

@@ -313,10 +313,10 @@ pub async fn get_available_ips(ctx: TunnelContext) -> Result<Vec<IpAddr>, Error>
let ips = ctx.net_iface.peek(|interfaces| { let ips = ctx.net_iface.peek(|interfaces| {
interfaces interfaces
.values() .values()
.filter_map(|info| { .flat_map(|info| {
info.ip_info info.ip_info
.as_ref() .iter()
.and_then(|ip_info| ip_info.subnets.iter().next().map(|subnet| subnet.addr())) .flat_map(|ip_info| ip_info.subnets.iter().map(|subnet| subnet.addr()))
}) })
.collect::<Vec<IpAddr>>() .collect::<Vec<IpAddr>>()
}); });
@@ -377,8 +377,11 @@ pub async fn init_web(ctx: CliContext) -> Result<(), Error> {
.call_remote::<TunnelContext>("web.enable", json!({})) .call_remote::<TunnelContext>("web.enable", json!({}))
.await .await
{ {
Ok(_) => println!("Webserver Initialized"), Ok(_) => {
Err(e) if e.code == ErrorKind::ParseNetAddress as i32 => { println!("Webserver Initialized");
return Ok(());
}
Err(e) if e.kind == ErrorKind::ParseNetAddress => {
println!("A listen address has not been set yet. Setting one up now..."); println!("A listen address has not been set yet. Setting one up now...");
let available_ips = from_value::<Vec<IpAddr>>( let available_ips = from_value::<Vec<IpAddr>>(
@@ -431,7 +434,7 @@ pub async fn init_web(ctx: CliContext) -> Result<(), Error> {
) )
.await?; .await?;
} }
Err(e) if e.code == ErrorKind::OpenSsl as i32 => { Err(e) if e.kind == ErrorKind::OpenSsl => {
println!( println!(
"StartTunnel has not been set up with an SSL Certificate yet. Setting one up now..." "StartTunnel has not been set up with an SSL Certificate yet. Setting one up now..."
); );
@@ -526,7 +529,7 @@ pub async fn init_web(ctx: CliContext) -> Result<(), Error> {
.await?; .await?;
} }
} }
Err(e) if e.code == ErrorKind::Authorization as i32 => { Err(e) if e.kind == ErrorKind::Authorization => {
println!("A password has not been setup yet. Setting one up now..."); println!("A password has not been setup yet. Setting one up now...");
super::auth::set_password_cli(HandlerArgs { super::auth::set_password_cli(HandlerArgs {

View File

@@ -6,12 +6,4 @@ if [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ]; then
SYSTEMCTL=deb-systemd-helper SYSTEMCTL=deb-systemd-helper
fi fi
augtool << EOI
set /augeas/load/Ini/lens IniFile.lns_loose
set /augeas/load/Ini/incl /etc/NetworkManager/NetworkManager.conf
load
set /files/etc/NetworkManager/NetworkManager.conf/section[.="ifupdown"]/managed true
save
EOI
$SYSTEMCTL enable start-tunneld.service $SYSTEMCTL enable start-tunneld.service

View File

@@ -1,9 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AnyVerifyingKey } from "./AnyVerifyingKey"
import type { ContactInfo } from "./ContactInfo"
export type SignerInfo = { export type SignerInfo = { name: string }
name: string
contact: Array<ContactInfo>
keys: Array<AnyVerifyingKey>
}

View File

@@ -378,7 +378,7 @@
{ {
"type": "initial", "type": "initial",
"maximumWarning": "500kB", "maximumWarning": "500kB",
"maximumError": "1MB" "maximumError": "5MB"
}, },
{ {
"type": "anyComponentStyle", "type": "anyComponentStyle",