Compare commits

...

4 Commits

Author SHA1 Message Date
Kevin Yue
f482bd077b Release 2.3.3 2024-06-23 21:42:55 +08:00
Kevin Yue
148468eee3 Release 2.3.2 2024-06-17 20:54:04 +08:00
Kevin Yue
79083e5664 feat: Remove dotenvy_macro crate from dependencies 2024-06-15 10:58:36 +08:00
Kevin Yue
c52d2bc0b6 fix: Decode CAS callback before parsing
Related: #372
2024-06-13 14:34:58 +00:00
10 changed files with 137 additions and 58 deletions

View File

@@ -168,22 +168,23 @@ jobs:
steps:
- name: Prepare workspace
run: rm -rf gh-release && mkdir gh-release
- name: Checkout GlobalProtect-openconnect
uses: actions/checkout@v3
with:
token: ${{ secrets.GH_PAT }}
repository: yuezk/GlobalProtect-openconnect
ref: ${{ github.ref }}
path: gh-release/gp
- name: Download all artifacts
uses: actions/download-artifact@v3
with:
path: gh-release
path: gh-release/gp/.build/artifacts
- name: Create GH release
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
RELEASE_TAG: ${{ github.ref == 'refs/heads/dev' && 'snapshot' || github.ref_name }}
REPO: ${{ github.repository }}
NOTES: ${{ github.ref == 'refs/heads/dev' && '**!!! DO NOT USE THIS RELEASE IN PRODUCTION !!!**' || format('Release {0}', github.ref_name) }}
run: |
gh -R "$REPO" release delete $RELEASE_TAG --yes --cleanup-tag || true
gh -R "$REPO" release create $RELEASE_TAG \
--title "$RELEASE_TAG" \
--notes "$NOTES" \
${{ github.ref == 'refs/heads/dev' && '--target dev' || '' }} \
${{ github.ref == 'refs/heads/dev' && '--prerelease' || '' }} \
gh-release/artifact-source/* \
gh-release/artifact-gpgui-*/*
cd gh-release/gp/scripts && ./gh-release.sh "$RELEASE_TAG"

33
Cargo.lock generated
View File

