Skip to content

Commit 763f2dd

Browse files
committed
feat: add HIP report generation functionality and related dependencies
1 parent f398cca commit 763f2dd

38 files changed

+2106
-772
lines changed

Cargo.lock

Lines changed: 305 additions & 146 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ license = "GPL-3.0"
1919

2020
[workspace.dependencies]
2121
anyhow = "1.0"
22+
askama = "0.14"
2223
base64 = "0.22"
24+
chrono = "0.4"
2325
clap = { version = "4", features = ["derive"] }
2426
clap-verbosity-flag = "3"
2527
ctrlc = "3.4"
@@ -32,7 +34,7 @@ regex = "1"
3234
reqwest = { version = "0.12", features = ["native-tls", "json"] }
3335
openssl = "0.10"
3436
pem = "3"
35-
roxmltree = "0.21"
37+
xmltree = "0.12"
3638
serde = { version = "1.0", features = ["derive"] }
3739
serde_json = "1.0"
3840
# Use 0.36 as newer versions requires Rust 1.88+
@@ -54,6 +56,9 @@ serde_urlencoded = "0.7"
5456
md5 = "0.8"
5557
sha256 = "1"
5658
which = "8"
59+
uuid = "1"
60+
netdev = "0.39"
61+
machine-uid = "0.5"
5762

5863
# Tauri dependencies
5964
tauri = { version = "2" }

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ install:
136136
install -Dm755 .build/gpgui/gpgui_*/gpgui $(DESTDIR)/usr/bin/gpgui; \
137137
fi
138138

139+
# Install the HIP report script
140+
install -Dm755 packaging/files/usr/libexec/gpclient/hipreport.sh $(DESTDIR)/usr/libexec/gpclient/hipreport.sh
141+
139142
# Install the disconnect hooks
140143
install -Dm755 packaging/files/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down
141144
install -Dm755 packaging/files/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook
@@ -156,6 +159,8 @@ uninstall:
156159
rm -f $(DESTDIR)/usr/bin/gpgui-helper
157160
rm -f $(DESTDIR)/usr/bin/gpgui
158161

162+
rm -f $(DESTDIR)/usr/libexec/gpclient/hipreport.sh
163+
159164
rm -f $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down
160165
rm -f $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook
161166

apps/gpclient/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,23 @@ gpapi = { path = "../../crates/gpapi", features = ["clap"] }
1212
openconnect = { path = "../../crates/openconnect" }
1313

1414
anyhow.workspace = true
15+
askama.workspace = true
16+
chrono.workspace = true
1517
clap.workspace = true
1618
env_logger.workspace = true
1719
inquire = "0.9"
1820
log.workspace = true
1921
tokio = { workspace = true, features = ["rt-multi-thread"] }
2022
sysinfo.workspace = true
2123
serde_json.workspace = true
24+
serde_urlencoded.workspace = true
2225
whoami.workspace = true
2326
tempfile.workspace = true
2427
reqwest.workspace = true
2528
directories.workspace = true
2629
compile-time.workspace = true
30+
netdev.workspace = true
31+
xmltree.workspace = true
2732

2833
[features]
2934
default = ["webview-auth"]

apps/gpclient/src/cli.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{env::temp_dir, fs::File, str::FromStr};
33
use anyhow::bail;
44
use clap::{Parser, Subcommand};
55
use gpapi::{
6-
clap::{handle_error, Args, InfoLevelVerbosity},
6+
clap::{Args, InfoLevelVerbosity, handle_error},
77
utils::openssl,
88
};
99
use log::info;
@@ -12,10 +12,11 @@ use tempfile::NamedTempFile;
1212
use tokio::fs;
1313

1414
use crate::{
15+
GP_CLIENT_LOCK_FILE,
1516
connect::{ConnectArgs, ConnectHandler},
1617
disconnect::{DisconnectArgs, DisconnectHandler},
18+
hip::{HipArgs, HipHandler},
1719
launch_gui::{LaunchGuiArgs, LaunchGuiHandler},
18-
GP_CLIENT_LOCK_FILE,
1920
};
2021

2122
const VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), " (", compile_time::date_str!(), ")");
@@ -34,6 +35,8 @@ enum CliCommand {
3435
Disconnect(DisconnectArgs),
3536
#[command(about = "Launch the GUI")]
3637
LaunchGui(LaunchGuiArgs),
38+
#[command(about = "Generate HIP report")]
39+
Hip(HipArgs),
3740
}
3841

3942
#[derive(Parser)]
@@ -132,6 +135,7 @@ impl Cli {
132135
CliCommand::Connect(args) => ConnectHandler::new(args, &shared_args).handle().await,
133136
CliCommand::Disconnect(args) => DisconnectHandler::new(args).handle().await,
134137
CliCommand::LaunchGui(args) => LaunchGuiHandler::new(args).handle().await,
138+
CliCommand::Hip(args) => HipHandler::new(args).handle().await,
135139
}
136140
}
137141
}

apps/gpclient/src/connect.rs

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use std::{cell::RefCell, fs, sync::Arc};
1+
use std::{borrow::Cow, cell::RefCell, fs, sync::Arc};
22

