diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..26c0223 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,30 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Logs** +- For the GUI version, you can find the logs at `~/.local/share/gpclient/gpclient.log` +- For the CLI version, copy the output of the `gpclient` command. + +**Environment:** + - OS: [e.g. Ubuntu 22.04] + - Desktop Environment: [e.g. GNOME or KDE] + - Output of `ps aux | grep 'gnome-keyring\|kwalletd5' | grep -v grep`: [Required for secure store error] + - Is remote SSH? [Yes/No] + +**Additional context** +Add any other context about the problem here. diff --git a/README.md b/README.md index 560f43a..e15c578 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ The GUI version is also available after you installed it. You can launch it from > [!Warning] > -> The client requires `openconnect >= 8.20`, please make sure you have it installed, you can check it with `openconnect --version`. +> The client requires `openconnect >= 8.20, pkexec, and gnome-keyring`, please make sure you have them installed. > Installing the client from PPA will automatically install the required version of `openconnect`. ### Debian/Ubuntu based distributions @@ -67,6 +67,7 @@ The GUI version is also available after you installed it. You can launch it from #### Install from PPA ``` +sudo apt-get install gir1.2-gtk-3.0 gir1.2-webkit2-4.0 sudo add-apt-repository ppa:yuezk/globalprotect-openconnect sudo apt-get update sudo apt-get install globalprotect-openconnect @@ -113,7 +114,7 @@ sudo dnf copr enable yuezk/globalprotect-openconnect sudo dnf install globalprotect-openconnect ``` -#### Install from OBS +#### Install from OBS (OpenSUSE Build Service) The package is also available on [OBS](https://build.opensuse.org/package/show/home:yuezk/globalprotect-openconnect) for various RPM-based distributions. You can follow the instructions [on this page](https://software.opensuse.org//download.html?project=home%3Ayuezk&package=globalprotect-openconnect) to install it. @@ -123,7 +124,20 @@ Download the latest RPM package from [releases](https://github.com/yuezk/GlobalP ### Other distributions -The project depends on `openconnect >= 8.20`, `webkit2gtk`, `libsecret`, `libayatana-appindicator` or `libappindicator-gtk3`. You can install them first and then download the latest binary release (i.e., `*.bin.tar.gz`) from [releases](https://github.com/yuezk/GlobalProtect-openconnect/releases) page. +- Install `openconnect >= 8.20`, `webkit2gtk`, `libsecret`, `libayatana-appindicator` or `libappindicator-gtk3`. +- Download `globalprotect-openconnect.tar.gz` from [releases](https://github.com/yuezk/GlobalProtect-openconnect/releases) page. +- Extract the tarball and run `make build` to build the client. +- Run `make install` to install the client. + +## FAQ + +1. How to deal with error `Secure Storage not ready` + + You need to install the `gnome-keyring` package, and restart the system (See [#321](https://github.com/yuezk/GlobalProtect-openconnect/issues/321), [#316](https://github.com/yuezk/GlobalProtect-openconnect/issues/316)). + +2. How to deal with error `(gpauth:18869): Gtk-WARNING **: 10:33:37.566: cannot open display:` + + If you encounter this error when using the CLI version, try to run the command with `sudo -E` (See [#316](https://github.com/yuezk/GlobalProtect-openconnect/issues/316)). ## About Trial diff --git a/apps/gpauth/src/auth_window.rs b/apps/gpauth/src/auth_window.rs index 11c4230..a97be24 100644 --- a/apps/gpauth/src/auth_window.rs +++ b/apps/gpauth/src/auth_window.rs @@ -413,7 +413,19 @@ fn read_auth_data(main_resource: &WebResource, auth_result_tx: mpsc::UnboundedSe } Err(AuthDataError::NotFound) => { info!("No auth data found in headers, trying to read from body..."); + let url = main_resource.uri().unwrap_or("".into()); + let is_acs_endpoint = url.contains("/SAML20/SP/ACS"); + read_auth_data_from_body(main_resource, move |auth_result| { + // If the endpoint is `/SAML20/SP/ACS` and no auth data found in body, it should be considered as invalid + let auth_result = auth_result.map_err(|err| { + if matches!(err, AuthDataError::NotFound) && is_acs_endpoint { + AuthDataError::Invalid + } else { + err + } + }); + send_auth_result(&auth_result_tx, auth_result) }); } diff --git a/apps/gpclient/src/connect.rs b/apps/gpclient/src/connect.rs index 5ed0792..309708a 100644 --- a/apps/gpclient/src/connect.rs +++ b/apps/gpclient/src/connect.rs @@ -37,6 +37,9 @@ pub(crate) struct ConnectArgs { #[arg(long, help = "Same as the '--csd-wrapper' option in the openconnect command")] csd_wrapper: Option, + #[arg(short, long, help = "Request MTU from server (legacy servers only)")] + mtu: Option, + #[arg(long, default_value = GP_USER_AGENT, help = "The user agent to use")] user_agent: String, #[arg(long, default_value = "Linux")] @@ -152,12 +155,14 @@ impl<'a> ConnectHandler<'a> { async fn connect_gateway(&self, gateway: &str, cookie: &str) -> anyhow::Result<()> { let csd_uid = get_csd_uid(&self.args.csd_user)?; + let mtu = self.args.mtu.unwrap_or(0); let vpn = Vpn::builder(gateway, cookie) .user_agent(self.args.user_agent.clone()) .script(self.args.script.clone()) .csd_uid(csd_uid) .csd_wrapper(self.args.csd_wrapper.clone()) + .mtu(mtu) .build(); let vpn = Arc::new(vpn); diff --git a/apps/gpservice/src/vpn_task.rs b/apps/gpservice/src/vpn_task.rs index ad19e47..62ab5ec 100644 --- a/apps/gpservice/src/vpn_task.rs +++ b/apps/gpservice/src/vpn_task.rs @@ -39,6 +39,7 @@ impl VpnTaskContext { .script(args.vpnc_script()) .csd_uid(args.csd_uid()) .csd_wrapper(args.csd_wrapper()) + .mtu(args.mtu()) .os(args.openconnect_os()) .build(); diff --git a/crates/gpapi/src/service/request.rs b/crates/gpapi/src/service/request.rs index 12e6308..57f37ee 100644 --- a/crates/gpapi/src/service/request.rs +++ b/crates/gpapi/src/service/request.rs @@ -34,6 +34,7 @@ pub struct ConnectArgs { user_agent: Option, csd_uid: u32, csd_wrapper: Option, + mtu: u32, os: Option, } @@ -46,6 +47,7 @@ impl ConnectArgs { os: None, csd_uid: 0, csd_wrapper: None, + mtu: 0, } } @@ -72,6 +74,10 @@ impl ConnectArgs { pub fn csd_wrapper(&self) -> Option { self.csd_wrapper.clone() } + + pub fn mtu(&self) -> u32 { + self.mtu + } } #[derive(Debug, Deserialize, Serialize, Type)] @@ -103,6 +109,11 @@ impl ConnectRequest { self } + pub fn with_mtu(mut self, mtu: u32) -> Self { + self.args.mtu = mtu; + self + } + pub fn with_user_agent>>(mut self, user_agent: T) -> Self { self.args.user_agent = user_agent.into(); self diff --git a/crates/openconnect/src/ffi/mod.rs b/crates/openconnect/src/ffi/mod.rs index 0d5d21e..aa5a4a3 100644 --- a/crates/openconnect/src/ffi/mod.rs +++ b/crates/openconnect/src/ffi/mod.rs @@ -18,6 +18,8 @@ pub(crate) struct ConnectOptions { pub csd_uid: u32, pub csd_wrapper: *const c_char, + + pub mtu: u32, } #[link(name = "vpn")] diff --git a/crates/openconnect/src/ffi/vpn.c b/crates/openconnect/src/ffi/vpn.c index f4e6423..e1f6c69 100644 --- a/crates/openconnect/src/ffi/vpn.c +++ b/crates/openconnect/src/ffi/vpn.c @@ -63,6 +63,7 @@ int vpn_connect(const vpn_options *options, vpn_connected_callback callback) INFO("OS: %s", options->os); INFO("CSD_USER: %d", options->csd_uid); INFO("CSD_WRAPPER: %s", options->csd_wrapper); + INFO("MTU: %d", options->mtu); vpninfo = openconnect_vpninfo_new(options->user_agent, validate_peer_cert, NULL, NULL, print_progress, NULL); @@ -97,6 +98,11 @@ int vpn_connect(const vpn_options *options, vpn_connected_callback callback) openconnect_setup_csd(vpninfo, options->csd_uid, 1, options->csd_wrapper); } + if (options->mtu > 0) { + int mtu = options->mtu < 576 ? 576 : options->mtu; + openconnect_set_reqmtu(vpninfo, mtu); + } + g_cmd_pipe_fd = openconnect_setup_cmd_pipe(vpninfo); if (g_cmd_pipe_fd < 0) { diff --git a/crates/openconnect/src/ffi/vpn.h b/crates/openconnect/src/ffi/vpn.h index e304ab5..58c52f0 100644 --- a/crates/openconnect/src/ffi/vpn.h +++ b/crates/openconnect/src/ffi/vpn.h @@ -19,6 +19,8 @@ typedef struct vpn_options const uid_t csd_uid; const char *csd_wrapper; + + const int mtu; } vpn_options; int vpn_connect(const vpn_options *options, vpn_connected_callback callback); diff --git a/crates/openconnect/src/vpn.rs b/crates/openconnect/src/vpn.rs index f41d1e0..cde0017 100644 --- a/crates/openconnect/src/vpn.rs +++ b/crates/openconnect/src/vpn.rs @@ -21,6 +21,8 @@ pub struct Vpn { csd_uid: u32, csd_wrapper: Option, + mtu: u32, + callback: OnConnectedCallback, } @@ -62,6 +64,8 @@ impl Vpn { csd_uid: self.csd_uid, csd_wrapper: Self::option_to_ptr(&self.csd_wrapper), + + mtu: self.mtu, } } @@ -82,6 +86,8 @@ pub struct VpnBuilder { csd_uid: u32, csd_wrapper: Option, + + mtu: u32, } impl VpnBuilder { @@ -94,6 +100,7 @@ impl VpnBuilder { os: None, csd_uid: 0, csd_wrapper: None, + mtu: 0, } } @@ -122,6 +129,11 @@ impl VpnBuilder { self } + pub fn mtu(mut self, mtu: u32) -> Self { + self.mtu = mtu; + self + } + pub fn build(self) -> Vpn { let user_agent = self.user_agent.unwrap_or_default(); let script = self.script.or_else(find_default_vpnc_script).unwrap_or_default(); @@ -139,6 +151,8 @@ impl VpnBuilder { csd_uid: self.csd_uid, csd_wrapper: self.csd_wrapper.as_deref().map(Self::to_cstring), + mtu: self.mtu, + callback: Default::default(), } }