@@ -570,7 +570,7 @@ dependencies = [
[[package]]
name = "common"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"is_executable",
]
@@ -898,24 +898,6 @@ dependencies = [
"litrs",
]
[[package]]
name = "dotenvy"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "dotenvy_macro"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0235d912a8c749f4e0c9f18ca253b4c28cfefc1d2518096016d6e3230b6424"
dependencies = [
"dotenvy",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "dtoa"
version = "1.0.9"
@@ -1436,13 +1418,12 @@ dependencies = [
[[package]]
name = "gpapi"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"anyhow",
"base64 0.21.5",
"chacha20poly1305",
"clap",
"dotenvy_macro",
"log",
"md5",
"open",
@@ -1470,7 +1451,7 @@ dependencies = [
[[package]]
name = "gpauth"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"anyhow",
"clap",
@@ -1491,7 +1472,7 @@ dependencies = [
[[package]]
name = "gpclient"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"anyhow",
"clap",
@@ -1513,7 +1494,7 @@ dependencies = [
[[package]]
name = "gpgui-helper"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"anyhow",
"clap",
@@ -1531,7 +1512,7 @@ dependencies = [
[[package]]
name = "gpservice"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"anyhow",
"axum",
@@ -2545,7 +2526,7 @@ dependencies = [
[[package]]
name = "openconnect"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"cc",
"common",

View File

@@ -5,7 +5,7 @@ members = ["crates/*", "apps/gpclient", "apps/gpservice", "apps/gpauth", "apps/g
[workspace.package]
rust-version = "1.70"
version = "2.3.1"
version = "2.3.3"
authors = ["Kevin Yue <k3vinyue@gmail.com>"]
homepage = "https://github.com/yuezk/GlobalProtect-openconnect"
edition = "2021"
@@ -41,7 +41,6 @@ uzers = "0.11"
whoami = "1"
thiserror = "1"
redact-engine = "0.1"
dotenvy_macro = "0.15"
compile-time = "0.2"
serde_urlencoded = "0.7"
md5="0.7"

View File

@@ -19,7 +19,7 @@ pub(crate) struct SharedArgs {
#[derive(Subcommand)]
enum CliCommand {
#[command(about = "Connect to a portal server")]
Connect(ConnectArgs),
Connect(Box<ConnectArgs>),
#[command(about = "Disconnect from the server")]
Disconnect,
#[command(about = "Launch the GUI")]

View File

@@ -1,5 +1,17 @@
# Changelog
## 2.3.3 - 2024-06-23
- GUI: add the remark field for the license activation
- GUI: check the saved secret key length
## 2.3.2 - 2024-06-17
- Fix the CAS callback parsing issue (fix [#372](https://github.com/yuezk/GlobalProtect-openconnect/issues/372))
- CLI: fix the `/tmp/gpauth.html` deletion issue (fix [#366](https://github.com/yuezk/GlobalProtect-openconnect/issues/366))
- GUI: fix the license not working after reboot (fix [#376](https://github.com/yuezk/GlobalProtect-openconnect/issues/376))
- GUI: add the license activation management link
## 2.3.1 - 2024-05-21
- Fix the `--sslkey` option not working

View File

@@ -25,7 +25,6 @@ chacha20poly1305 = { version = "0.10", features = ["std"] }
redact-engine.workspace = true
url.workspace = true
regex.workspace = true
dotenvy_macro.workspace = true
uzers.workspace = true
serde_urlencoded.workspace = true
md5.workspace = true

19
crates/gpapi/build.rs Normal file
View File

@@ -0,0 +1,19 @@
use std::path::Path;
fn main() {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let workspace_dir = Path::new(manifest_dir).ancestors().nth(2).unwrap();
let gpgui_dir = workspace_dir.parent().unwrap().join("gpgui");
let gp_service_binary = workspace_dir.join("target/debug/gpservice");
let gp_client_binary = workspace_dir.join("target/debug/gpclient");
let gp_auth_binary = workspace_dir.join("target/debug/gpauth");
let gp_gui_helper_binary = workspace_dir.join("target/debug/gpgui-helper");
let gp_gui_binary = gpgui_dir.join("target/debug/gpgui");
println!("cargo:rustc-env=GP_SERVICE_BINARY={}", gp_service_binary.display());
println!("cargo:rustc-env=GP_CLIENT_BINARY={}", gp_client_binary.display());
println!("cargo:rustc-env=GP_AUTH_BINARY={}", gp_auth_binary.display());
println!("cargo:rustc-env=GP_GUI_HELPER_BINARY={}", gp_gui_helper_binary.display());
println!("cargo:rustc-env=GP_GUI_BINARY={}", gp_gui_binary.display());
}

View File

@@ -1,3 +1,5 @@
use std::borrow::{Borrow, Cow};
use log::{info, warn};
use regex::Regex;
use serde::{Deserialize, Serialize};
@@ -68,24 +70,29 @@ impl SamlAuthData {
if auth_data.starts_with("cas-as") {
info!("Got CAS auth data from globalprotectcallback");
let auth_data: SamlAuthData = serde_urlencoded::from_str(auth_data).map_err(|e| {
// Decode the auth data and use the original value if decoding fails
let auth_data = urlencoding::decode(auth_data).unwrap_or_else(|err| {
warn!("Failed to decode token auth data: {}", err);
Cow::Borrowed(auth_data)
});
let auth_data: SamlAuthData = serde_urlencoded::from_str(auth_data.borrow()).map_err(|e| {
warn!("Failed to parse token auth data: {}", e);
warn!("Auth data: {}", auth_data);
AuthDataParseError::Invalid
})?;
Ok(auth_data)
} else {
info!("Parsing SAML auth data...");
let auth_data = decode_to_string(auth_data).map_err(|e| {
warn!("Failed to decode SAML auth data: {}", e);
AuthDataParseError::Invalid
})?;
let auth_data = Self::from_html(&auth_data)?;
Ok(auth_data)
return Ok(auth_data);
}
info!("Parsing SAML auth data...");
let auth_data = decode_to_string(auth_data).map_err(|e| {
warn!("Failed to decode SAML auth data: {}", e);
AuthDataParseError::Invalid
})?;
let auth_data = Self::from_html(&auth_data)?;
Ok(auth_data)
}
pub fn username(&self) -> &str {
@@ -143,6 +150,16 @@ mod tests {
assert_eq!(auth_data.token(), Some("very_long_string"));
}
#[test]
fn auth_data_from_gpcallback_cas_urlencoded() {
let auth_data = "globalprotectcallback:cas-as%3D1%26un%3Dxyz%40email.com%26token%3Dvery_long_string";
let auth_data = SamlAuthData::from_gpcallback(auth_data).unwrap();
assert_eq!(auth_data.username(), "xyz@email.com");
assert_eq!(auth_data.token(), Some("very_long_string"));
}
#[test]
fn auth_data_from_gpcallback_non_cas() {
let auth_data = "PGh0bWw+PCEtLSA8c2FtbC1hdXRoLXN0YXR1cz4xPC9zYW1sLWF1dGgtc3RhdHVzPjxwcmVsb2dpbi1jb29raWU+cHJlbG9naW4tY29va2llPC9wcmVsb2dpbi1jb29raWU+PHNhbWwtdXNlcm5hbWU+eHl6QGVtYWlsLmNvbTwvc2FtbC11c2VybmFtZT48c2FtbC1zbG8+bm88L3NhbWwtc2xvPjxzYW1sLVNlc3Npb25Ob3RPbk9yQWZ0ZXI+PC9zYW1sLVNlc3Npb25Ob3RPbk9yQWZ0ZXI+IC0tPjwvaHRtbD4=";

View File

@@ -29,12 +29,12 @@ pub const GP_GUI_HELPER_BINARY: &str = "/usr/bin/gpgui-helper";
pub(crate) const GP_AUTH_BINARY: &str = "/usr/bin/gpauth";
#[cfg(debug_assertions)]
pub const GP_CLIENT_BINARY: &str = dotenvy_macro::dotenv!("GP_CLIENT_BINARY");
pub const GP_CLIENT_BINARY: &str = env!("GP_CLIENT_BINARY");
#[cfg(debug_assertions)]
pub const GP_SERVICE_BINARY: &str = dotenvy_macro::dotenv!("GP_SERVICE_BINARY");
pub const GP_SERVICE_BINARY: &str = env!("GP_SERVICE_BINARY");
#[cfg(debug_assertions)]
pub const GP_GUI_BINARY: &str = dotenvy_macro::dotenv!("GP_GUI_BINARY");
pub const GP_GUI_BINARY: &str = env!("GP_GUI_BINARY");
#[cfg(debug_assertions)]
pub const GP_GUI_HELPER_BINARY: &str = dotenvy_macro::dotenv!("GP_GUI_HELPER_BINARY");
pub const GP_GUI_HELPER_BINARY: &str = env!("GP_GUI_HELPER_BINARY");
#[cfg(debug_assertions)]
pub(crate) const GP_AUTH_BINARY: &str = dotenvy_macro::dotenv!("GP_AUTH_BINARY");
pub(crate) const GP_AUTH_BINARY: &str = env!("GP_AUTH_BINARY");

51
scripts/gh-release.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/bash
# Usage: ./scripts/gh-release.sh <tag>
set -e
REPO="yuezk/GlobalProtect-openconnect"
TAG=$1
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
RELEASE_NOTES="Release $TAG"
if [ -z "$TAG" ]; then
echo "Usage: ./scripts/gh-release.sh <tag>"
exit 1
fi
# For snapshot release, we don't create a release, just clear the existing assets and upload new ones.
# This is to avoid notification spam.
release_snapshot() {
RELEASE_NOTES='**!!! DO NOT USE THIS RELEASE IN PRODUCTION !!!**'
# Get the existing assets
gh -R "$REPO" release view "$TAG" --json assets --jq '.assets[].name' \
| xargs -I {} gh -R "$REPO" release delete-asset "$TAG" {} --yes
echo "Uploading new assets..."
gh -R "$REPO" release upload "$TAG" \
"$PROJECT_DIR"/.build/artifacts/artifact-source/* \
"$PROJECT_DIR"/.build/artifacts/artifact-gpgui-*/*
}
release_tag() {
echo "Removing existing release..."
gh -R "$REPO" release delete $TAG --yes --cleanup-tag || true
echo "Creating release..."
gh -R "$REPO" release create $TAG \
--title "$TAG" \
--notes "$RELEASE_NOTES" \
"$PROJECT_DIR"/.build/artifacts/artifact-source/* \
"$PROJECT_DIR"/.build/artifacts/artifact-gpgui-*/*
}
if [[ $TAG == *"snapshot" ]]; then
release_snapshot
else
release_tag
fi