33
use anyhow::bail;
44
use clap::Args;
5-
use common::constants::GP_USER_AGENT;
5+
use common::constants::{GP_CLIENT_VERSION, GP_USER_AGENT};
66
use gpapi::{
77
auth::SamlAuthResult,
88
clap::{ToVerboseArg, args::Os},
@@ -15,7 +15,7 @@ use gpapi::{
1515
auth_launcher::SamlAuthLauncher,
1616
users::{get_non_root_user, get_user_by_name},
1717
},
18-
utils::{request::RequestIdentityError, shutdown_signal},
18+
utils::{host_utils, request::RequestIdentityError, shutdown_signal},
1919
};
2020
use inquire::{Password, PasswordDisplayMode, Select, Text};
2121
use log::{info, warn};
@@ -86,8 +86,11 @@ pub(crate) struct ConnectArgs {
8686
#[arg(long, help = "Do not ask for IPv6 connectivity")]
8787
disable_ipv6: bool,
8888

89-
#[arg(long, default_value = GP_USER_AGENT, help = "The user agent to use")]
90-
user_agent: String,
89+
#[arg(
90+
long,
91+
help = "The user agent to use, if not specified, it will be generated based on the OS and client version"
92+
)]
93+
user_agent: Option<String>,
9194

9295
#[arg(long, value_enum, default_value_t = ConnectArgs::default_os())]
9396
os: Os,
@@ -130,18 +133,29 @@ pub(crate) struct ConnectArgs {
130133

131134
impl ConnectArgs {
132135
fn default_os() -> Os {
133-
if cfg!(target_os = "macos") { Os::Mac } else { Os::Linux }
136+
#[cfg(target_os = "macos")]
137+
{
138+
Os::Mac
139+
}
140+
#[cfg(target_os = "windows")]
141+
{
142+
Os::Windows
143+
}
144+
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
145+
{
146+
Os::Linux
147+
}
134148
}
135149

136-
fn os_version(&self) -> String {
150+
fn os_version(&self) -> &str {
137151
if let Some(os_version) = self.os_version.as_deref() {
138-
return os_version.to_string();
152+
return os_version;
139153
}
140154

141155
match self.os {
142-
Os::Linux => format!("Linux {}", whoami::distro()),
143-
Os::Windows => String::from("Microsoft Windows 11 Pro , 64-bit"),
144-
Os::Mac => String::from("Apple Mac OS X 13.4.0"),
156+
Os::Linux => host_utils::get_linux_os_string(),
157+
Os::Windows => host_utils::get_windows_os_string(),
158+
Os::Mac => host_utils::get_macos_os_string(),
145159
}
146160
}
147161
}
@@ -163,11 +177,25 @@ impl<'a> ConnectHandler<'a> {
163177
}
164178
}
165179

180+
fn user_agent(&self) -> Cow<'_, str> {
181+
if let Some(user_agent) = self.args.user_agent.as_deref() {
182+
Cow::Borrowed(user_agent)
183+
} else {
184+
let client_version = self.args.client_version.as_deref().unwrap_or(GP_CLIENT_VERSION);
185+
Cow::Owned(format!(
186+
"{}/{} ({})",
187+
GP_USER_AGENT,
188+
client_version,
189+
self.args.os_version()
190+
))
191+
}
192+
}
193+
166194
fn build_gp_params(&self) -> GpParams {
167195
GpParams::builder()
168-
.user_agent(&self.args.user_agent)
196+
.user_agent(&self.user_agent())
169197
.client_os(ClientOs::from(&self.args.os))
170-
.os_version(self.args.os_version())
198+
.os_version(self.args.os_version().to_owned())
171199
.ignore_tls_errors(self.shared_args.ignore_tls_errors)
172200
.certificate(self.args.certificate.clone())
173201
.sslkey(self.args.sslkey.clone())
@@ -331,14 +359,16 @@ impl<'a> ConnectHandler<'a> {
331359
(false, None)
332360
};
333361

334-
let os = ClientOs::from(&self.args.os).to_openconnect_os().to_string();
362+
let os = ClientOs::from(&self.args.os).to_openconnect_os().to_owned();
363+
let os_version = self.args.os_version().to_owned();
335364
let client_version = client_version.map(|s| s.to_owned());
336365
let vpn = Vpn::builder(gateway, cookie)
337366
.script(self.args.script.clone())
338367
.interface(self.args.interface.clone())
339368
.script_tun(self.args.script_tun)
340-
.user_agent(self.args.user_agent.clone())
369+
.user_agent(self.user_agent().into_owned())
341370
.os(Some(os))
371+
.os_version(Some(os_version))
342372
.client_version(client_version)
343373
.certificate(self.args.certificate.clone())
344374
.sslkey(self.args.sslkey.clone())
@@ -394,10 +424,11 @@ impl<'a> ConnectHandler<'a> {
394424

395425
let os_version = self.args.os_version();
396426
let verbose = self.shared_args.verbose.to_verbose_arg();
427+
let user_agent = self.user_agent();
397428
let auth_launcher = SamlAuthLauncher::new(&self.args.server)
398429
.gateway(is_gateway)
399430
.saml_request(prelogin.saml_request())
400-
.user_agent(&self.args.user_agent)
431+
.user_agent(&user_agent)
401432
.os(self.args.os.as_str())
402433
.os_version(Some(&os_version))
403434
.fix_openssl(self.shared_args.fix_openssl)

0 commit comments

Comments
 (0)