From b188d61be1e8bc82d2f34ac32ad22bd4b555ae43 Mon Sep 17 00:00:00 2001 From: Kevin Yue Date: Sun, 12 Jan 2025 14:41:03 +0800 Subject: [PATCH] fix: disconnect VPN when sleep --- .github/workflows/build.yaml | 5 + Cargo.lock | 377 ++++++++++-------- Cargo.toml | 18 +- Makefile | 7 + apps/gpclient/Cargo.toml | 2 +- apps/gpclient/src/cli.rs | 6 +- apps/gpclient/src/connect.rs | 22 +- apps/gpclient/src/disconnect.rs | 68 +++- apps/gpservice/Cargo.toml | 2 +- apps/gpservice/src/cli.rs | 75 +++- apps/gpservice/src/handlers.rs | 5 +- apps/gpservice/src/vpn_task.rs | 10 +- apps/gpservice/src/ws_connection.rs | 4 +- apps/gpservice/src/ws_server.rs | 8 +- crates/gpapi/Cargo.toml | 2 +- crates/gpapi/src/service/event.rs | 1 + crates/gpapi/src/utils/endpoint.rs | 9 +- crates/gpapi/src/utils/lock_file.rs | 95 ++++- packaging/binary/Makefile.in | 7 + .../dispatcher.d/gpclient-nm-hook | 26 ++ .../dispatcher.d/pre-down.d/gpclient.down | 6 + .../rpm/globalprotect-openconnect.spec.in | 7 + 22 files changed, 525 insertions(+), 237 deletions(-) create mode 100755 packaging/files/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook create mode 100755 packaging/files/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2015a967..36499aaf 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -14,6 +14,11 @@ on: - release/* tags: - v*.*.* + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: # Include arm64 if ref is a tag setup-matrix: diff --git a/Cargo.lock b/Cargo.lock index fba8a5d6..4edab240 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,11 +113,12 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys 0.59.0", ] @@ -141,7 +142,7 @@ checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -205,14 +206,14 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.9" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" dependencies = [ - "async-trait", "axum-core", "base64 0.22.1", "bytes", + "form_urlencoded", "futures-util", "http", "http-body", @@ -242,11 +243,10 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" dependencies = [ - "async-trait", "bytes", "futures-util", "http", @@ -296,9 +296,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" dependencies = [ "serde", ] @@ -381,7 +381,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cairo-sys-rs", "glib", "libc", @@ -429,24 +429,24 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.10", + "thiserror 2.0.11", ] [[package]] name = "cargo_toml" -version = "0.17.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719" +checksum = "5fbd1fe9db3ebf71b89060adaf7b0504c2d6a425cf061313099547e382c2e472" dependencies = [ "serde", - "toml 0.8.2", + "toml 0.8.19", ] [[package]] name = "cc" -version = "1.2.7" +version = "1.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" dependencies = [ "shlex", ] @@ -546,9 +546,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.25" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95dca1b68188a08ca6af9d96a6576150f598824bdb528c1190460c2940a0b48" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", "clap_derive", @@ -566,9 +566,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.25" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab52925392148efd3f7562f2136a81ffb778076bcc85727c6e020d6dd57cf15" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstream", "anstyle", @@ -585,7 +585,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -600,7 +600,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block", "cocoa-foundation", "core-foundation 0.10.0", @@ -616,7 +616,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e14045fb83be07b5acf1c0884b2180461635b433455fa35d1cd6f17f1450679d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block", "core-foundation 0.10.0", "core-graphics-types", @@ -709,7 +709,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "core-foundation 0.10.0", "core-graphics-types", "foreign-types 0.5.0", @@ -722,7 +722,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "core-foundation 0.10.0", "libc", ] @@ -839,7 +839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -849,7 +849,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -873,7 +873,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -884,14 +884,14 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" [[package]] name = "deranged" @@ -913,7 +913,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -970,7 +970,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -993,7 +993,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1059,7 +1059,7 @@ dependencies = [ "cc", "memchr", "rustc_version", - "toml 0.8.2", + "toml 0.8.19", "vswhom", "winreg", ] @@ -1214,7 +1214,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1304,7 +1304,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1530,7 +1530,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "futures-channel", "futures-core", "futures-executor", @@ -1554,11 +1554,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" dependencies = [ "heck 0.4.1", - "proc-macro-crate 2.0.2", + "proc-macro-crate 2.0.0", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1615,7 +1615,7 @@ dependencies = [ "specta", "tauri", "tempfile", - "thiserror 2.0.10", + "thiserror 2.0.11", "tokio", "url", "urlencoding", @@ -1753,7 +1753,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1768,7 +1768,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.7.0", + "indexmap 2.7.1", "slab", "tokio", "tokio-util", @@ -2110,7 +2110,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -2153,9 +2153,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -2186,7 +2186,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "crossterm", "dyn-clone", "fuzzy-matcher", @@ -2199,9 +2199,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "is-docker" @@ -2296,9 +2296,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -2332,7 +2332,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "serde", "unicode-segmentation", ] @@ -2402,7 +2402,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "libc", "redox_syscall", ] @@ -2431,9 +2431,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "log-reload" @@ -2493,9 +2493,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matchit" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "md5" @@ -2526,9 +2526,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" dependencies = [ "adler2", "simd-adler32", @@ -2600,7 +2600,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "jni-sys", "log", "ndk-sys", @@ -2684,10 +2684,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 2.0.2", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -2724,7 +2724,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "libc", "objc2", @@ -2740,7 +2740,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "objc2", "objc2-core-location", @@ -2764,7 +2764,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "objc2", "objc2-foundation", @@ -2806,7 +2806,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "libc", "objc2", @@ -2830,7 +2830,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "objc2", "objc2-foundation", @@ -2842,7 +2842,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "objc2", "objc2-foundation", @@ -2865,7 +2865,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "objc2", "objc2-cloud-kit", @@ -2897,7 +2897,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "objc2", "objc2-core-location", @@ -2910,7 +2910,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "block2", "objc2", "objc2-app-kit", @@ -2964,7 +2964,7 @@ version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -2981,7 +2981,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3182,7 +3182,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3237,7 +3237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.7.0", + "indexmap 2.7.1", "quick-xml", "serde", "time", @@ -3300,12 +3300,20 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit 0.22.22", ] [[package]] @@ -3340,9 +3348,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -3492,7 +3500,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", ] [[package]] @@ -3623,7 +3631,7 @@ version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "errno", "libc", "linux-raw-sys", @@ -3632,9 +3640,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ "once_cell", "rustls-pki-types", @@ -3723,7 +3731,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3738,7 +3746,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -3777,9 +3785,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" dependencies = [ "serde", ] @@ -3812,7 +3820,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3823,14 +3831,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "serde_json" -version = "1.0.135" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" +checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" dependencies = [ "itoa 1.0.14", "memchr", @@ -3866,7 +3874,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3900,7 +3908,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_derive", "serde_json", @@ -3917,7 +3925,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4133,7 +4141,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4210,9 +4218,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.95" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -4236,7 +4244,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4259,7 +4267,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -4283,7 +4291,7 @@ dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml 0.8.2", + "toml 0.8.19", "version-compare", ] @@ -4293,7 +4301,7 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3731d04d4ac210cd5f344087733943b9bfb1a32654387dad4d1c70de21aee2c9" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cocoa", "core-foundation 0.10.0", "core-graphics", @@ -4333,7 +4341,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4355,9 +4363,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.2.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2e3349fbb2be7af9fad1b43d61ac83ba55ab48d47fbe1b2732f0c8211610a9" +checksum = "78f6efc261c7905839b4914889a5b25df07f0ff89c63fb4afd6ff8c96af15e4d" dependencies = [ "anyhow", "bytes", @@ -4392,7 +4400,7 @@ dependencies = [ "tauri-runtime", "tauri-runtime-wry", "tauri-utils", - "thiserror 2.0.10", + "thiserror 2.0.11", "tokio", "tray-icon", "url", @@ -4405,9 +4413,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b274ec7239ada504deb615f1c8abd7ba99631e879709e6f10e5d17217058d976" +checksum = "8e950124f6779c6cf98e3260c7a6c8488a74aa6350dd54c6950fdaa349bca2df" dependencies = [ "anyhow", "cargo_toml", @@ -4421,7 +4429,7 @@ dependencies = [ "serde_json", "tauri-utils", "tauri-winres", - "toml 0.8.2", + "toml 0.8.19", "walkdir", ] @@ -4443,9 +4451,9 @@ dependencies = [ "serde", "serde_json", "sha2", - "syn 2.0.95", + "syn 2.0.96", "tauri-utils", - "thiserror 2.0.10", + "thiserror 2.0.11", "time", "url", "uuid", @@ -4461,7 +4469,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "tauri-codegen", "tauri-utils", ] @@ -4480,7 +4488,7 @@ dependencies = [ "serde", "serde_json", "tauri-utils", - "thiserror 2.0.10", + "thiserror 2.0.11", "url", "windows 0.58.0", ] @@ -4540,8 +4548,8 @@ dependencies = [ "serde_json", "serde_with", "swift-rs", - "thiserror 2.0.10", - "toml 0.8.2", + "thiserror 2.0.11", + "toml 0.8.19", "url", "urlpattern", "uuid", @@ -4600,11 +4608,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.10", + "thiserror-impl 2.0.11", ] [[package]] @@ -4615,18 +4623,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "thiserror-impl" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4702,7 +4710,6 @@ dependencies = [ "bytes", "libc", "mio 1.0.3", - "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -4718,7 +4725,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4743,9 +4750,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.24.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +checksum = "be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a" dependencies = [ "futures-util", "log", @@ -4780,21 +4787,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.22.22", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4805,24 +4812,35 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.7.1", + "toml_datetime", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.24", ] [[package]] @@ -4902,9 +4920,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24" dependencies = [ "byteorder", "bytes", @@ -4914,7 +4932,7 @@ dependencies = [ "log", "rand 0.8.5", "sha1", - "thiserror 1.0.69", + "thiserror 2.0.11", "utf-8", ] @@ -5067,9 +5085,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" dependencies = [ "getrandom 0.2.15", "serde", @@ -5162,34 +5180,35 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", @@ -5200,9 +5219,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5210,22 +5229,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-streams" @@ -5242,9 +5264,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -5334,7 +5356,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5478,7 +5500,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5489,7 +5511,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5500,7 +5522,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5511,7 +5533,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5849,6 +5871,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.52.0" @@ -5879,9 +5910,9 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e644bf458e27b11b0ecafc9e5633d1304fdae82baca1d42185669752fe6ca4f" +checksum = "a2e33c08b174442ff80d5c791020696f9f8b4e4a87b8cfc7494aad6167ec44e1" dependencies = [ "base64 0.22.1", "block2", @@ -5909,7 +5940,7 @@ dependencies = [ "sha2", "soup3", "tao-macros", - "thiserror 2.0.10", + "thiserror 2.0.11", "url", "webkit2gtk", "webkit2gtk-sys", @@ -5981,7 +6012,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] @@ -6003,7 +6034,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -6023,7 +6054,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] @@ -6052,5 +6083,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] diff --git a/Cargo.toml b/Cargo.toml index 3817c9ef..958e5cbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,13 @@ [workspace] resolver = "2" -members = ["crates/*", "apps/gpclient", "apps/gpservice", "apps/gpauth", "apps/gpgui-helper/src-tauri"] +members = [ + "crates/*", + "apps/gpclient", + "apps/gpservice", + "apps/gpauth", + "apps/gpgui-helper/src-tauri", +] [workspace.package] rust-version = "1.80" @@ -31,11 +37,11 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sysinfo = "0.33" tempfile = "3.8" -tokio = { version = "1", features = ["full"] } +tokio = { version = "1" } tokio-util = "0.7" url = "2.4" urlencoding = "2.1.3" -axum = "0.7" +axum = "0.8" futures = "0.3" futures-util = "0.3" uzers = "0.12" @@ -44,9 +50,9 @@ thiserror = "2" redact-engine = "0.1" compile-time = "0.2" serde_urlencoded = "0.7" -md5="0.7" -sha256="1" -which="7" +md5 = "0.7" +sha256 = "1" +which = "7" # Tauri dependencies tauri = { version = "2" } diff --git a/Makefile b/Makefile index ac1fe008..c453141e 100644 --- a/Makefile +++ b/Makefile @@ -130,6 +130,10 @@ install: install -Dm755 .build/gpgui/gpgui_*/gpgui $(DESTDIR)/usr/bin/gpgui; \ fi + # Install the disconnect hooks + 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 + install -Dm755 packaging/files/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook + install -Dm644 packaging/files/usr/share/applications/gpgui.desktop $(DESTDIR)/usr/share/applications/gpgui.desktop install -Dm644 packaging/files/usr/share/icons/hicolor/scalable/apps/gpgui.svg $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/gpgui.svg install -Dm644 packaging/files/usr/share/icons/hicolor/32x32/apps/gpgui.png $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/gpgui.png @@ -146,6 +150,9 @@ uninstall: rm -f $(DESTDIR)/usr/bin/gpgui-helper rm -f $(DESTDIR)/usr/bin/gpgui + rm -f $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down + rm -f $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook + rm -f $(DESTDIR)/usr/share/applications/gpgui.desktop rm -f $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/gpgui.svg rm -f $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/gpgui.png diff --git a/apps/gpclient/Cargo.toml b/apps/gpclient/Cargo.toml index 1dc414e1..06133092 100644 --- a/apps/gpclient/Cargo.toml +++ b/apps/gpclient/Cargo.toml @@ -16,7 +16,7 @@ clap.workspace = true env_logger.workspace = true inquire = "0.7" log.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["rt-multi-thread"] } sysinfo.workspace = true serde_json.workspace = true whoami.workspace = true diff --git a/apps/gpclient/src/cli.rs b/apps/gpclient/src/cli.rs index 3d832720..5ff10950 100644 --- a/apps/gpclient/src/cli.rs +++ b/apps/gpclient/src/cli.rs @@ -10,7 +10,7 @@ use tempfile::NamedTempFile; use crate::{ connect::{ConnectArgs, ConnectHandler}, - disconnect::DisconnectHandler, + disconnect::{DisconnectArgs, DisconnectHandler}, launch_gui::{LaunchGuiArgs, LaunchGuiHandler}, }; @@ -27,7 +27,7 @@ enum CliCommand { #[command(about = "Connect to a portal server")] Connect(Box), #[command(about = "Disconnect from the server")] - Disconnect, + Disconnect(DisconnectArgs), #[command(about = "Launch the GUI")] LaunchGui(LaunchGuiArgs), } @@ -102,7 +102,7 @@ impl Cli { match &self.command { CliCommand::Connect(args) => ConnectHandler::new(args, &shared_args).handle().await, - CliCommand::Disconnect => DisconnectHandler::new().handle(), + CliCommand::Disconnect(args) => DisconnectHandler::new(args).handle().await, CliCommand::LaunchGui(args) => LaunchGuiHandler::new(args).handle().await, } } diff --git a/apps/gpclient/src/connect.rs b/apps/gpclient/src/connect.rs index df7d1603..691fc7ae 100644 --- a/apps/gpclient/src/connect.rs +++ b/apps/gpclient/src/connect.rs @@ -84,11 +84,11 @@ pub(crate) struct ConnectArgs { #[arg(long, default_value = GP_USER_AGENT, help = "The user agent to use")] user_agent: String, - #[arg(long, default_value = "Linux")] + #[arg(long, value_enum, default_value_t = ConnectArgs::default_os())] os: Os, - #[arg(long)] - os_version: Option, + #[arg(long, default_value_t = ConnectArgs::default_os_version())] + os_version: String, #[arg(long, help = "Disable DTLS and ESP")] no_dtls: bool, @@ -113,12 +113,16 @@ pub(crate) struct ConnectArgs { } impl ConnectArgs { - fn os_version(&self) -> String { - if let Some(os_version) = &self.os_version { - return os_version.to_owned(); + fn default_os() -> Os { + if cfg!(target_os = "macos") { + Os::Mac + } else { + Os::Linux } + } - match self.os { + fn default_os_version() -> String { + match ConnectArgs::default_os() { Os::Linux => format!("Linux {}", whoami::distro()), Os::Windows => String::from("Microsoft Windows 11 Pro , 64-bit"), Os::Mac => String::from("Apple Mac OS X 13.4.0"), @@ -145,7 +149,7 @@ impl<'a> ConnectHandler<'a> { GpParams::builder() .user_agent(&self.args.user_agent) .client_os(ClientOs::from(&self.args.os)) - .os_version(self.args.os_version()) + .os_version(self.args.os_version.clone()) .ignore_tls_errors(self.shared_args.ignore_tls_errors) .certificate(self.args.certificate.clone()) .sslkey(self.args.sslkey.clone()) @@ -355,7 +359,7 @@ impl<'a> ConnectHandler<'a> { None }; - let os_version = self.args.os_version(); + let os_version = self.args.os_version.clone(); let verbose = self.shared_args.verbose.to_verbose_arg(); let auth_launcher = SamlAuthLauncher::new(&self.args.server) .gateway(is_gateway) diff --git a/apps/gpclient/src/disconnect.rs b/apps/gpclient/src/disconnect.rs index b1678fbb..a0c6d66d 100644 --- a/apps/gpclient/src/disconnect.rs +++ b/apps/gpclient/src/disconnect.rs @@ -1,31 +1,63 @@ use crate::GP_CLIENT_LOCK_FILE; +use clap::Args; +use gpapi::utils::lock_file::gpservice_lock_info; use log::{info, warn}; -use std::fs; +use std::{fs, str::FromStr, thread, time::Duration}; use sysinfo::{Pid, Signal, System}; -pub(crate) struct DisconnectHandler; +#[derive(Args)] +pub struct DisconnectArgs { + #[arg( + long, + required = false, + help = "The time in seconds to wait for the VPN connection to disconnect" + )] + wait: Option, +} + +pub struct DisconnectHandler<'a> { + args: &'a DisconnectArgs, +} -impl DisconnectHandler { - pub(crate) fn new() -> Self { - Self +impl<'a> DisconnectHandler<'a> { + pub fn new(args: &'a DisconnectArgs) -> Self { + Self { args } } - pub(crate) fn handle(&self) -> anyhow::Result<()> { - if fs::metadata(GP_CLIENT_LOCK_FILE).is_err() { - warn!("PID file not found, maybe the client is not running"); - return Ok(()); - } + pub async fn handle(&self) -> anyhow::Result<()> { + // Try to disconnect the CLI client + if let Ok(c) = fs::read_to_string(GP_CLIENT_LOCK_FILE) { + send_signal(c.trim(), Signal::Interrupt).unwrap_or_else(|err| { + warn!("Failed to send signal to client: {}", err); + }); + }; - let pid = fs::read_to_string(GP_CLIENT_LOCK_FILE)?; - let pid = pid.trim().parse::()?; - let s = System::new_all(); + // Try to disconnect the GUI service + if let Ok(c) = gpservice_lock_info().await { + send_signal(&c.pid.to_string(), Signal::User1).unwrap_or_else(|err| { + warn!("Failed to send signal to service: {}", err); + }); + }; - if let Some(process) = s.process(Pid::from(pid)) { - info!("Found process {}, killing...", pid); - if process.kill_with(Signal::Interrupt).is_none() { - warn!("Failed to kill process {}", pid); - } + // sleep, to give the client and service time to disconnect + if let Some(wait) = self.args.wait { + thread::sleep(Duration::from_secs(wait)); } + Ok(()) } } + +fn send_signal(pid: &str, signal: Signal) -> anyhow::Result<()> { + let s = System::new_all(); + let pid = Pid::from_str(pid)?; + + if let Some(process) = s.process(pid) { + info!("Found process {}, sending signal...", pid); + + if process.kill_with(signal).is_none() { + warn!("Failed to kill process {}", pid); + } + } + Ok(()) +} diff --git a/apps/gpservice/Cargo.toml b/apps/gpservice/Cargo.toml index fdff7031..a990b014 100644 --- a/apps/gpservice/Cargo.toml +++ b/apps/gpservice/Cargo.toml @@ -9,7 +9,7 @@ gpapi = { path = "../../crates/gpapi", features = ["clap", "logger"] } openconnect = { path = "../../crates/openconnect" } clap.workspace = true anyhow.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["rt-multi-thread"] } tokio-util.workspace = true axum = { workspace = true, features = ["ws"] } futures.workspace = true diff --git a/apps/gpservice/src/cli.rs b/apps/gpservice/src/cli.rs index 82ded3eb..fefe6ca5 100644 --- a/apps/gpservice/src/cli.rs +++ b/apps/gpservice/src/cli.rs @@ -38,7 +38,8 @@ impl Cli { let redaction = self.init_logger(); info!("gpservice started: {}", VERSION); - let lock_file = Arc::new(LockFile::new(GP_SERVICE_LOCK_FILE)); + let pid = std::process::id(); + let lock_file = Arc::new(LockFile::new(GP_SERVICE_LOCK_FILE, pid)); if lock_file.check_health().await { bail!("Another instance of the service is already running"); @@ -56,9 +57,17 @@ impl Cli { let (shutdown_tx, mut shutdown_rx) = mpsc::channel::<()>(4); let shutdown_tx_clone = shutdown_tx.clone(); - let vpn_task_token = vpn_task.cancel_token(); + let vpn_task_cancel_token = vpn_task.cancel_token(); let server_token = ws_server.cancel_token(); + #[cfg(unix)] + { + let vpn_ctx = vpn_task.context(); + let ws_ctx = ws_server.context(); + + tokio::spawn(async move { signals::handle_signals(vpn_ctx, ws_ctx).await }); + } + let vpn_task_handle = tokio::spawn(async move { vpn_task.start(server_token).await }); let ws_server_handle = tokio::spawn(async move { ws_server.start(shutdown_tx_clone).await }); @@ -82,15 +91,15 @@ impl Cli { } tokio::select! { - _ = shutdown_signal() => { - info!("Shutdown signal received"); - } - _ = shutdown_rx.recv() => { - info!("Shutdown request received, shutting down"); - } + _ = shutdown_signal() => { + info!("Shutdown signal received"); + } + _ = shutdown_rx.recv() => { + info!("Shutdown request received, shutting down"); + } } - vpn_task_token.cancel(); + vpn_task_cancel_token.cancel(); let _ = tokio::join!(vpn_task_handle, ws_server_handle); lock_file.unlock()?; @@ -137,6 +146,54 @@ impl Cli { } } +#[cfg(unix)] +mod signals { + use std::sync::Arc; + + use log::{info, warn}; + + use crate::vpn_task::VpnTaskContext; + use crate::ws_server::WsServerContext; + + const DISCONNECTED_PID_FILE: &str = "/tmp/gpservice_disconnected.pid"; + + pub async fn handle_signals(vpn_ctx: Arc, ws_ctx: Arc) { + use gpapi::service::event::WsEvent; + use tokio::signal::unix::{signal, Signal, SignalKind}; + + let (mut user_sig1, mut user_sig2) = match || -> anyhow::Result<(Signal, Signal)> { + let user_sig1 = signal(SignalKind::user_defined1())?; + let user_sig2 = signal(SignalKind::user_defined2())?; + Ok((user_sig1, user_sig2)) + }() { + Ok(signals) => signals, + Err(err) => { + warn!("Failed to create signal: {}", err); + return; + } + }; + + loop { + tokio::select! { + _ = user_sig1.recv() => { + info!("Received SIGUSR1 signal"); + if vpn_ctx.disconnect().await { + // Write the PID to a dedicated file to indicate that the VPN task is disconnected via SIGUSR1 + let pid = std::process::id(); + if let Err(err) = tokio::fs::write(DISCONNECTED_PID_FILE, pid.to_string()).await { + warn!("Failed to write PID to file: {}", err); + } + } + } + _ = user_sig2.recv() => { + info!("Received SIGUSR2 signal"); + ws_ctx.send_event(WsEvent::ResumeConnection).await; + } + } + } + } +} + async fn launch_gui(envs: Option>, api_key: Vec, mut minimized: bool) { loop { let gui_launcher = GuiLauncher::new(env!("CARGO_PKG_VERSION"), &api_key) diff --git a/apps/gpservice/src/handlers.rs b/apps/gpservice/src/handlers.rs index 42bad2ba..700d6ab6 100644 --- a/apps/gpservice/src/handlers.rs +++ b/apps/gpservice/src/handlers.rs @@ -1,5 +1,4 @@ use std::{ - borrow::Cow, fs::{File, Permissions}, io::BufReader, ops::ControlFlow, @@ -12,7 +11,7 @@ use anyhow::bail; use axum::{ body::Bytes, extract::{ - ws::{self, CloseFrame, Message, WebSocket}, + ws::{self, CloseFrame, Message, Utf8Bytes, WebSocket}, State, WebSocketUpgrade, }, http::StatusCode, @@ -133,7 +132,7 @@ async fn handle_socket(mut socket: WebSocket, ctx: Arc) { let close_msg = Message::Close(Some(CloseFrame { code: ws::close_code::NORMAL, - reason: Cow::from("Goodbye"), + reason: Utf8Bytes::from("Goodbye"), })); if let Err(err) = sender.send(close_msg).await { diff --git a/apps/gpservice/src/vpn_task.rs b/apps/gpservice/src/vpn_task.rs index 11577d11..77b0bf51 100644 --- a/apps/gpservice/src/vpn_task.rs +++ b/apps/gpservice/src/vpn_task.rs @@ -90,7 +90,7 @@ impl VpnTaskContext { }); } - pub async fn disconnect(&self) { + pub async fn disconnect(&self) -> bool { if let Some(disconnect_rx) = self.disconnect_rx.write().await.take() { info!("Disconnecting VPN..."); if let Some(vpn) = self.vpn_handle.read().await.as_ref() { @@ -101,9 +101,13 @@ impl VpnTaskContext { // Wait for the VPN to be disconnected disconnect_rx.await.ok(); info!("VPN disconnected"); + + true } else { info!("VPN is not connected, skip disconnect"); self.vpn_state_tx.send(VpnState::Disconnected).ok(); + + false } } } @@ -146,6 +150,10 @@ impl VpnTask { server_cancel_token.cancel(); } + pub fn context(&self) -> Arc { + return Arc::clone(&self.ctx); + } + async fn recv(&mut self) { while let Some(req) = self.ws_req_rx.recv().await { tokio::spawn(process_ws_req(req, self.ctx.clone())); diff --git a/apps/gpservice/src/ws_connection.rs b/apps/gpservice/src/ws_connection.rs index 13c7f6c9..e5b3c854 100644 --- a/apps/gpservice/src/ws_connection.rs +++ b/apps/gpservice/src/ws_connection.rs @@ -20,7 +20,7 @@ impl WsConnection { pub async fn send_event(&self, event: &WsEvent) -> anyhow::Result<()> { let encrypted = self.crypto.encrypt(event)?; - let msg = Message::Binary(encrypted); + let msg = Message::Binary(encrypted.into()); self.tx.send(msg).await?; @@ -29,7 +29,7 @@ impl WsConnection { pub fn recv_msg(&self, msg: Message) -> ControlFlow<(), WsRequest> { match msg { - Message::Binary(data) => match self.crypto.decrypt(data) { + Message::Binary(data) => match self.crypto.decrypt(data.into()) { Ok(ws_req) => ControlFlow::Continue(ws_req), Err(err) => { info!("Failed to decrypt message: {}", err); diff --git a/apps/gpservice/src/ws_server.rs b/apps/gpservice/src/ws_server.rs index 5d550ebc..a2fe9654 100644 --- a/apps/gpservice/src/ws_server.rs +++ b/apps/gpservice/src/ws_server.rs @@ -113,6 +113,10 @@ impl WsServer { } } + pub fn context(&self) -> Arc { + Arc::clone(&self.ctx) + } + pub fn cancel_token(&self) -> CancellationToken { self.cancel_token.clone() } @@ -124,7 +128,7 @@ impl WsServer { warn!("Failed to start WS server: {}", err); let _ = shutdown_tx.send(()).await; return; - }, + } }; tokio::select! { @@ -149,7 +153,7 @@ impl WsServer { info!("WS server listening on port: {}", port); - self.lock_file.lock(port.to_string())?; + self.lock_file.lock(&port.to_string())?; Ok(listener) } diff --git a/crates/gpapi/Cargo.toml b/crates/gpapi/Cargo.toml index 0b95b970..c82ce001 100644 --- a/crates/gpapi/Cargo.toml +++ b/crates/gpapi/Cargo.toml @@ -18,7 +18,7 @@ roxmltree.workspace = true serde.workspace = true specta = { workspace = true, features = ["derive"] } urlencoding.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["process", "signal", "macros"] } serde_json.workspace = true whoami.workspace = true tempfile.workspace = true diff --git a/crates/gpapi/src/service/event.rs b/crates/gpapi/src/service/event.rs index 869b9809..9f3339d0 100644 --- a/crates/gpapi/src/service/event.rs +++ b/crates/gpapi/src/service/event.rs @@ -7,4 +7,5 @@ use super::vpn_state::VpnState; pub enum WsEvent { VpnState(VpnState), ActiveGui, + ResumeConnection, } diff --git a/crates/gpapi/src/utils/endpoint.rs b/crates/gpapi/src/utils/endpoint.rs index 0a88bc6a..6c0aa5a2 100644 --- a/crates/gpapi/src/utils/endpoint.rs +++ b/crates/gpapi/src/utils/endpoint.rs @@ -1,10 +1,9 @@ -use tokio::fs; - -use crate::GP_SERVICE_LOCK_FILE; +use super::lock_file::gpservice_lock_info; async fn read_port() -> anyhow::Result { - let port = fs::read_to_string(GP_SERVICE_LOCK_FILE).await?; - Ok(port.trim().to_string()) + let lock_info = gpservice_lock_info().await?; + + Ok(lock_info.port.to_string()) } pub async fn http_endpoint() -> anyhow::Result { diff --git a/crates/gpapi/src/utils/lock_file.rs b/crates/gpapi/src/utils/lock_file.rs index 93ee5104..fa535f15 100644 --- a/crates/gpapi/src/utils/lock_file.rs +++ b/crates/gpapi/src/utils/lock_file.rs @@ -1,19 +1,24 @@ use std::path::PathBuf; +use thiserror::Error; +use tokio::fs; + pub struct LockFile { path: PathBuf, + pid: u32, } impl LockFile { - pub fn new>(path: P) -> Self { - Self { path: path.into() } + pub fn new>(path: P, pid: u32) -> Self { + Self { path: path.into(), pid } } pub fn exists(&self) -> bool { self.path.exists() } - pub fn lock(&self, content: impl AsRef<[u8]>) -> anyhow::Result<()> { + pub fn lock(&self, content: &str) -> anyhow::Result<()> { + let content = format!("{}:{}", self.pid, content); std::fs::write(&self.path, content)?; Ok(()) } @@ -37,3 +42,87 @@ impl LockFile { } } } + +#[derive(Error, Debug)] +pub enum LockFileError { + #[error("Failed to read lock file: {0}")] + IoError(#[from] std::io::Error), + + #[error("Invalid lock file format: expected 'pid:port'")] + InvalidFormat, + + #[error("Invalid PID value: {0}")] + InvalidPid(std::num::ParseIntError), + + #[error("Invalid port value: {0}")] + InvalidPort(std::num::ParseIntError), +} + +pub struct LockInfo { + pub pid: u32, + pub port: u32, +} + +impl LockInfo { + async fn from_file(path: impl AsRef) -> Result { + let content = fs::read_to_string(path).await?; + Self::parse(&content) + } + + fn parse(content: &str) -> Result { + let mut parts = content.trim().split(':'); + + let pid = parts + .next() + .ok_or(LockFileError::InvalidFormat)? + .parse() + .map_err(LockFileError::InvalidPid)?; + + let port = parts + .next() + .ok_or(LockFileError::InvalidFormat)? + .parse() + .map_err(LockFileError::InvalidPort)?; + + // Ensure there are no extra parts after pid:port + if parts.next().is_some() { + return Err(LockFileError::InvalidFormat); + } + + Ok(Self { pid, port }) + } +} + +pub async fn gpservice_lock_info() -> Result { + LockInfo::from_file(crate::GP_SERVICE_LOCK_FILE).await +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_valid_input() { + let info = LockInfo::parse("1234:8080").unwrap(); + assert_eq!(info.pid, 1234); + assert_eq!(info.port, 8080); + } + + #[test] + fn test_parse_invalid_format() { + assert!(matches!( + LockInfo::parse("123:456:789"), + Err(LockFileError::InvalidFormat) + )); + } + + #[test] + fn test_parse_invalid_numbers() { + assert!(matches!(LockInfo::parse("abc:8080"), Err(LockFileError::InvalidPid(_)))); + + assert!(matches!( + LockInfo::parse("1234:abc"), + Err(LockFileError::InvalidPort(_)) + )); + } +} diff --git a/packaging/binary/Makefile.in b/packaging/binary/Makefile.in index 154ce5bc..a9f9bdd8 100644 --- a/packaging/binary/Makefile.in +++ b/packaging/binary/Makefile.in @@ -10,6 +10,10 @@ install: install -Dm755 artifacts/usr/bin/gpgui $(DESTDIR)/usr/bin/gpgui; \ fi + # Install the disconnect hooks + install -Dm755 artifacts/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down + install -Dm755 artifacts/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook + install -Dm644 artifacts/usr/share/applications/gpgui.desktop $(DESTDIR)/usr/share/applications/gpgui.desktop install -Dm644 artifacts/usr/share/icons/hicolor/scalable/apps/gpgui.svg $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/gpgui.svg install -Dm644 artifacts/usr/share/icons/hicolor/32x32/apps/gpgui.png $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/gpgui.png @@ -26,6 +30,9 @@ uninstall: rm -f $(DESTDIR)/usr/bin/gpgui-helper rm -f $(DESTDIR)/usr/bin/gpgui + rm -f $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down + rm -f $(DESTDIR)/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook + rm -f $(DESTDIR)/usr/share/applications/gpgui.desktop rm -f $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/gpgui.svg rm -f $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/gpgui.png diff --git a/packaging/files/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook b/packaging/files/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook new file mode 100755 index 00000000..ba79ecdb --- /dev/null +++ b/packaging/files/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook @@ -0,0 +1,26 @@ +#!/bin/sh + +# Resume the VPN connection if the network comes back up + +set -e + +PIDFILE=/tmp/gpservice_disconnected.pid + +resume_vpn() { + if [ -f $PIDFILE ]; then + PID=$(cat $PIDFILE) + + # Always remove the PID file + rm $PIDFILE + + # Ensure the PID is a gpservice process + if ps -p $PID -o comm= | grep -q gpservice; then + # Send a USR2 signal to the gpclient process to resume the VPN connection + kill -USR2 $PID + fi + fi +} + +if [ "$2" = "up" ]; then + resume_vpn +fi diff --git a/packaging/files/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down b/packaging/files/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down new file mode 100755 index 00000000..cf88eabe --- /dev/null +++ b/packaging/files/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e + +# Disconnect the VPN connection before the network goes down +/usr/bin/gpclient disconnect --wait 3 diff --git a/packaging/rpm/globalprotect-openconnect.spec.in b/packaging/rpm/globalprotect-openconnect.spec.in index 3b341415..356e69f9 100644 --- a/packaging/rpm/globalprotect-openconnect.spec.in +++ b/packaging/rpm/globalprotect-openconnect.spec.in @@ -60,6 +60,13 @@ make build OFFLINE=@OFFLINE@ BUILD_FE=0 %{_datadir}/icons/hicolor/scalable/apps/gpgui.svg %{_datadir}/polkit-1/actions/com.yuezk.gpgui.policy +%dir /usr/lib/NetworkManager +%dir /usr/lib/NetworkManager/dispatcher.d +%dir /usr/lib/NetworkManager/dispatcher.d/pre-down.d + +/usr/lib/NetworkManager/dispatcher.d/pre-down.d/gpclient.down +/usr/lib/NetworkManager/dispatcher.d/gpclient-nm-hook + %dir %{_datadir}/icons/hicolor %dir %{_datadir}/icons/hicolor/32x32 %dir %{_datadir}/icons/hicolor/32x32/apps