diff options
| -rw-r--r-- | Cargo.lock | 403 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | desktop/mullvad-daemon-portable/.gitignore | 2 | ||||
| -rwxr-xr-x | desktop/mullvad-daemon-portable/build-image.sh | 39 | ||||
| -rwxr-xr-x | desktop/mullvad-daemon-portable/mullvad-daemon-static | bin | 0 -> 16604776 bytes | |||
| -rw-r--r-- | desktop/mullvad-daemon-portable/mullvad-daemon.service | 20 | ||||
| -rw-r--r-- | desktop/mullvad-daemon-portable/portablectl-rs/Cargo.toml | 19 | ||||
| -rw-r--r-- | desktop/mullvad-daemon-portable/portablectl-rs/src/bus.rs | 77 | ||||
| -rw-r--r-- | desktop/mullvad-daemon-portable/portablectl-rs/src/main.rs | 127 | ||||
| -rw-r--r-- | desktop/mullvad-daemon-portable/repart.d/10-root.conf | 19 | ||||
| -rw-r--r-- | desktop/mullvad-daemon-portable/test.sh | 7 |
11 files changed, 696 insertions, 19 deletions
diff --git a/Cargo.lock b/Cargo.lock index 64a7c98627..c82ac9c81e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,18 @@ dependencies = [ ] [[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] name = "async-channel" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -177,6 +189,96 @@ dependencies = [ ] [[package]] +name = "async-executor" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 1.1.3", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix 1.1.3", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + +[[package]] +name = "async-signal" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 1.1.3", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + +[[package]] name = "async-task" version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1198,6 +1300,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + +[[package]] name = "enum-as-inner" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1230,6 +1338,27 @@ dependencies = [ ] [[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + +[[package]] name = "env_filter" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1275,12 +1404,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1457,7 +1586,10 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ + "fastrand", "futures-core", + "futures-io", + "parking", "pin-project-lite", ] @@ -1689,9 +1821,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" @@ -1712,6 +1844,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2156,9 +2294,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.2.6" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown", @@ -2478,9 +2616,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libdbus-sys" @@ -2540,6 +2678,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] name = "litemap" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2702,7 +2846,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", @@ -3695,6 +3839,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] name = "os_info" version = "3.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4020,6 +4174,20 @@ dependencies = [ ] [[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.5.2", + "pin-project-lite", + "rustix 1.1.3", + "windows-sys 0.61.2", +] + +[[package]] name = "poly1305" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4049,6 +4217,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] +name = "portablectl-rs" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "serde", + "tokio", + "tracing", + "tracing-subscriber", + "zbus", +] + +[[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4112,6 +4293,15 @@ dependencies = [ ] [[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.10+spec-1.0.0", +] + +[[package]] name = "proc-macro2" version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4558,13 +4748,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.9.0", - "errno 0.3.8", + "errno 0.3.14", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] [[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.9.0", + "errno 0.3.14", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", +] + +[[package]] name = "rustls" version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4727,6 +4930,17 @@ dependencies = [ ] [[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + +[[package]] name = "serde_spanned" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5386,7 +5600,7 @@ checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "rustix", + "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -5557,6 +5771,7 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.8", "tokio-macros", + "tracing", "windows-sys 0.52.0", ] @@ -5668,8 +5883,8 @@ checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.8", + "toml_edit 0.22.20", ] [[package]] @@ -5682,6 +5897,15 @@ dependencies = [ ] [[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] name = "toml_edit" version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5690,8 +5914,29 @@ dependencies = [ "indexmap", "serde", "serde_spanned", - "toml_datetime", - "winnow", + "toml_datetime 0.6.8", + "winnow 0.6.20", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.14", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow 0.7.14", ] [[package]] @@ -6012,6 +6257,17 @@ dependencies = [ ] [[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset 0.9.1", + "tempfile", + "winapi", +] + +[[package]] name = "unarray" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6260,7 +6516,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix", + "rustix 0.38.34", ] [[package]] @@ -6962,6 +7218,15 @@ dependencies = [ ] [[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] name = "winreg" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7092,6 +7357,68 @@ dependencies = [ ] [[package]] +name = "zbus" +version = "5.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfeff997a0aaa3eb20c4652baf788d2dfa6d2839a0ead0b3ff69ce2f9c4bdd1" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix 1.1.3", + "serde", + "serde_repr", + "tokio", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow 0.7.14", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bbd5a90dbe8feee5b13def448427ae314ccd26a49cac47905cafefb9ff846f1" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.108", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" +dependencies = [ + "serde", + "winnow 0.7.14", + "zvariant", +] + +[[package]] name = "zerocopy" version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7173,3 +7500,43 @@ dependencies = [ "quote", "syn 2.0.108", ] + +[[package]] +name = "zvariant" +version = "5.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b64ef4f40c7951337ddc7023dd03528a57a3ce3408ee9da5e948bd29b232c4" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow 0.7.14", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484d5d975eb7afb52cc6b929c13d3719a20ad650fea4120e6310de3fc55e415c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.108", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.108", + "winnow 0.7.14", +] diff --git a/Cargo.toml b/Cargo.toml index e011166d98..e1563f51b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] resolver = "2" members = [ - "android/translations-converter", + "android/translations-converter", "desktop/mullvad-daemon-portable/portablectl-rs", "desktop/packages/nseventforwarder", "desktop/packages/windows-utils", "installer-downloader", diff --git a/desktop/mullvad-daemon-portable/.gitignore b/desktop/mullvad-daemon-portable/.gitignore new file mode 100644 index 0000000000..dc932dc2ea --- /dev/null +++ b/desktop/mullvad-daemon-portable/.gitignore @@ -0,0 +1,2 @@ +rootfs +*.raw diff --git a/desktop/mullvad-daemon-portable/build-image.sh b/desktop/mullvad-daemon-portable/build-image.sh new file mode 100755 index 0000000000..ade04b6211 --- /dev/null +++ b/desktop/mullvad-daemon-portable/build-image.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +set -ex + +OUTFILE="mullvad-portable.raw" +DESTDIR="./rootfs" + +cd "$(dirname "$0")" + +rm -rf "$DESTDIR" "$OUTFILE" +mkdir "$DESTDIR" + +mkdir -p \ + "$DESTDIR/etc" \ + "$DESTDIR/usr/bin" \ + "$DESTDIR/usr/lib/systemd/system" \ + "$DESTDIR/var/log" \ + "$DESTDIR/var/tmp" \ + "$DESTDIR/proc" \ + "$DESTDIR/sys" \ + "$DESTDIR/dev" \ + "$DESTDIR/run" \ + "$DESTDIR/tmp" + +# TODO: compile daemon statically +cp mullvad-daemon-static "$DESTDIR/usr/bin/mullvad-daemon" + +cp mullvad-daemon.service "$DESTDIR/usr/lib/systemd/system/mullvad-portable.service" + +cp /usr/lib/os-release "$DESTDIR/usr/lib/os-release" +cat >> "$DESTDIR/usr/lib/os-release" <<EOF +PORTABLE_PRETTY_NAME="Mullvad Daemon (portable)" +EOF + +touch "$DESTDIR/etc/resolv.conf" +touch "$DESTDIR/etc/machine-id" + +systemd-repart --definitions repart.d --empty=create --size=auto --copy-source "$DESTDIR" mullvad-portable.raw + diff --git a/desktop/mullvad-daemon-portable/mullvad-daemon-static b/desktop/mullvad-daemon-portable/mullvad-daemon-static Binary files differnew file mode 100755 index 0000000000..c905045c7b --- /dev/null +++ b/desktop/mullvad-daemon-portable/mullvad-daemon-static diff --git a/desktop/mullvad-daemon-portable/mullvad-daemon.service b/desktop/mullvad-daemon-portable/mullvad-daemon.service new file mode 100644 index 0000000000..e36bd90eff --- /dev/null +++ b/desktop/mullvad-daemon-portable/mullvad-daemon.service @@ -0,0 +1,20 @@ +# Systemd service unit file for the Mullvad VPN daemon +# testing if new changes are added + +[Unit] +Description=Mullvad VPN daemon +Before=network-online.target +After=mullvad-early-boot-blocking.service NetworkManager.service systemd-resolved.service + +StartLimitBurst=5 +StartLimitIntervalSec=20 +RequiresMountsFor=/opt/Mullvad\x20VPN/resources/ + +[Service] +Restart=always +RestartSec=1 +ExecStart=/usr/bin/mullvad-daemon -v --disable-stdout-timestamps +Environment="MULLVAD_RESOURCE_DIR=/opt/Mullvad VPN/resources/" + +[Install] +WantedBy=multi-user.target diff --git a/desktop/mullvad-daemon-portable/portablectl-rs/Cargo.toml b/desktop/mullvad-daemon-portable/portablectl-rs/Cargo.toml new file mode 100644 index 0000000000..f4b4e56499 --- /dev/null +++ b/desktop/mullvad-daemon-portable/portablectl-rs/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "portablectl-rs" +version = "0.1.0" +edition.workspace = true +rust-version.workspace = true +repository.workspace = true +license.workspace = true + +[dependencies] +anyhow.workspace = true +clap = { workspace = true, features = ["derive", "env"] } +serde = { workspace = true, features = ["derive"] } +tokio = { workspace = true, features = ["full"] } +tracing = "0.1.44" +tracing-subscriber = { workspace = true, features = ["env-filter"] } +zbus = { version = "5.13.2", features = ["tokio"] } + +[lints] +workspace = true diff --git a/desktop/mullvad-daemon-portable/portablectl-rs/src/bus.rs b/desktop/mullvad-daemon-portable/portablectl-rs/src/bus.rs new file mode 100644 index 0000000000..5119b68896 --- /dev/null +++ b/desktop/mullvad-daemon-portable/portablectl-rs/src/bus.rs @@ -0,0 +1,77 @@ +use serde::Deserialize; +use zbus::zvariant::OwnedObjectPath; + +#[zbus::proxy( + interface = "org.freedesktop.portable1.Manager", + default_service = "org.freedesktop.portable1", + default_path = "/org/freedesktop/portable1" +)] + +pub trait PortabledD { + // TODO: return type is object-path + async fn get_image(&self, name: &str) -> zbus::Result<OwnedObjectPath>; + async fn list_images(&self) -> zbus::Result<Vec<ImageListing>>; + + /// Attach a portable service image. + /// + /// - `image` refers to a path or a name. + /// - if `runtime=true`, the image will not persist across reboots. + /// - `copy_mode` is one of `""`, `"copy"`, `"symlink"` `"mixed"`. + /// + /// ## dbus type signature: + /// ```systemd + /// AttachImage(in s image, + /// in as matches, + /// in s profile, + /// in b runtime, + /// in s copy_mode, + /// out a(sss) changes); + /// ``` + #[zbus(allow_interactive_auth)] + async fn attach_image( + &self, + image: &str, + matches: &[&str], + profile: &str, + runtime: bool, + copy_mode: &str, + ) -> zbus::Result<Vec<Change>>; + + /// Detach a portable service image. + /// + /// - `image` refers to a path or a name. + /// - `runtime` indicates whether the image was attached only for the current boot session. + /// + /// ## dbus type signature: + /// ```systemd + /// AttachImage(in s image, + /// in as matches, + /// in s profile, + /// in b runtime, + /// in s copy_mode, + /// out a(sss) changes); + /// ``` + #[zbus(allow_interactive_auth)] + async fn detach_image(&self, image: &str, runtime: bool) -> zbus::Result<Vec<Change>>; +} + +/// A change that was applied to the system as a result of `PortableD::attach_image`. +#[derive(Clone, Debug, Deserialize, zbus::zvariant::Type)] +pub struct Change { + pub change_type: String, + pub path: String, + pub source: String, +} + +#[derive(Clone, Debug, Deserialize, zbus::zvariant::Type)] +pub struct ImageListing { + // TODO: field names + pub name: String, + pub image_type: String, + pub read_only: bool, + pub creation_time: u64, + pub modification_time: u64, + pub current_disk_space: u64, + pub usage: String, + pub object_path: OwnedObjectPath, // TODO: type is object-path +} diff --git a/desktop/mullvad-daemon-portable/portablectl-rs/src/main.rs b/desktop/mullvad-daemon-portable/portablectl-rs/src/main.rs new file mode 100644 index 0000000000..1b4e90a3a1 --- /dev/null +++ b/desktop/mullvad-daemon-portable/portablectl-rs/src/main.rs @@ -0,0 +1,127 @@ +use std::path::Path; + +use anyhow::Context; +use clap::Parser; + +use crate::bus::Change; + +mod bus; + +#[derive(Parser)] +struct Opt { + #[clap(long, env = "RUST_LOG", default_value = "info")] + log_filter: String, + + #[clap(subcommand)] + command: Command, +} + +#[derive(clap::Subcommand)] +enum Command { + List, + Attach { + image: String, + #[clap(long, default_value = "default")] + profile: String, + }, + Detach { + image: String, + }, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let opt = Opt::parse(); + + let fmt_subscriber = tracing_subscriber::FmtSubscriber::builder() + .with_env_filter(&opt.log_filter) + .finish(); + tracing::subscriber::set_global_default(fmt_subscriber) + .context("Failed to initialize tracing subscriber")?; + + tracing::info!("Connecting to dbus"); + let connection = zbus::connection::Builder::system()? + .auth_mechanism(zbus::AuthMechanism::External) + .build() + .await + .context("Failed to connect to session dbus")?; + + tracing::info!("Connecting to portabled"); + let portabled = bus::PortabledDProxy::new(&connection) + .await + .context("Failed to connect to dbus service")?; + + match opt.command { + Command::List => { + tracing::info!("Listing images"); + for image in portabled + .list_images() + .await + .context("Failed to list portabled images")? + { + tracing::info!("{image:#?}"); + } + } + Command::Attach { image, profile } => { + let image = if image.contains('/') { + let path = Path::new(&image); + let path = path.canonicalize().context("Failed to canonicalize path")?; + path.to_str() + .context("Path was not valid utf-8")? + .to_string() + } else { + image + }; + + let unit_file_matches = &[]; + let runtime = true; + let changes = portabled + .attach_image( + &image, + unit_file_matches, + &profile, + runtime, + "", // TODO + ) + .await + .context("Failed to attach portable service image")?; + + log_changes(&changes); + } + Command::Detach { image } => { + let image = if image.contains('/') { + let path = Path::new(&image); + let path = path.canonicalize().context("Failed to canonicalize path")?; + path.to_str() + .context("Path was not valid utf-8")? + .to_string() + } else { + image + }; + + let runtime = true; + let changes = portabled + .detach_image(&image, runtime) + .await + .context("Failed to detach portable service")?; + log_changes(&changes); + } + } + + Ok(()) +} + +fn log_changes(changes: &[Change]) { + for change in changes { + if change.source.is_empty() { + tracing::info!("- {} {:?}", change.change_type, change.path); + } else { + tracing::info!( + "- {} {:?} -> {:?}", + change.change_type, + change.source, + change.path + ); + } + } +} diff --git a/desktop/mullvad-daemon-portable/repart.d/10-root.conf b/desktop/mullvad-daemon-portable/repart.d/10-root.conf new file mode 100644 index 0000000000..e94f0f8fd0 --- /dev/null +++ b/desktop/mullvad-daemon-portable/repart.d/10-root.conf @@ -0,0 +1,19 @@ +[Partition] +Type=root +Format=btrfs +Label=root + +SizeMinBytes=1M +SizeMaxBytes=1G + +# don't sign the image +Verity=off + +CopyFiles=/dev +CopyFiles=/etc +CopyFiles=/proc +CopyFiles=/run +CopyFiles=/sys +CopyFiles=/tmp +CopyFiles=/usr +CopyFiles=/var diff --git a/desktop/mullvad-daemon-portable/test.sh b/desktop/mullvad-daemon-portable/test.sh new file mode 100644 index 0000000000..6ea8d65c64 --- /dev/null +++ b/desktop/mullvad-daemon-portable/test.sh @@ -0,0 +1,7 @@ +systemctl stop mullvad-portable.service +portablectl detach ./mullvad-portable.service +portablectl attach --profile=trusted ./mullvad-portable.service +systemctl start mullvad-portable.service +systemctl status mullvad-portable.service +journalctl -xefu mullvad-portable.service + |
