From 355f74318d1af6b836a0cc2c58449cf0827dc247 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Wed, 16 Oct 2024 12:19:08 +0300 Subject: [PATCH 01/63] [service] Fix check for invalid kext handle (#1716) * [service] Fix check for invalid kext handle * [windows_kext] Use BTreeMap as cache structure * [windows_kext] Fix synchronization bug * Update windows_kext/kextinterface/kext_file.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update windows_kext/kextinterface/kext_file.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update windows_kext/kextinterface/kext_file.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- windows_kext/driver/Cargo.lock | 54 --------------- windows_kext/driver/Cargo.toml | 1 - windows_kext/driver/src/bandwidth.rs | 40 +++++------ windows_kext/driver/src/connection_cache.rs | 73 +-------------------- windows_kext/driver/src/connection_map.rs | 12 +--- windows_kext/driver/src/driver_hashmap.rs | 25 ------- windows_kext/driver/src/lib.rs | 1 - windows_kext/driver/src/stream_callouts.rs | 15 +++-- windows_kext/kextinterface/kext.go | 10 +-- windows_kext/kextinterface/kext_file.go | 51 +++++++++++++- 10 files changed, 86 insertions(+), 196 deletions(-) delete mode 100644 windows_kext/driver/src/driver_hashmap.rs diff --git a/windows_kext/driver/Cargo.lock b/windows_kext/driver/Cargo.lock index b8746745..4a0e0b39 100644 --- a/windows_kext/driver/Cargo.lock +++ b/windows_kext/driver/Cargo.lock @@ -2,18 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "atomic-polyfill" version = "1.0.3" @@ -57,7 +45,6 @@ checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" name = "driver" version = "0.0.0" dependencies = [ - "hashbrown", "num", "num-derive", "num-traits", @@ -76,15 +63,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", -] - [[package]] name = "heapless" version = "0.7.17" @@ -217,12 +195,6 @@ dependencies = [ "syn", ] -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - [[package]] name = "proc-macro2" version = "1.0.78" @@ -316,12 +288,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "wdk" version = "0.0.0" @@ -399,23 +365,3 @@ source = "git+https://github.com/microsoft/windows-rs?rev=dffa8b03dc4987c278d82e name = "windows_x86_64_msvc" version = "0.52.5" source = "git+https://github.com/microsoft/windows-rs?rev=dffa8b03dc4987c278d82e88015ffe96aa8ac317#dffa8b03dc4987c278d82e88015ffe96aa8ac317" - -[[package]] -name = "zerocopy" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/windows_kext/driver/Cargo.toml b/windows_kext/driver/Cargo.toml index 66dffaca..034627c0 100644 --- a/windows_kext/driver/Cargo.toml +++ b/windows_kext/driver/Cargo.toml @@ -17,7 +17,6 @@ num = { version = "0.4", default-features = false } num-derive = { version = "0.4", default-features = false } num-traits = { version = "0.2", default-features = false } smoltcp = { version = "0.10", default-features = false, features = ["proto-ipv4", "proto-ipv6"] } -hashbrown = { version = "0.14.3", default-features = false, features = ["ahash"]} # WARNING: Do not update. The version was choosen for a reason. See wdk/README.md for more detiels. [dependencies.windows-sys] diff --git a/windows_kext/driver/src/bandwidth.rs b/windows_kext/driver/src/bandwidth.rs index 4fb48786..0105ac72 100644 --- a/windows_kext/driver/src/bandwidth.rs +++ b/windows_kext/driver/src/bandwidth.rs @@ -1,14 +1,10 @@ +use alloc::collections::BTreeMap; use protocol::info::{BandwidthValueV4, BandwidthValueV6, Info}; use smoltcp::wire::{IpProtocol, Ipv4Address, Ipv6Address}; use wdk::rw_spin_lock::RwSpinLock; -use crate::driver_hashmap::DeviceHashMap; - -#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] -pub struct Key
-where - Address: Eq + PartialEq, -{ +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] +pub struct Key { pub local_ip: Address, pub local_port: u16, pub remote_ip: Address, @@ -25,32 +21,32 @@ enum Direction { Rx(usize), } pub struct Bandwidth { - stats_tcp_v4: DeviceHashMap, Value>, + stats_tcp_v4: BTreeMap, Value>, stats_tcp_v4_lock: RwSpinLock, - stats_tcp_v6: DeviceHashMap, Value>, + stats_tcp_v6: BTreeMap, Value>, stats_tcp_v6_lock: RwSpinLock, - stats_udp_v4: DeviceHashMap, Value>, + stats_udp_v4: BTreeMap, Value>, stats_udp_v4_lock: RwSpinLock, - stats_udp_v6: DeviceHashMap, Value>, + stats_udp_v6: BTreeMap, Value>, stats_udp_v6_lock: RwSpinLock, } impl Bandwidth { pub fn new() -> Self { Self { - stats_tcp_v4: DeviceHashMap::new(), + stats_tcp_v4: BTreeMap::new(), stats_tcp_v4_lock: RwSpinLock::default(), - stats_tcp_v6: DeviceHashMap::new(), + stats_tcp_v6: BTreeMap::new(), stats_tcp_v6_lock: RwSpinLock::default(), - stats_udp_v4: DeviceHashMap::new(), + stats_udp_v4: BTreeMap::new(), stats_udp_v4_lock: RwSpinLock::default(), - stats_udp_v6: DeviceHashMap::new(), + stats_udp_v6: BTreeMap::new(), stats_udp_v6_lock: RwSpinLock::default(), } } @@ -62,7 +58,7 @@ impl Bandwidth { if self.stats_tcp_v4.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_tcp_v4, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_tcp_v4, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -89,7 +85,7 @@ impl Bandwidth { if self.stats_tcp_v6.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_tcp_v6, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_tcp_v6, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -116,7 +112,7 @@ impl Bandwidth { if self.stats_udp_v4.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_udp_v4, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_udp_v4, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -140,10 +136,10 @@ impl Bandwidth { let stats_map; { let _guard = self.stats_udp_v6_lock.write_lock(); - if self.stats_tcp_v6.is_empty() { + if self.stats_udp_v6.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_tcp_v6, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_udp_v6, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -235,8 +231,8 @@ impl Bandwidth { ); } - fn update( - map: &mut DeviceHashMap, Value>, + fn update( + map: &mut BTreeMap, Value>, lock: &mut RwSpinLock, key: Key
, bytes: Direction, diff --git a/windows_kext/driver/src/connection_cache.rs b/windows_kext/driver/src/connection_cache.rs index 665e60f4..a076df02 100644 --- a/windows_kext/driver/src/connection_cache.rs +++ b/windows_kext/driver/src/connection_cache.rs @@ -1,10 +1,8 @@ -use core::time::Duration; - use crate::{ connection::{Connection, ConnectionV4, ConnectionV6, RedirectInfo, Verdict}, connection_map::{ConnectionMap, Key}, }; -use alloc::{format, string::String, vec::Vec}; +use alloc::vec::Vec; use smoltcp::wire::IpProtocol; use wdk::rw_spin_lock::RwSpinLock; @@ -128,73 +126,4 @@ impl ConnectionCache { return size; } - - #[allow(dead_code)] - pub fn get_full_cache_info(&self) -> String { - let mut info = String::new(); - let now = wdk::utils::get_system_timestamp_ms(); - { - let _guard = self.lock_v4.read_lock(); - for ((protocol, port), connections) in self.connections_v4.iter() { - info.push_str(&format!("{} -> {}\n", protocol, port,)); - for conn in connections { - let active_time_seconds = - Duration::from_millis(now - conn.get_last_accessed_time()).as_secs(); - info.push_str(&format!( - "\t{}:{} -> {}:{} {} last active {}m {}s ago", - conn.local_address, - conn.local_port, - conn.remote_address, - conn.remote_port, - conn.verdict, - active_time_seconds / 60, - active_time_seconds % 60 - )); - if conn.has_ended() { - let end_time_seconds = - Duration::from_millis(now - conn.get_end_time()).as_secs(); - info.push_str(&format!( - "\t ended {}m {}s ago", - end_time_seconds / 60, - end_time_seconds % 60 - )); - } - info.push('\n'); - } - } - } - - { - let _guard = self.lock_v6.read_lock(); - for ((protocol, port), connections) in self.connections_v6.iter() { - info.push_str(&format!("{} -> {} \n", protocol, port)); - for conn in connections { - let active_time_seconds = - Duration::from_millis(now - conn.get_last_accessed_time()).as_secs(); - info.push_str(&format!( - "\t{}:{} -> {}:{} {} last active {}m {}s ago", - conn.local_address, - conn.local_port, - conn.remote_address, - conn.remote_port, - conn.verdict, - active_time_seconds / 60, - active_time_seconds % 60 - )); - if conn.has_ended() { - let end_time_seconds = - Duration::from_millis(now - conn.get_end_time()).as_secs(); - info.push_str(&format!( - "\t ended {}m {}s ago", - end_time_seconds / 60, - end_time_seconds % 60 - )); - } - info.push('\n'); - } - } - } - - return info; - } } diff --git a/windows_kext/driver/src/connection_map.rs b/windows_kext/driver/src/connection_map.rs index bf2210f8..7cadf87b 100644 --- a/windows_kext/driver/src/connection_map.rs +++ b/windows_kext/driver/src/connection_map.rs @@ -1,8 +1,7 @@ use core::{fmt::Display, time::Duration}; use crate::connection::Connection; -use alloc::vec::Vec; -use hashbrown::HashMap; +use alloc::{collections::BTreeMap, vec::Vec}; use smoltcp::wire::{IpAddress, IpProtocol}; #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord)] @@ -63,11 +62,11 @@ impl Key { } } -pub struct ConnectionMap(HashMap<(IpProtocol, u16), Vec>); +pub struct ConnectionMap(BTreeMap<(IpProtocol, u16), Vec>); impl ConnectionMap { pub fn new() -> Self { - Self(HashMap::new()) + Self(BTreeMap::new()) } pub fn add(&mut self, conn: T) { @@ -164,7 +163,6 @@ impl ConnectionMap { self.0.retain(|_, v| !v.is_empty()); } - #[allow(dead_code)] pub fn get_count(&self) -> usize { let mut count = 0; for conn in self.0.values() { @@ -172,8 +170,4 @@ impl ConnectionMap { } return count; } - - pub fn iter(&self) -> hashbrown::hash_map::Iter<'_, (IpProtocol, u16), Vec> { - self.0.iter() - } } diff --git a/windows_kext/driver/src/driver_hashmap.rs b/windows_kext/driver/src/driver_hashmap.rs deleted file mode 100644 index 1c8b706a..00000000 --- a/windows_kext/driver/src/driver_hashmap.rs +++ /dev/null @@ -1,25 +0,0 @@ -use core::ops::{Deref, DerefMut}; - -use hashbrown::HashMap; - -pub struct DeviceHashMap(Option>); - -impl DeviceHashMap { - pub fn new() -> Self { - Self(Some(HashMap::new())) - } -} - -impl Deref for DeviceHashMap { - type Target = HashMap; - - fn deref(&self) -> &Self::Target { - self.0.as_ref().unwrap() - } -} - -impl DerefMut for DeviceHashMap { - fn deref_mut(&mut self) -> &mut Self::Target { - self.0.as_mut().unwrap() - } -} diff --git a/windows_kext/driver/src/lib.rs b/windows_kext/driver/src/lib.rs index d13e9d3f..7d9fe3a1 100644 --- a/windows_kext/driver/src/lib.rs +++ b/windows_kext/driver/src/lib.rs @@ -13,7 +13,6 @@ mod connection; mod connection_cache; mod connection_map; mod device; -mod driver_hashmap; mod entry; mod id_cache; pub mod logger; diff --git a/windows_kext/driver/src/stream_callouts.rs b/windows_kext/driver/src/stream_callouts.rs index a6393764..f0a0f0d0 100644 --- a/windows_kext/driver/src/stream_callouts.rs +++ b/windows_kext/driver/src/stream_callouts.rs @@ -4,6 +4,8 @@ use wdk::filter_engine::{callout_data::CalloutData, layer, net_buffer::NetBuffer use crate::{bandwidth, connection::Direction}; pub fn stream_layer_tcp_v4(data: CalloutData) { + type Fields = layer::FieldsStreamV4; + let Some(device) = crate::entry::get_device() else { return; }; @@ -16,7 +18,6 @@ pub fn stream_layer_tcp_v4(data: CalloutData) { } else { return; }; - type Fields = layer::FieldsStreamV4; let local_ip = Ipv4Address::from_bytes( &data .get_value_u32(Fields::IpLocalAddress as usize) @@ -56,6 +57,8 @@ pub fn stream_layer_tcp_v4(data: CalloutData) { } pub fn stream_layer_tcp_v6(data: CalloutData) { + type Fields = layer::FieldsStreamV6; + let Some(device) = crate::entry::get_device() else { return; }; @@ -68,16 +71,18 @@ pub fn stream_layer_tcp_v6(data: CalloutData) { } else { return; }; - type Fields = layer::FieldsStreamV6; + if data_length == 0 { return; } let local_ip = Ipv6Address::from_bytes(data.get_value_byte_array16(Fields::IpLocalAddress as usize)); let local_port = data.get_value_u16(Fields::IpLocalPort as usize); + let remote_ip = Ipv6Address::from_bytes(data.get_value_byte_array16(Fields::IpRemoteAddress as usize)); let remote_port = data.get_value_u16(Fields::IpRemotePort as usize); + match direction { Direction::Outbound => { device.bandwidth_stats.update_tcp_v6_tx( @@ -105,6 +110,8 @@ pub fn stream_layer_tcp_v6(data: CalloutData) { } pub fn stream_layer_udp_v4(data: CalloutData) { + type Fields = layer::FieldsDatagramDataV4; + let Some(device) = crate::entry::get_device() else { return; }; @@ -112,7 +119,6 @@ pub fn stream_layer_udp_v4(data: CalloutData) { for nbl in NetBufferListIter::new(data.get_layer_data() as _) { data_length += nbl.get_data_length() as usize; } - type Fields = layer::FieldsDatagramDataV4; let mut direction = Direction::Inbound; if data.get_value_u8(Fields::Direction as usize) == 0 { direction = Direction::Outbound; @@ -157,6 +163,8 @@ pub fn stream_layer_udp_v4(data: CalloutData) { } pub fn stream_layer_udp_v6(data: CalloutData) { + type Fields = layer::FieldsDatagramDataV6; + let Some(device) = crate::entry::get_device() else { return; }; @@ -164,7 +172,6 @@ pub fn stream_layer_udp_v6(data: CalloutData) { for nbl in NetBufferListIter::new(data.get_layer_data() as _) { data_length += nbl.get_data_length() as usize; } - type Fields = layer::FieldsDatagramDataV6; let mut direction = Direction::Inbound; if data.get_value_u8(Fields::Direction as usize) == 0 { direction = Direction::Outbound; diff --git a/windows_kext/kextinterface/kext.go b/windows_kext/kextinterface/kext.go index 8322ead8..c9b61c7c 100644 --- a/windows_kext/kextinterface/kext.go +++ b/windows_kext/kextinterface/kext.go @@ -38,7 +38,7 @@ var ( ) const ( - winInvalidHandleValue = windows.Handle(^uintptr(0)) // Max value + winInvalidHandleValue = windows.InvalidHandle stopServiceTimeoutDuration = time.Duration(30 * time.Second) ) @@ -48,7 +48,7 @@ type KextService struct { } func (s *KextService) isValid() bool { - return s != nil && s.handle != winInvalidHandleValue && s.handle != 0 + return s != nil && s.handle != windows.InvalidHandle && s.handle != 0 } func (s *KextService) isRunning() (bool, error) { @@ -99,7 +99,7 @@ func (s *KextService) Start(wait bool) error { _ = windows.ControlService(s.handle, windows.SERVICE_CONTROL_STOP, &status) _ = windows.DeleteService(s.handle) _ = windows.CloseServiceHandle(s.handle) - s.handle = winInvalidHandleValue + s.handle = windows.InvalidHandle return err } } @@ -158,7 +158,7 @@ func (s *KextService) Delete() error { return fmt.Errorf("failed to close service handle: %s", err) } - s.handle = winInvalidHandleValue + s.handle = windows.InvalidHandle return nil } @@ -234,7 +234,7 @@ func CreateKextService(driverName string, driverPath string) (*KextService, erro return nil, err } - service = winInvalidHandleValue + service = windows.InvalidHandle log.Warning("kext: old driver service was deleted successfully") } diff --git a/windows_kext/kextinterface/kext_file.go b/windows_kext/kextinterface/kext_file.go index 045ee06e..fac6c5cd 100644 --- a/windows_kext/kextinterface/kext_file.go +++ b/windows_kext/kextinterface/kext_file.go @@ -4,6 +4,8 @@ package kextinterface import ( + "fmt" + "golang.org/x/sys/windows" ) @@ -13,7 +15,16 @@ type KextFile struct { read_slice []byte } +// Read tries to read the supplied buffer length from the driver. +// The data from the driver is read in chunks `len(f.buffer)` and the extra data is cached for the next call. +// The performance penalty of calling the function with small buffers is very small. +// The function will block until the next info packet is received from the kext. func (f *KextFile) Read(buffer []byte) (int, error) { + if err := f.IsValid(); err != nil { + return 0, fmt.Errorf("failed to read: %w", err) + } + + // If no data is available from previous calls, read from kext. if f.read_slice == nil || len(f.read_slice) == 0 { err := f.refill_read_buffer() if err != nil { @@ -22,14 +33,19 @@ func (f *KextFile) Read(buffer []byte) (int, error) { } if len(f.read_slice) >= len(buffer) { - // Write all requested bytes. + // There is enough data to fill the requested buffer. copy(buffer, f.read_slice[0:len(buffer)]) + // Move the slice to contain the remaining data. f.read_slice = f.read_slice[len(buffer):] } else { - // Write all available bytes and read again. + // There is not enough data to fill the requested buffer. + + // Write everything available. copy(buffer[0:len(f.read_slice)], f.read_slice) copiedBytes := len(f.read_slice) f.read_slice = nil + + // Read again. _, err := f.Read(buffer[copiedBytes:]) if err != nil { return 0, err @@ -51,20 +67,33 @@ func (f *KextFile) refill_read_buffer() error { return nil } +// Write sends the buffer bytes to the kext. The function will block until the whole buffer is written to the kext. func (f *KextFile) Write(buffer []byte) (int, error) { + if err := f.IsValid(); err != nil { + return 0, fmt.Errorf("failed to write: %w", err) + } var count uint32 = 0 overlapped := &windows.Overlapped{} err := windows.WriteFile(f.handle, buffer, &count, overlapped) return int(count), err } +// Close closes the handle to the kext. This will cancel all active Reads and Writes. func (f *KextFile) Close() error { + if err := f.IsValid(); err != nil { + return fmt.Errorf("failed to close: %w", err) + } err := windows.CloseHandle(f.handle) - f.handle = winInvalidHandleValue + f.handle = windows.InvalidHandle return err } +// deviceIOControl exists for compatibility with the old kext. func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) (*windows.Overlapped, error) { + if err := f.IsValid(); err != nil { + return nil, fmt.Errorf("failed to send io control: %w", err) + } + // Prepare the input data var inDataPtr *byte = nil var inDataSize uint32 = 0 if inData != nil { @@ -72,6 +101,7 @@ func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) ( inDataSize = uint32(len(inData)) } + // Prepare the output data var outDataPtr *byte = nil var outDataSize uint32 = 0 if outData != nil { @@ -79,6 +109,7 @@ func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) ( outDataSize = uint32(len(outData)) } + // Make the request to the kext. overlapped := &windows.Overlapped{} err := windows.DeviceIoControl(f.handle, code, @@ -92,6 +123,20 @@ func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) ( return overlapped, nil } +// GetHandle returns the handle of the kext. func (f *KextFile) GetHandle() windows.Handle { return f.handle } + +// IsValid checks if kext file holds a valid handle to the kext driver. +func (f *KextFile) IsValid() error { + if f == nil { + return fmt.Errorf("nil kext file") + } + + if f.handle == windows.Handle(0) || f.handle == windows.InvalidHandle { + return fmt.Errorf("invalid handle") + } + + return nil +} From d26ab22d92d36557cd3d2f9cd7f4efc92518e75d Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 16 Oct 2024 13:53:48 +0200 Subject: [PATCH 02/63] Bump kext version --- windows_kext/kextinterface/version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows_kext/kextinterface/version.txt b/windows_kext/kextinterface/version.txt index 19dfc079..5db4ff8e 100644 --- a/windows_kext/kextinterface/version.txt +++ b/windows_kext/kextinterface/version.txt @@ -1 +1 @@ -[2, 0, 3, 0] \ No newline at end of file +[2, 0, 4, 0] \ No newline at end of file From 145f5e67dee8f49cd7ac8170610fdc3ee3f1033c Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 28 Oct 2024 08:35:02 +0200 Subject: [PATCH 03/63] [windows_kext] Improve documentation (#1719) --- windows_kext/README.md | 46 ++++++++++++++++++--------------- windows_kext/protocol/README.md | 39 ++++++++++++++++++++++++++++ windows_kext/release/README.md | 5 ++-- 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/windows_kext/README.md b/windows_kext/README.md index f77de347..ce80d0b1 100644 --- a/windows_kext/README.md +++ b/windows_kext/README.md @@ -5,51 +5,55 @@ Implementation of Safing's Portmaster Windows kernel extension in Rust. - [Driver](driver/README.md) -> entry point. - [WDK](wdk/README.md) -> Windows Driver Kit interface. -- [Packet Path](PacketDoc.md) -> Detiled documentation of what happens to a packet when it enters the kernel extension. -- [Release](release/README.md) -> Guide how to do a release build +- [Packet Path](PacketFlow.md) -> Detailed documentation of what happens to a packet when it enters the kernel extension. +- [Release](release/README.md) -> Guide how to do a release build. +- [Windows Filtering Platform - MS](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/roadmap-for-developing-wfp-callout-drivers) -> The driver is build on top of WFP. + ### Building The Windows Portmaster Kernel Extension is currently only developed and tested for the amd64 (64-bit) architecture. -__Prerequesites:__ +__Prerequirements:__ - Visual Studio 2022 - Install C++ and Windows 11 SDK (22H2) components - Add `link.exe` and `signtool` in the PATH -- Rust +- Windows Driver Kit + - https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk +- Rust (Can be separate machine) - https://www.rust-lang.org/tools/install -- Cargo make(optional) - - https://github.com/sagiegurari/cargo-make __Setup Test Signing:__ -In order to test the driver on your machine, you will have to test sign it (starting with Windows 10). +> Not recommended for a work machine. Usually done on virtual machine dedicated for testing. +In order to test the driver on your machine, you will have to sign it (starting with Windows 10). Create a new certificate for test signing: - :: Open a *x64 Free Build Environment* console as Administrator. +```ps1 + # Open a *x64 Free Build Environment* console as Administrator. - :: Run the MakeCert.exe tool to create a test certificate: + # Run the MakeCert.exe tool to create a test certificate: MakeCert -r -pe -ss PrivateCertStore -n "CN=DriverCertificate" DriverCertificate.cer - :: Install the test certificate with CertMgr.exe: + # Install the test certificate with CertMgr.exe: CertMgr /add DriverCertificate.cer /s /r localMachine root - +``` Enable Test Signing on the dev machine: - - :: Before you can load test-signed drivers, you must enable Windows test mode. To do this, run this command: +```ps1 + # Before you can load test-signed drivers, you must enable Windows test mode. To do this, run this command: Bcdedit.exe -set TESTSIGNING ON - :: Then, restart Windows. For more information, see The TESTSIGNING Boot Configuration Option. - + # Then, restart Windows. For more information, see The TESTSIGNING Boot Configuration Option. +``` __Build driver:__ -``` -cd driver -cargo build +```sh + cd driver + cargo build ``` > Build also works on linux @@ -63,9 +67,9 @@ Run `link.bat`. - Install go - https://go.dev/dl/ -``` -cd kext_tester -go run . +```sh + cd kext_tester + go run . ``` > make sure the hardcoded path in main.go is pointing to the correct `.sys` file diff --git a/windows_kext/protocol/README.md b/windows_kext/protocol/README.md index cde5d85c..2547f988 100644 --- a/windows_kext/protocol/README.md +++ b/windows_kext/protocol/README.md @@ -2,3 +2,42 @@ Defines protocol that communicates with `kextinterface` / Portmaster. +The crate implements simple binary protocol. The communications is designed to be concurrent stream of packets. +Input and output work independent of each other. + - Pormtaster can read multiple info packets from the queue with single read request. + - Portmaster can write one command packet to the kernel extension with single write request. + +## Info: Kext -> Portmaster + +Info is a packet that sends information/events from the kernel extension to portmaster. +For example: `new connection`, `end of connection`, `bandwidth stats` ... check `info.rs` for full list. + +The Info packet contains a header that is 5 bytes +``` +0 1 2 3 4 +0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Info Type | Length | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` +> Note that one tick mark represents one bit position. + +The header is followed by the info data. + + +## Command: Portmaster -> Kext + +Command is a packet that portmaster sends to the kernel extension. +For example: `verdict response`, `shutdown`, `get logs` ... check `command.rs` for full list. + +The header of the command packet is 1 byte +``` +0 1 2 3 4 5 6 7 ++-+-+-+-+-+-+-+-+ +| Command Type | ++-+-+-+-+-+-+-+-+ +``` +> Note that one tick mark represents one bit position. + +Rest of the packet will be the payload of the command (some commands don't contain payload just the command type). + diff --git a/windows_kext/release/README.md b/windows_kext/release/README.md index 939f88d6..28898c9d 100644 --- a/windows_kext/release/README.md +++ b/windows_kext/release/README.md @@ -7,12 +7,13 @@ ### Generate the cab file - Copy the zip and extract it on a windows machine. - * Some version Visual Studio needs to be installed. + * Visual Studio 2022 and WDK need to be installed. - From VS Command Prompt / PowerShell run: ``` cd kext_release_v.../ ./build_cab.bat ``` +> Script is written for VS `$SDK_Version = "10.0.22621.0"`. If different version is used update the script. 3. Sing the cab file @@ -25,4 +26,4 @@ cd kext_release_v.../ - Wait for the process to finish, download the `.zip`. The zip will contain the release files. -> Optionally sign the .sys file. +> Optionally sign the .sys file, with company certificate. From af3bb804bf59e897a5ec184b0ecd121e28e26474 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Thu, 7 Nov 2024 15:52:26 +0200 Subject: [PATCH 04/63] Fix reading only the needed TCP/UDP header bytes (#1730) * [windows_kext] Fix reading only the needed TCP/UDP header bytes * [windows_kext] Disable debug mode * [windows_kext] Block all fragment packets * [windows_kext] Improve wording for compiler error --- windows_kext/driver/src/lib.rs | 5 +++++ windows_kext/driver/src/logger.rs | 5 +---- windows_kext/driver/src/packet_callouts.rs | 7 +++++++ windows_kext/driver/src/packet_util.rs | 13 +++++++------ windows_kext/wdk/src/filter_engine/callout_data.rs | 4 ++++ windows_kext/wdk/src/filter_engine/metadata.rs | 14 +++++++++++--- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/windows_kext/driver/src/lib.rs b/windows_kext/driver/src/lib.rs index 7d9fe3a1..45bc6c60 100644 --- a/windows_kext/driver/src/lib.rs +++ b/windows_kext/driver/src/lib.rs @@ -22,6 +22,11 @@ mod stream_callouts; use wdk::allocator::WindowsAllocator; +// For consistent behavior during development and production only release mode should be used. +// Certain behavior of the compiler will change and this can result in errors and different behavior in debug and release mode. +#[cfg(debug_assertions)] +compile_error!("Must be built in release mode to ensure consistent behavior and prevent optimization-related issues. Use `cargo build --release`."); + #[cfg(not(test))] use core::panic::PanicInfo; diff --git a/windows_kext/driver/src/logger.rs b/windows_kext/driver/src/logger.rs index 5a0440a2..129f9f7c 100644 --- a/windows_kext/driver/src/logger.rs +++ b/windows_kext/driver/src/logger.rs @@ -6,11 +6,8 @@ use core::{ }; use protocol::info::{Info, Severity}; -#[cfg(not(debug_assertions))] pub const LOG_LEVEL: u8 = Severity::Warning as u8; - -#[cfg(debug_assertions)] -pub const LOG_LEVEL: u8 = Severity::Trace as u8; +// pub const LOG_LEVEL: u8 = Severity::Trace as u8; pub const MAX_LOG_LINE_SIZE: usize = 150; diff --git a/windows_kext/driver/src/packet_callouts.rs b/windows_kext/driver/src/packet_callouts.rs index fb3ee90b..4609aad0 100644 --- a/windows_kext/driver/src/packet_callouts.rs +++ b/windows_kext/driver/src/packet_callouts.rs @@ -110,6 +110,13 @@ fn ip_packet_layer( interface_index: u32, sub_interface_index: u32, ) { + // Block all fragment data. No easy way to keep track of the origin and they are rarely used. + if data.is_fragment_data() { + data.action_block(); + crate::err!("blocked fragment packet"); + return; + } + let Some(device) = crate::entry::get_device() else { return; }; diff --git a/windows_kext/driver/src/packet_util.rs b/windows_kext/driver/src/packet_util.rs index 42b4dac7..6f5b4eb3 100644 --- a/windows_kext/driver/src/packet_util.rs +++ b/windows_kext/driver/src/packet_util.rs @@ -245,8 +245,6 @@ fn print_packet(packet: &[u8]) { /// /// * `Ok(Key)` - A key containing the protocol, local and remote addresses and ports. /// * `Err(String)` - An error message if the function fails to get net_buffer data. -const HEADERS_LEN: usize = smoltcp::wire::IPV4_HEADER_LEN + smoltcp::wire::TCP_HEADER_LEN; - fn get_ports(packet: &[u8], protocol: smoltcp::wire::IpProtocol) -> (u16, u16) { match protocol { smoltcp::wire::IpProtocol::Tcp => { @@ -262,12 +260,13 @@ fn get_ports(packet: &[u8], protocol: smoltcp::wire::IpProtocol) -> (u16, u16) { } pub fn get_key_from_nbl_v4(nbl: &NetBufferList, direction: Direction) -> Result { - // Get bytes - let mut headers = [0; HEADERS_LEN]; + // Get first bytes of the packet. IP header + src port (2 bytes) + dst port (2 bytes) + let mut headers = [0; smoltcp::wire::IPV4_HEADER_LEN + 4]; if nbl.read_bytes(&mut headers).is_err() { return Err("failed to get net_buffer data".to_string()); } + // This will panic in debug mode, probably because of runtime checks. // Parse packet let ip_packet = Ipv4Packet::new_unchecked(&headers); let (src_port, dst_port) = get_ports( @@ -307,11 +306,13 @@ pub fn get_key_from_nbl_v4(nbl: &NetBufferList, direction: Direction) -> Result< /// * `Ok(Key)` - A key containing the protocol, local and remote addresses and ports. /// * `Err(String)` - An error message if the function fails to get net_buffer data. pub fn get_key_from_nbl_v6(nbl: &NetBufferList, direction: Direction) -> Result { - // Get bytes - let mut headers = [0; smoltcp::wire::IPV6_HEADER_LEN + smoltcp::wire::TCP_HEADER_LEN]; + // Get first bytes of the packet. IP header + src port (2 bytes) + dst port (2 bytes) + let mut headers = [0; smoltcp::wire::IPV6_HEADER_LEN + 4]; let Ok(()) = nbl.read_bytes(&mut headers) else { return Err("failed to get net_buffer data".to_string()); }; + + // This will panic in debug mode, probably because of runtime checks. // Parse packet let ip_packet = Ipv6Packet::new_unchecked(&headers); let (src_port, dst_port) = get_ports( diff --git a/windows_kext/wdk/src/filter_engine/callout_data.rs b/windows_kext/wdk/src/filter_engine/callout_data.rs index bb861f84..abb5e318 100644 --- a/windows_kext/wdk/src/filter_engine/callout_data.rs +++ b/windows_kext/wdk/src/filter_engine/callout_data.rs @@ -133,6 +133,10 @@ impl<'a> CalloutData<'a> { } } + pub fn is_fragment_data(&self) -> bool { + unsafe { (*self.metadata).is_fragment_data() } + } + pub fn pend_operation( &mut self, packet_list: Option, diff --git a/windows_kext/wdk/src/filter_engine/metadata.rs b/windows_kext/wdk/src/filter_engine/metadata.rs index 632830fa..55b3b7de 100644 --- a/windows_kext/wdk/src/filter_engine/metadata.rs +++ b/windows_kext/wdk/src/filter_engine/metadata.rs @@ -7,9 +7,9 @@ use windows_sys::Win32::{ NetworkManagement::{ IpHelper::IP_ADDRESS_PREFIX, WindowsFilteringPlatform::{ - FWPS_METADATA_FIELD_COMPLETION_HANDLE, FWPS_METADATA_FIELD_PROCESS_ID, - FWPS_METADATA_FIELD_PROCESS_PATH, FWPS_METADATA_FIELD_REMOTE_SCOPE_ID, - FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA, + FWPS_METADATA_FIELD_COMPLETION_HANDLE, FWPS_METADATA_FIELD_FRAGMENT_DATA, + FWPS_METADATA_FIELD_PROCESS_ID, FWPS_METADATA_FIELD_PROCESS_PATH, + FWPS_METADATA_FIELD_REMOTE_SCOPE_ID, FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA, FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE, FWP_BYTE_BLOB, FWP_DIRECTION, }, }, @@ -137,6 +137,14 @@ impl FwpsIncomingMetadataValues { None } + pub(crate) fn is_fragment_data(&self) -> bool { + if self.has_field(FWPS_METADATA_FIELD_FRAGMENT_DATA) { + return self.fragment_metadata.fragment_offset != 0; + } + + false + } + pub(crate) unsafe fn get_control_data(&self) -> Option> { if self.has_field(FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA) { if self.control_data.is_null() || self.control_data_length == 0 { From a99b68ec9144357ea70c4f6ce47996d37b38c218 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 15:10:41 +0100 Subject: [PATCH 05/63] Warn instead of failing when process username cannot be found --- service/process/process.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/process/process.go b/service/process/process.go index 60dac7eb..4e0eeeae 100644 --- a/service/process/process.go +++ b/service/process/process.go @@ -256,7 +256,7 @@ func loadProcess(ctx context.Context, key string, pInfo *processInfo.Process) (* // Username process.UserName, err = pInfo.UsernameWithContext(ctx) if err != nil { - return nil, fmt.Errorf("process: failed to get Username for p%d: %w", pInfo.Pid, err) + log.Tracer(ctx).Warningf("process: failed to get username (PID %d): %s", pInfo.Pid, err) } // TODO: User Home From 07acb9befac484982e0ff5b7e362d82d5ba45096 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 15:11:07 +0100 Subject: [PATCH 06/63] Notify packet issues asynchronously --- service/compat/callbacks.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/service/compat/callbacks.go b/service/compat/callbacks.go index 2abfa858..71fd8b69 100644 --- a/service/compat/callbacks.go +++ b/service/compat/callbacks.go @@ -3,6 +3,7 @@ package compat import ( "net" + "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/network/packet" "github.com/safing/portmaster/service/process" ) @@ -31,10 +32,16 @@ func SubmitDNSCheckDomain(subdomain string) (respondWith net.IP) { // ReportSecureDNSBypassIssue reports a DNS bypassing issue for the given process. func ReportSecureDNSBypassIssue(p *process.Process) { - secureDNSBypassIssue.notify(p) + module.mgr.Go("report secure dns bypass issue", func(w *mgr.WorkerCtx) error { + secureDNSBypassIssue.notify(p) + return nil + }) } // ReportMultiPeerUDPTunnelIssue reports a multi-peer UDP tunnel for the given process. func ReportMultiPeerUDPTunnelIssue(p *process.Process) { - multiPeerUDPTunnelIssue.notify(p) + module.mgr.Go("report multi-peer udp tunnel issue", func(w *mgr.WorkerCtx) error { + multiPeerUDPTunnelIssue.notify(p) + return nil + }) } From f4b96e1ce7ba95893c8dff929f6e0ef1e5b22809 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 15:13:44 +0100 Subject: [PATCH 07/63] Make saving IP and CNAMEs more defensive --- service/firewall/dns.go | 6 +++--- service/nameserver/nameserver.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/service/firewall/dns.go b/service/firewall/dns.go index 8a6e1973..9b1a55e5 100644 --- a/service/firewall/dns.go +++ b/service/firewall/dns.go @@ -302,11 +302,11 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw Expires: rrCache.Expires, } - // Resolve all CNAMEs in the correct order and add the to the record. + // Resolve all CNAMEs in the correct order and add the to the record - up to max 50 layers. domain := q.FQDN - for { + for range 50 { nextDomain, isCNAME := cnames[domain] - if !isCNAME { + if !isCNAME || nextDomain == domain { break } diff --git a/service/nameserver/nameserver.go b/service/nameserver/nameserver.go index c699cd99..1d346220 100644 --- a/service/nameserver/nameserver.go +++ b/service/nameserver/nameserver.go @@ -224,8 +224,8 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) } // Save the request as open, as we don't know if there will be a connection or not. - network.SaveOpenDNSRequest(q, rrCache, conn) firewall.UpdateIPsAndCNAMEs(q, rrCache, conn) + network.SaveOpenDNSRequest(q, rrCache, conn) case network.VerdictUndeterminable: fallthrough From 38e9e342f716f3bd469faa47efd65b64ac753255 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 15:42:49 +0100 Subject: [PATCH 08/63] Update deps --- go.mod | 42 ++++++++++++++--------------- go.sum | 85 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/go.mod b/go.mod index 436df094..80685cce 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ replace github.com/tc-hib/winres => github.com/dhaavi/winres v0.2.2 require ( fyne.io/systray v1.11.0 github.com/VictoriaMetrics/metrics v1.35.1 - github.com/Xuanwo/go-locale v1.1.1 + github.com/Xuanwo/go-locale v1.1.2 github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 github.com/agext/levenshtein v1.2.3 github.com/armon/go-radix v1.0.0 @@ -16,7 +16,7 @@ require ( github.com/bluele/gcache v0.0.2 github.com/brianvoe/gofakeit v3.18.0+incompatible github.com/cilium/ebpf v0.16.0 - github.com/coreos/go-iptables v0.7.0 + github.com/coreos/go-iptables v0.8.0 github.com/davecgh/go-spew v1.1.1 github.com/dgraph-io/badger v1.6.2 github.com/dhaavi/go-notify v0.0.0-20190209221809-c404b1f22435 @@ -32,8 +32,9 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.7.0 - github.com/jackc/puddle/v2 v2.2.1 + github.com/jackc/puddle/v2 v2.2.2 github.com/lmittmann/tint v1.0.5 + github.com/maruel/panicparse/v2 v2.3.1 github.com/mat/besticon v3.12.0+incompatible github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-isatty v0.0.20 @@ -44,7 +45,7 @@ require ( github.com/oschwald/maxminddb-golang v1.13.1 github.com/r3labs/diff/v3 v3.0.1 github.com/rot256/pblind v0.0.0-20240730113005-f3275049ead5 - github.com/safing/jess v0.3.4 + github.com/safing/jess v0.3.5 github.com/safing/structures v1.1.0 github.com/seehuhn/fortuna v1.0.1 github.com/shirou/gopsutil v3.21.11+incompatible @@ -54,18 +55,18 @@ require ( github.com/tannerryan/ring v1.1.2 github.com/tc-hib/winres v0.3.1 github.com/tevino/abool v1.2.0 - github.com/tidwall/gjson v1.17.3 + github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 github.com/vincent-petithory/dataurl v1.0.0 - go.etcd.io/bbolt v1.3.10 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/image v0.19.0 - golang.org/x/net v0.28.0 - golang.org/x/sync v0.8.0 - golang.org/x/sys v0.24.0 + go.etcd.io/bbolt v1.3.11 + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f + golang.org/x/image v0.22.0 + golang.org/x/net v0.31.0 + golang.org/x/sync v0.9.0 + golang.org/x/sys v0.27.0 gopkg.in/yaml.v3 v3.0.1 - zombiezen.com/go/sqlite v1.3.0 + zombiezen.com/go/sqlite v1.4.0 ) require ( @@ -89,8 +90,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.8 // indirect - github.com/maruel/panicparse/v2 v2.3.1 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -105,7 +105,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.8.0 // indirect + github.com/tklauser/numcpus v0.9.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect @@ -114,14 +114,14 @@ require ( github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zalando/go-keyring v0.2.5 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/text v0.20.0 // indirect + golang.org/x/tools v0.27.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - modernc.org/libc v1.59.9 // indirect + modernc.org/libc v1.61.0 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.32.0 // indirect + modernc.org/sqlite v1.33.1 // indirect ) diff --git a/go.sum b/go.sum index 50df69d6..4a0cac3f 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/VictoriaMetrics/metrics v1.35.1 h1:o84wtBKQbzLdDy14XeskkCZih6anG+veZ1SwJHFGwrU= github.com/VictoriaMetrics/metrics v1.35.1/go.mod h1:r7hveu6xMdUACXvB8TYdAj8WEsKzWB0EkpJN+RDtOf8= -github.com/Xuanwo/go-locale v1.1.1 h1:nhvzo1phY4LRwdrwVwKWXn5iZ0pMwwsa3o29yiDRuZc= -github.com/Xuanwo/go-locale v1.1.1/go.mod h1:ldC3FzZeMYALkL3YYpwhr4iVYdOIUx42kORcnAHdKUo= +github.com/Xuanwo/go-locale v1.1.2 h1:6H+olvrQcyVOZ+GAC2rXu4armacTT4ZrFCA0mB24XVo= +github.com/Xuanwo/go-locale v1.1.2/go.mod h1:1JBER4QV7Ji39GJ4AvVlfvqmTUqopzxQxdg2mXYOw94= github.com/aead/ecdh v0.2.0 h1:pYop54xVaq/CEREFEcukHRZfTdjiWvYIsZDXXrBapQQ= github.com/aead/ecdh v0.2.0/go.mod h1:a9HHtXuSo8J1Js1MwLQx2mBhkXMT6YwUmVVEY4tTB8U= github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 h1:5L8Mj9Co9sJVgW3TpYk2gxGJnDjsYuboNTcRmbtGKGs= @@ -38,8 +38,8 @@ github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= -github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= +github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -141,8 +141,8 @@ github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cO github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= -github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= @@ -159,8 +159,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786 h1:N527AHMa79 github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786/go.mod h1:v4hqbTdfQngbVSZJVWUhGE/lbTFf9jb+ygmNUDQMuOs= github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM= github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= -github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= -github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -246,8 +246,8 @@ github.com/rot256/pblind v0.0.0-20240730113005-f3275049ead5 h1:R/qQ2Hw5/BgVQS87p github.com/rot256/pblind v0.0.0-20240730113005-f3275049ead5/go.mod h1:NTdpGnZ/E2cKXTiAz824w1p6OIm0mBbXcyuiYPCi/Ps= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/safing/jess v0.3.4 h1:/p6ensqEUn2jI/z1EB9JUdwH4MJQirh/C9jEwNBzxw8= -github.com/safing/jess v0.3.4/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= +github.com/safing/jess v0.3.5 h1:KS5elTKfWcDUow8SUoCj5QdyyGJNoExJNySerNkbxUU= +github.com/safing/jess v0.3.5/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= github.com/safing/structures v1.1.0 h1:QzHBQBjaZSLzw2f6PM4ibSmPcfBHAOB5CKJ+k4FYkhQ= github.com/safing/structures v1.1.0/go.mod h1:QUrB74FcU41ahQ5oy3YNFCoSq+twE/n3+vNZc2K35II= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= @@ -291,8 +291,8 @@ github.com/tannerryan/ring v1.1.2/go.mod h1:DkELJEjbZhJBtFKR9Xziwj3HKZnb/knRgljN github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= -github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -302,8 +302,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= -github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= +github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 h1:UFHFmFfixpmfRBcxuu+LA9l8MdURWVdVNUHxO5n1d2w= github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26/go.mod h1:IGhd0qMDsUa9acVjsbsT7bu3ktadtGOHI79+idTew/M= @@ -333,26 +333,26 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= -go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= -golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= +golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g= +golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -374,15 +374,15 @@ golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -419,10 +419,9 @@ golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -430,16 +429,16 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -463,14 +462,14 @@ honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.20.7 h1:skrinQsjxWfvj6nbC3ztZPJy+NuwmB3hV9zX/pthNYQ= -modernc.org/ccgo/v4 v4.20.7/go.mod h1:UOkI3JSG2zT4E2ioHlncSOZsXbuDCZLvPi3uMlZT5GY= +modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4= +modernc.org/ccgo/v4 v4.21.0/go.mod h1:h6kt6H/A2+ew/3MW/p6KEoQmrq/i3pr0J/SiwiaF/g0= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/libc v1.59.9 h1:k+nNDDakwipimgmJ1D9H466LhFeSkaPPycAs1OZiDmY= -modernc.org/libc v1.59.9/go.mod h1:EY/egGEU7Ju66eU6SBqCNYaFUDuc4npICkMWnU5EE3A= +modernc.org/libc v1.61.0 h1:eGFcvWpqlnoGwzZeZe3PWJkkKbM/3SUGyk1DVZQ0TpE= +modernc.org/libc v1.61.0/go.mod h1:DvxVX89wtGTu+r72MLGhygpfi3aUGgZRdAYGCAVVud0= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -479,11 +478,11 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= -modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= +modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -zombiezen.com/go/sqlite v1.3.0 h1:98g1gnCm+CNz6AuQHu0gqyw7gR2WU3O3PJufDOStpUs= -zombiezen.com/go/sqlite v1.3.0/go.mod h1:yRl27//s/9aXU3RWs8uFQwjkTG9gYNGEls6+6SvrclY= +zombiezen.com/go/sqlite v1.4.0 h1:N1s3RIljwtp4541Y8rM880qgGIgq3fTD2yks1xftnKU= +zombiezen.com/go/sqlite v1.4.0/go.mod h1:0w9F1DN9IZj9AcLS9YDKMboubCACkwYCGkzoy3eG5ik= From a4b76843e5328aa3103b38ec4abdae1e137386d4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 17:39:49 +0100 Subject: [PATCH 09/63] Bump kext version --- windows_kext/kextinterface/version.txt | 2 +- windows_kext/release/README.md | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/windows_kext/kextinterface/version.txt b/windows_kext/kextinterface/version.txt index 5db4ff8e..ac4c24a6 100644 --- a/windows_kext/kextinterface/version.txt +++ b/windows_kext/kextinterface/version.txt @@ -1 +1 @@ -[2, 0, 4, 0] \ No newline at end of file +[2, 0, 5, 0] \ No newline at end of file diff --git a/windows_kext/release/README.md b/windows_kext/release/README.md index 28898c9d..319bbd2c 100644 --- a/windows_kext/release/README.md +++ b/windows_kext/release/README.md @@ -1,11 +1,13 @@ # Kext release tool ### Generate the zip file + - Make sure `kextinterface/version.txt` is up to date - Execute: `cargo run` * This will generate release `kext_release_vX-X-X.zip` file. Which contains all the necessary files to make the release. ### Generate the cab file + - Copy the zip and extract it on a windows machine. * Visual Studio 2022 and WDK need to be installed. - From VS Command Prompt / PowerShell run: @@ -15,9 +17,10 @@ cd kext_release_v.../ ``` > Script is written for VS `$SDK_Version = "10.0.22621.0"`. If different version is used update the script. -3. Sing the cab file +- Sing the cab file ### Let Microsoft Sign + - Go to https://partner.microsoft.com/en-us/dashboard/hardware/driver/New - Enter "PortmasterKext vX.X.X #1" as the product name - Upload `portmaster-kext_vX-X-X.cab` From fe070b4f564b3727758b408477b7d4c7cb822040 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 25 Nov 2024 14:03:35 +0200 Subject: [PATCH 10/63] Feature/kext default action drop (#1747) * [windows_kext] Make default action to drop * [windows_kext] Minor improvments --- windows_kext/driver/src/ale_callouts.rs | 3 +++ windows_kext/driver/src/packet_callouts.rs | 7 +++++-- windows_kext/wdk/src/filter_engine/callout_data.rs | 11 ++++------- windows_kext/wdk/src/filter_engine/classify.rs | 5 +++++ windows_kext/wdk/src/filter_engine/ffi.rs | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/windows_kext/driver/src/ale_callouts.rs b/windows_kext/driver/src/ale_callouts.rs index ed478938..51c5cc30 100644 --- a/windows_kext/driver/src/ale_callouts.rs +++ b/windows_kext/driver/src/ale_callouts.rs @@ -105,6 +105,9 @@ pub fn ale_layer_connect_v6(data: CalloutData) { } fn ale_layer_auth(mut data: CalloutData, ale_data: AleLayerData) { + // Make the default path as drop. + data.block_and_absorb(); + let Some(device) = crate::entry::get_device() else { return; }; diff --git a/windows_kext/driver/src/packet_callouts.rs b/windows_kext/driver/src/packet_callouts.rs index 4609aad0..1e8c28f1 100644 --- a/windows_kext/driver/src/packet_callouts.rs +++ b/windows_kext/driver/src/packet_callouts.rs @@ -110,9 +110,12 @@ fn ip_packet_layer( interface_index: u32, sub_interface_index: u32, ) { + // Make the default path as drop. + data.block_and_absorb(); + // Block all fragment data. No easy way to keep track of the origin and they are rarely used. if data.is_fragment_data() { - data.action_block(); + data.block_and_absorb(); crate::err!("blocked fragment packet"); return; } @@ -147,7 +150,7 @@ fn ip_packet_layer( } { Ok(key) => key, Err(err) => { - crate::dbg!("failed to get key from nbl: {}", err); + crate::err!("failed to get key from nbl: {}", err); return; } }; diff --git a/windows_kext/wdk/src/filter_engine/callout_data.rs b/windows_kext/wdk/src/filter_engine/callout_data.rs index abb5e318..ff155dd1 100644 --- a/windows_kext/wdk/src/filter_engine/callout_data.rs +++ b/windows_kext/wdk/src/filter_engine/callout_data.rs @@ -161,24 +161,28 @@ impl<'a> CalloutData<'a> { pub fn action_permit(&mut self) { unsafe { (*self.classify_out).action_permit(); + (*self.classify_out).clear_absorb_flag(); } } pub fn action_continue(&mut self) { unsafe { (*self.classify_out).action_continue(); + (*self.classify_out).clear_absorb_flag(); } } pub fn action_block(&mut self) { unsafe { (*self.classify_out).action_block(); + (*self.classify_out).clear_absorb_flag(); } } pub fn action_none(&mut self) { unsafe { (*self.classify_out).set_none(); + (*self.classify_out).clear_absorb_flag(); } } @@ -198,13 +202,6 @@ impl<'a> CalloutData<'a> { self.get_value_u32(flags_index) & FWP_CONDITION_FLAG_IS_REAUTHORIZE > 0 } - pub fn parmit_and_absorb(&mut self) { - unsafe { - (*self.classify_out).action_permit(); - (*self.classify_out).set_absorb(); - } - } - pub fn get_callout_id(&self) -> usize { self.callout_id } diff --git a/windows_kext/wdk/src/filter_engine/classify.rs b/windows_kext/wdk/src/filter_engine/classify.rs index 1acff2ed..6d5b9b05 100644 --- a/windows_kext/wdk/src/filter_engine/classify.rs +++ b/windows_kext/wdk/src/filter_engine/classify.rs @@ -80,6 +80,11 @@ impl ClassifyOut { self.flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } + // Removes the absorb flag. + pub fn clear_absorb_flag(&mut self) { + self.flags &= !FWPS_CLASSIFY_OUT_FLAG_ABSORB; + } + // Clear the write flag permission. Next filter in the chain will not change the action. pub fn clear_write_flag(&mut self) { self.rights &= !FWPS_RIGHT_ACTION_WRITE; diff --git a/windows_kext/wdk/src/filter_engine/ffi.rs b/windows_kext/wdk/src/filter_engine/ffi.rs index 45103272..bf5fa361 100644 --- a/windows_kext/wdk/src/filter_engine/ffi.rs +++ b/windows_kext/wdk/src/filter_engine/ffi.rs @@ -62,7 +62,7 @@ pub(crate) fn register_sublayer( sublayer.displayData.name = name.as_ptr() as _; sublayer.displayData.description = description.as_ptr() as _; sublayer.flags = 0; - sublayer.weight = 0xFFFF; + sublayer.weight = 0xFFFF; // Set to Max value. Weight compared to other sublayers. let status = FwpmSubLayerAdd0(filter_engine_handle, &sublayer, core::ptr::null_mut()); check_ntstatus(status as i32)?; From ca88c6d8adc8890d3f9c96beb7f14f0b687a75cf Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 26 Nov 2024 16:59:06 +0200 Subject: [PATCH 11/63] [desktop] Update tauri (#1760) --- Earthfile | 2 +- desktop/angular/package-lock.json | 134 +- desktop/angular/package.json | 14 +- desktop/tauri/src-tauri/Cargo.lock | 4280 ++++++++++++----- desktop/tauri/src-tauri/Cargo.toml | 22 +- .../src-tauri/gen/schemas/acl-manifests.json | 2 +- .../src-tauri/gen/schemas/desktop-schema.json | 2705 ++++------- .../src-tauri/gen/schemas/linux-schema.json | 2705 ++++------- .../src-tauri/gen/schemas/windows-schema.json | 2705 ++++------- desktop/tauri/src-tauri/src/traymenu.rs | 8 +- desktop/tauri/src-tauri/templates/main.wxs | 2 +- .../src-tauri/templates/main_original.wxs | 2 +- 12 files changed, 6438 insertions(+), 6143 deletions(-) diff --git a/Earthfile b/Earthfile index 9d016b08..de711d17 100644 --- a/Earthfile +++ b/Earthfile @@ -420,7 +420,7 @@ rust-base: DO rust+INIT --keep_fingerprints=true # For now we need tauri-cli 2.0.0 for bulding - DO rust+CARGO --args="install tauri-cli --version ^2.0.0-beta" + DO rust+CARGO --args="install tauri-cli --version 2.1.0" # Explicitly cache here. SAVE IMAGE --cache-hint diff --git a/desktop/angular/package-lock.json b/desktop/angular/package-lock.json index b8527c1d..8bf3faab 100644 --- a/desktop/angular/package-lock.json +++ b/desktop/angular/package-lock.json @@ -23,13 +23,13 @@ "@fortawesome/free-brands-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@tauri-apps/api": ">=2.0.0-rc.1", - "@tauri-apps/plugin-cli": ">=2.0.0-rc.1", - "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-rc.1", - "@tauri-apps/plugin-dialog": ">=2.0.0-rc.1", - "@tauri-apps/plugin-notification": ">=2.0.0-rc.1", - "@tauri-apps/plugin-os": ">=2.0.0-rc.1", - "@tauri-apps/plugin-shell": "^2.0.0-rc", + "@tauri-apps/api": ">=2.1.1", + "@tauri-apps/plugin-cli": ">=2.0.0", + "@tauri-apps/plugin-clipboard-manager": ">=2.0.0", + "@tauri-apps/plugin-dialog": ">=2.0.0", + "@tauri-apps/plugin-notification": ">=2.0.0", + "@tauri-apps/plugin-os": ">=2.0.0", + "@tauri-apps/plugin-shell": "^2.0.1", "autoprefixer": "^10.4.14", "d3": "^7.8.4", "data-urls": "^5.0.0", @@ -4406,9 +4406,9 @@ "peer": true }, "node_modules/@tauri-apps/api": { - "version": "2.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.4.tgz", - "integrity": "sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.1.1.tgz", + "integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==", "license": "Apache-2.0 OR MIT", "funding": { "type": "opencollective", @@ -4416,57 +4416,57 @@ } }, "node_modules/@tauri-apps/plugin-cli": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0-rc.1.tgz", - "integrity": "sha512-EcSTRfEU3zzlNbgwVtZVzqB19z3PNjyXD9H+YXuuLpV+Hwuh6Oi1fhUdCI0mp5zr9HSMWE+HzHkpBI7sVP1RyA==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0.tgz", + "integrity": "sha512-glQmlL1IiCGEa1FHYa/PTPSeYhfu56omLRgHXWlJECDt6DbJyRuJWVgtkQfUxtqnVdYnnU+DGIGeiInoEqtjLw==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-clipboard-manager": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.1.tgz", - "integrity": "sha512-hFgUABMmQuVGKwHb8PR9fuqfk0WRkedbWUt/ZV5sL4Q6kLrsp3JYJvtzVPeMYdeBvMqHl8WXNxAc/zwSld2h9w==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0.tgz", + "integrity": "sha512-V1sXmbjnwfXt/r48RJMwfUmDMSaP/8/YbH4CLNxt+/sf1eHlIP8PRFdFDQwLN0cNQKu2rqQVbG/Wc/Ps6cDUhw==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-dialog": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.1.tgz", - "integrity": "sha512-H28gh6BfZtjflHQ+HrmWwunDriBI3AQLAKnMs50GA6zeNUULqbQr7VXbAAKeJL/0CmWcecID4PKXVoSlaWRhEg==", - "license": "MIT or APACHE-2.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.1.tgz", + "integrity": "sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-notification": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-rc.1.tgz", - "integrity": "sha512-ddDj7xM8XR7Zv2vdpofNXlLjcp49p/VjlL0D+/eBcMuyooaLNMor3jz/+H6s23iHerdxMWA50mzy26BRN1BySA==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0.tgz", + "integrity": "sha512-6qEDYJS7mgXZWLXA0EFL+DVCJh8sJlzSoyw6B50pxhLPVFjc5Vr5DVzl5W3mUHaYhod5wsC984eQnlCCGqxYDA==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-os": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.1.tgz", - "integrity": "sha512-PV8zlSTmYfiN2xzILUmlDSEycS7UYbH2yXk/ZqF+qQU6/s+OVQvmSth4EhllFjcpvPbtqELvpzfjw+2qEouchA==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0.tgz", + "integrity": "sha512-M7hG/nNyQYTJxVG/UhTKhp9mpXriwWzrs9mqDreB8mIgqA3ek5nHLdwRZJWhkKjZrnDT4v9CpA9BhYeplTlAiA==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-shell": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.1.tgz", - "integrity": "sha512-JtNROc0rqEwN/g93ig5pK4cl1vUo2yn+osCpY9de64cy/d9hRzof7AuYOgvt/Xcd5VPQmlgo2AGvUh5sQRSR1A==", - "license": "MIT or APACHE-2.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.1.tgz", + "integrity": "sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tootallnate/once": { @@ -21067,56 +21067,56 @@ "peer": true }, "@tauri-apps/api": { - "version": "2.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.4.tgz", - "integrity": "sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.1.1.tgz", + "integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==" }, "@tauri-apps/plugin-cli": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0-rc.1.tgz", - "integrity": "sha512-EcSTRfEU3zzlNbgwVtZVzqB19z3PNjyXD9H+YXuuLpV+Hwuh6Oi1fhUdCI0mp5zr9HSMWE+HzHkpBI7sVP1RyA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0.tgz", + "integrity": "sha512-glQmlL1IiCGEa1FHYa/PTPSeYhfu56omLRgHXWlJECDt6DbJyRuJWVgtkQfUxtqnVdYnnU+DGIGeiInoEqtjLw==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-clipboard-manager": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.1.tgz", - "integrity": "sha512-hFgUABMmQuVGKwHb8PR9fuqfk0WRkedbWUt/ZV5sL4Q6kLrsp3JYJvtzVPeMYdeBvMqHl8WXNxAc/zwSld2h9w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0.tgz", + "integrity": "sha512-V1sXmbjnwfXt/r48RJMwfUmDMSaP/8/YbH4CLNxt+/sf1eHlIP8PRFdFDQwLN0cNQKu2rqQVbG/Wc/Ps6cDUhw==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-dialog": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.1.tgz", - "integrity": "sha512-H28gh6BfZtjflHQ+HrmWwunDriBI3AQLAKnMs50GA6zeNUULqbQr7VXbAAKeJL/0CmWcecID4PKXVoSlaWRhEg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.1.tgz", + "integrity": "sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-notification": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-rc.1.tgz", - "integrity": "sha512-ddDj7xM8XR7Zv2vdpofNXlLjcp49p/VjlL0D+/eBcMuyooaLNMor3jz/+H6s23iHerdxMWA50mzy26BRN1BySA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0.tgz", + "integrity": "sha512-6qEDYJS7mgXZWLXA0EFL+DVCJh8sJlzSoyw6B50pxhLPVFjc5Vr5DVzl5W3mUHaYhod5wsC984eQnlCCGqxYDA==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-os": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.1.tgz", - "integrity": "sha512-PV8zlSTmYfiN2xzILUmlDSEycS7UYbH2yXk/ZqF+qQU6/s+OVQvmSth4EhllFjcpvPbtqELvpzfjw+2qEouchA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0.tgz", + "integrity": "sha512-M7hG/nNyQYTJxVG/UhTKhp9mpXriwWzrs9mqDreB8mIgqA3ek5nHLdwRZJWhkKjZrnDT4v9CpA9BhYeplTlAiA==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-shell": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.1.tgz", - "integrity": "sha512-JtNROc0rqEwN/g93ig5pK4cl1vUo2yn+osCpY9de64cy/d9hRzof7AuYOgvt/Xcd5VPQmlgo2AGvUh5sQRSR1A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.1.tgz", + "integrity": "sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tootallnate/once": { diff --git a/desktop/angular/package.json b/desktop/angular/package.json index 5e916e51..2b0f9ea2 100644 --- a/desktop/angular/package.json +++ b/desktop/angular/package.json @@ -37,13 +37,13 @@ "@fortawesome/free-brands-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@tauri-apps/api": ">=2.0.0-rc.1", - "@tauri-apps/plugin-cli": ">=2.0.0-rc.1", - "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-rc.1", - "@tauri-apps/plugin-dialog": ">=2.0.0-rc.1", - "@tauri-apps/plugin-notification": ">=2.0.0-rc.1", - "@tauri-apps/plugin-os": ">=2.0.0-rc.1", - "@tauri-apps/plugin-shell": "^2.0.0-rc", + "@tauri-apps/api": ">=2.1.1", + "@tauri-apps/plugin-cli": ">=2.0.0", + "@tauri-apps/plugin-clipboard-manager": ">=2.0.0", + "@tauri-apps/plugin-dialog": ">=2.0.0", + "@tauri-apps/plugin-notification": ">=2.0.0", + "@tauri-apps/plugin-os": ">=2.0.0", + "@tauri-apps/plugin-shell": "^2.0.1", "autoprefixer": "^10.4.14", "d3": "^7.8.4", "data-urls": "^5.0.0", diff --git a/desktop/tauri/src-tauri/Cargo.lock b/desktop/tauri/src-tauri/Cargo.lock index 8d938985..ee45ef31 100644 --- a/desktop/tauri/src-tauri/Cargo.lock +++ b/desktop/tauri/src-tauri/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "android-tzdata" @@ -156,9 +156,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -171,43 +171,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "app" @@ -215,7 +215,7 @@ version = "0.1.0" dependencies = [ "assert_matches", "cached", - "clap 4.5.16", + "clap 4.5.21", "ctor", "dark-light", "dataurl", @@ -228,12 +228,12 @@ dependencies = [ "glib-sys", "gtk", "gtk-sys", - "http", + "http 1.1.0", "lazy_static", "log", "notify-rust", "open", - "reqwest", + "reqwest 0.12.9", "rfd", "rust-ini", "serde", @@ -251,7 +251,7 @@ dependencies = [ "tauri-plugin-single-instance", "tauri-plugin-window-state", "tauri-winrt-notification 0.3.1", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-websockets", "url", @@ -261,6 +261,170 @@ dependencies = [ "windows-service", ] +[[package]] +name = "app-store-connect" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fb5489b9bfcfa3aec2f68cc79eafb999b5af9b9d9d70ca8dfe36acdd1b2b05" +dependencies = [ + "anyhow", + "base64 0.21.7", + "clap 4.5.21", + "dirs 5.0.1", + "env_logger 0.10.2", + "jsonwebtoken", + "log", + "pem", + "rand 0.8.5", + "reqwest 0.11.27", + "rsa", + "serde", + "serde_json", + "thiserror 1.0.69", + "x509-certificate", +] + +[[package]] +name = "apple-bundles" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb7c27ee2ca7826adfdc84228cd4c5a84ab57b0a11d269d1d7cd0615238e5a2" +dependencies = [ + "anyhow", + "plist", + "simple-file-manifest", + "walkdir", +] + +[[package]] +name = "apple-codesign" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "329820aac7259ca0529d3cc21dd3b4c11651225dfce9e0ce25b121b23f923164" +dependencies = [ + "anyhow", + "app-store-connect", + "apple-bundles", + "apple-flat-package", + "apple-xar", + "aws-config", + "aws-sdk-s3", + "aws-smithy-http", + "aws-smithy-types", + "base64 0.21.7", + "bcder", + "bitflags 2.6.0", + "bytes", + "chrono", + "clap 4.5.21", + "cryptographic-message-syntax", + "der 0.7.9", + "dialoguer", + "difference", + "digest", + "dirs 5.0.1", + "elliptic-curve 0.13.8", + "env_logger 0.10.2", + "figment", + "filetime", + "glob", + "goblin", + "hex", + "log", + "md-5", + "minicbor", + "num-traits", + "object 0.32.2", + "oid-registry", + "once_cell", + "p12", + "p256 0.13.2", + "pem", + "pkcs1", + "pkcs8 0.10.2", + "plist", + "rand 0.8.5", + "rasn", + "rayon", + "regex", + "reqwest 0.11.27", + "ring", + "rsa", + "scroll", + "security-framework", + "security-framework-sys", + "semver", + "serde", + "serde_json", + "serde_yaml", + "sha2", + "signature 2.2.0", + "simple-file-manifest", + "spake2", + "spki 0.7.3", + "subtle", + "tempfile", + "thiserror 1.0.69", + "tokio", + "tungstenite 0.21.0", + "uuid", + "walkdir", + "widestring", + "windows-sys 0.52.0", + "x509", + "x509-certificate", + "xml-rs", + "yasna", + "zeroize", + "zip 0.6.6", + "zip_structs", +] + +[[package]] +name = "apple-flat-package" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6adc520e05304de5ec383487786fa20e9c636fe972e59719cdd93621a2db6f1" +dependencies = [ + "apple-xar", + "cpio-archive", + "flate2", + "scroll", + "serde", + "serde-xml-rs", + "thiserror 1.0.69", +] + +[[package]] +name = "apple-xar" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "844e00dc1e665b3cf0bba745aa9c6464292ca512db0c11384511586701eb0335" +dependencies = [ + "base64 0.21.7", + "bcder", + "bzip2", + "chrono", + "cryptographic-message-syntax", + "digest", + "flate2", + "log", + "md-5", + "rand 0.8.5", + "reqwest 0.11.27", + "scroll", + "serde", + "serde-xml-rs", + "sha1", + "sha2", + "signature 2.2.0", + "thiserror 1.0.69", + "url", + "x509-certificate", + "xml-rs", + "xz2", +] + [[package]] name = "ar" version = "0.9.0" @@ -269,22 +433,22 @@ checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" dependencies = [ "derive_arbitrary", ] [[package]] name = "arboard" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" +checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" dependencies = [ "clipboard-win", "core-graphics 0.23.2", - "image 0.25.2", + "image", "log", "objc2", "objc2-app-kit", @@ -302,7 +466,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -319,9 +483,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -355,19 +519,61 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.8.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093" +checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3" dependencies = [ "enumflags2", "futures-channel", "futures-util", "rand 0.8.5", + "raw-window-handle", "serde", "serde_repr", "tokio", "url", - "zbus 4.4.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "zbus 5.1.1", +] + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -418,14 +624,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.1.0", - "futures-lite 2.3.0", + "fastrand 2.2.0", + "futures-lite 2.5.0", "slab", ] @@ -449,7 +655,7 @@ checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ "async-lock 3.4.0", "blocking", - "futures-lite 2.3.0", + "futures-lite 2.5.0", ] [[package]] @@ -474,18 +680,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.5.0", "parking", - "polling 3.7.3", - "rustix 0.38.34", + "polling 3.7.4", + "rustix 0.38.41", "slab", "tracing", "windows-sys 0.59.0", @@ -517,9 +723,9 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ - "async-io 2.3.4", + "async-io 2.4.0", "blocking", - "futures-lite 2.3.0", + "futures-lite 2.5.0", ] [[package]] @@ -535,28 +741,27 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.34", + "rustix 0.38.41", "windows-sys 0.48.0", ] [[package]] name = "async-process" -version = "2.2.4" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a07789659a4d385b79b18b9127fc27e1a59e1e89117c78c5ea3b806f016374" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ "async-channel", - "async-io 2.3.4", + "async-io 2.4.0", "async-lock 3.4.0", "async-signal", "async-task", "blocking", "cfg-if", "event-listener 5.3.1", - "futures-lite 2.3.0", - "rustix 0.38.34", + "futures-lite 2.5.0", + "rustix 0.38.41", "tracing", - "windows-sys 0.59.0", ] [[package]] @@ -567,7 +772,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -576,13 +781,13 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io 2.3.4", + "async-io 2.4.0", "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.34", + "rustix 0.38.41", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -596,13 +801,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -628,6 +833,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "atomic" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +dependencies = [ + "bytemuck", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -647,9 +861,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "av1-grain" @@ -667,30 +881,404 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" dependencies = [ "arrayvec 0.7.6", ] [[package]] -name = "axum" -version = "0.7.5" +name = "aws-config" +version = "1.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "9b49afaa341e8dd8577e1a2200468f98956d6eda50bcf4a53246cc00174ba924" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand 2.2.0", + "hex", + "http 0.2.12", + "ring", + "time", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e8f6b615cb5fc60a98132268508ad104310f0cfb25a1c22eee76efdf9154da" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + +[[package]] +name = "aws-runtime" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a10d5c055aa540164d9561a0e2e74ad30f0dcf7393c3a92f6733ddf9c5762468" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand 2.2.0", + "http 0.2.12", + "http-body 0.4.6", + "once_cell", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", +] + +[[package]] +name = "aws-sdk-s3" +version = "1.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43850204a109a5eea1ea93951cf0440268cef98b0d27dfef4534949e23735f7" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-checksums", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "bytes", + "fastrand 2.2.0", + "hex", + "hmac", + "http 0.2.12", + "http-body 0.4.6", + "lru", + "once_cell", + "percent-encoding", + "regex-lite", + "sha2", + "tracing", + "url", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09677244a9da92172c8dc60109b4a9658597d4d298b188dd0018b6a66b410ca4" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fea2f3a8bb3bd10932ae7ad59cc59f65f270fc9183a7e91f501dc5efbef7ee" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ada54e5f26ac246dc79727def52f7f8ed38915cb47781e2a72213957dc3a7d5" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5619742a0d8f253be760bfbb8e8e8368c69e3587e4637af5754e488a611499b1" +dependencies = [ + "aws-credential-types", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "crypto-bigint 0.5.5", + "form_urlencoded", + "hex", + "hmac", + "http 0.2.12", + "http 1.1.0", + "once_cell", + "p256 0.11.1", + "percent-encoding", + "ring", + "sha2", + "subtle", + "time", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-checksums" +version = "0.60.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1a71073fca26775c8b5189175ea8863afb1c9ea2cceb02a5de5ad9dfbaa795" +dependencies = [ + "aws-smithy-http", + "aws-smithy-types", + "bytes", + "crc32c", + "crc32fast", + "hex", + "http 0.2.12", + "http-body 0.4.6", + "md-5", + "pin-project-lite", + "sha1", + "sha2", + "tracing", +] + +[[package]] +name = "aws-smithy-eventstream" +version = "0.60.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef7d0a272725f87e51ba2bf89f8c21e4df61b9e49ae1ac367a6d69916ef7c90" +dependencies = [ + "aws-smithy-types", + "bytes", + "crc32fast", +] + +[[package]] +name = "aws-smithy-http" +version = "0.60.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8bc3e8fdc6b8d07d976e301c02fe553f72a39b7a9fea820e023268467d7ab6" +dependencies = [ + "aws-smithy-eventstream", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http-body 0.4.6", + "once_cell", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.60.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" +dependencies = [ + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be28bd063fa91fd871d131fc8b68d7cd4c5fa0869bea68daca50dcb1cbd76be2" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "fastrand 2.2.0", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "http-body 1.0.1", + "httparse", + "hyper 0.14.31", + "hyper-rustls 0.24.2", + "once_cell", + "pin-project-lite", + "pin-utils", + "rustls 0.21.12", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92165296a47a812b267b4f41032ff8069ab7ff783696d217f0994a0d7ab585cd" +dependencies = [ + "aws-smithy-async", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.1.0", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-types" +version = "1.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fbd94a32b3a7d55d3806fe27d98d3ad393050439dd05eb53ece36ec5e3d3510" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.1.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa 1.0.14", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab0b0166827aa700d3dc519f72f8b3a91c35d0b8d042dc5d643a91e6f80648fc" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5221b91b3e441e6675310829fd8984801b772cb1546ef6c0e54dec9f1ac13fef" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "rustc_version", + "tracing", +] + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", - "base64 0.21.7", + "base64 0.22.1", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.5.1", "hyper-util", - "itoa 1.0.11", + "itoa 1.0.14", "matchit", "memchr", "mime", @@ -702,10 +1290,10 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", "tokio-tungstenite", - "tower", + "tower 0.5.1", "tower-layer", "tower-service", "tracing", @@ -713,20 +1301,20 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", @@ -734,19 +1322,25 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.36.5", "rustc-demangle", + "windows-targets 0.52.6", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base16ct" version = "0.2.0" @@ -771,6 +1365,16 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "base64ct" version = "1.6.0" @@ -836,16 +1440,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57792b99d555ebf109c83169228076f7d997e2b37ba1a653850ccd703ac7bab0" dependencies = [ "sysctl", - "thiserror", + "thiserror 1.0.69", "uname", "winapi", ] [[package]] name = "bitstream-io" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcde5f311c85b8ca30c2e4198d4326bc342c76541590106f5fa4a50946ea499" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" [[package]] name = "bitvec" @@ -859,6 +1463,16 @@ dependencies = [ "wyz", ] +[[package]] +name = "bitvec-nom2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d988fcc40055ceaa85edc55875a08f8abd29018582647fd82ad6128dba14a5f0" +dependencies = [ + "bitvec", + "nom", +] + [[package]] name = "blake2" version = "0.10.6" @@ -921,7 +1535,7 @@ dependencies = [ "async-channel", "async-task", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.5.0", "piper", ] @@ -937,9 +1551,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" dependencies = [ "borsh-derive", "cfg_aliases", @@ -947,23 +1561,22 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", - "syn_derive", + "syn 2.0.89", ] [[package]] name = "brotli" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -982,9 +1595,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" dependencies = [ "memchr", "serde", @@ -1007,9 +1620,9 @@ dependencies = [ [[package]] name = "built" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" [[package]] name = "bumpalo" @@ -1022,9 +1635,9 @@ dependencies = [ [[package]] name = "byte-unit" -version = "5.1.4" +version = "5.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" +checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174" dependencies = [ "rust_decimal", "serde", @@ -1061,9 +1674,9 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -1079,13 +1692,29 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" dependencies = [ "serde", ] +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + +[[package]] +name = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" + [[package]] name = "bzip2" version = "0.4.4" @@ -1119,7 +1748,7 @@ dependencies = [ "hashbrown 0.14.5", "instant", "once_cell", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1151,7 +1780,7 @@ dependencies = [ "glib", "libc", "once_cell", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1186,9 +1815,9 @@ dependencies = [ [[package]] name = "cargo-mobile2" -version = "0.15.1" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b8132519bea2d46174e777bd36d480d93afbe1df31c27cacfb411ff152bba1" +checksum = "197498a32cc339dac8e77a319eacf00688b5ac633628f007c4465f303cc69105" dependencies = [ "colored", "core-foundation 0.10.0", @@ -1212,7 +1841,7 @@ dependencies = [ "serde", "serde_json", "textwrap 0.16.1", - "thiserror", + "thiserror 1.0.69", "toml 0.8.19", "ureq", "which", @@ -1240,7 +1869,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1272,10 +1901,19 @@ dependencies = [ ] [[package]] -name = "cc" -version = "1.1.13" +name = "cbc" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "jobserver", "libc", @@ -1372,9 +2010,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -1382,9 +2020,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -1394,30 +2032,30 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.18" +version = "4.5.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee158892bd7ce77aa15c208abbdb73e155d191c287a659b57abd5adb92feb03" +checksum = "d9647a559c112175f17cf724dc72d3645680a883c58481332779192b0d8e7a01" dependencies = [ - "clap 4.5.16", + "clap 4.5.21", ] [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "clipboard-win" @@ -1439,22 +2077,6 @@ dependencies = [ "digest", ] -[[package]] -name = "cocoa" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation 0.1.2", - "core-foundation 0.9.4", - "core-graphics 0.23.2", - "foreign-types 0.5.0", - "libc", - "objc", -] - [[package]] name = "cocoa" version = "0.26.0" @@ -1463,7 +2085,7 @@ checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2" dependencies = [ "bitflags 2.6.0", "block", - "cocoa-foundation 0.2.0", + "cocoa-foundation", "core-foundation 0.10.0", "core-graphics 0.24.0", "foreign-types 0.5.0", @@ -1471,20 +2093,6 @@ dependencies = [ "objc", ] -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "libc", - "objc", -] - [[package]] name = "cocoa-foundation" version = "0.2.0" @@ -1507,9 +2115,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" @@ -1545,7 +2153,7 @@ checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" dependencies = [ "castaway", "cfg-if", - "itoa 1.0.11", + "itoa 1.0.14", "rustversion", "ryu", "static_assertions", @@ -1599,6 +2207,12 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "const_panic" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "013b6c2c3a14d678f38cd23994b02da3a1a1b6a5d1eedddfe63a5a5f11b13a81" + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -1611,6 +2225,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + +[[package]] +name = "cookie-factory" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2" +dependencies = [ + "futures", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1696,15 +2329,27 @@ dependencies = [ [[package]] name = "cpio" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e3adec7390c7643049466136117057188edf5f23efc5c8b4fc8079c8dc34a6" +checksum = "938e716cb1ade5d6c8f959c13a7248b889c07491fc7e41167c3afe20f8f0de1e" + +[[package]] +name = "cpio-archive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63d5133d716d3d82da8c76367ddb0ab1733e2629f1462e4f39947e13b8b4b741" +dependencies = [ + "chrono", + "is_executable", + "simple-file-manifest", + "thiserror 1.0.69", +] [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -1715,6 +2360,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd121741cf3eb82c08dd3023eb55bf2665e5f60ec20f89760cf836ae4562e6a0" +[[package]] +name = "crc32c" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +dependencies = [ + "rustc_version", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -1764,6 +2418,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -1787,6 +2453,23 @@ dependencies = [ "typenum", ] +[[package]] +name = "cryptographic-message-syntax" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c324ba1028cef7e3a71a00cbf585637bb0215dec2f6a2b566d094190a1309b" +dependencies = [ + "bcder", + "bytes", + "chrono", + "hex", + "pem", + "reqwest 0.11.27", + "ring", + "signature 2.2.0", + "x509-certificate", +] + [[package]] name = "css-color" version = "0.2.8" @@ -1817,17 +2500,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "ctor" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -1860,6 +2543,7 @@ dependencies = [ "curve25519-dalek-derive", "digest", "fiat-crypto", + "rand_core 0.6.4", "rustc_version", "subtle", "zeroize", @@ -1873,7 +2557,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -1889,7 +2573,7 @@ dependencies = [ "objc", "rust-ini", "web-sys", - "winreg", + "winreg 0.52.0", "xdg", "zbus 3.15.2", ] @@ -1939,7 +2623,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -1961,14 +2645,14 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", @@ -2019,6 +2703,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b" +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "der" version = "0.7.9" @@ -2053,44 +2747,44 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "derive_builder" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "derive_builder_macro" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -2103,7 +2797,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -2136,10 +2830,16 @@ dependencies = [ "console", "shell-words", "tempfile", - "thiserror", + "thiserror 1.0.69", "zeroize", ] +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + [[package]] name = "digest" version = "0.10.7" @@ -2190,7 +2890,7 @@ checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", "option-ext", - "redox_users 0.4.5", + "redox_users 0.4.6", "windows-sys 0.48.0", ] @@ -2201,7 +2901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users 0.4.5", + "redox_users 0.4.6", "winapi", ] @@ -2219,7 +2919,16 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", +] + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading 0.8.5", ] [[package]] @@ -2242,7 +2951,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -2254,6 +2963,18 @@ dependencies = [ "const-random", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dpi" version = "0.1.1" @@ -2272,10 +2993,10 @@ dependencies = [ "digest", "num-bigint-dig", "num-traits", - "pkcs8", - "rfc6979", + "pkcs8 0.10.2", + "rfc6979 0.4.0", "sha2", - "signature", + "signature 2.2.0", "zeroize", ] @@ -2331,18 +3052,30 @@ dependencies = [ "subtle", ] +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.9", "digest", - "elliptic-curve", - "rfc6979", - "signature", - "spki", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -2351,8 +3084,8 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "signature", + "pkcs8 0.10.2", + "signature 2.2.0", ] [[package]] @@ -2381,39 +3114,59 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct", - "crypto-bigint", + "base16ct 0.2.0", + "crypto-bigint 0.5.5", "digest", - "ff", + "ff 0.13.0", "generic-array", - "group", + "group 0.13.0", "hkdf", "pem-rfc7468", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", "subtle", "zeroize", ] [[package]] name = "embed-resource" -version = "2.4.3" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edcacde9351c33139a41e3c97eb2334351a81a2791bebb0b243df837128f602" +checksum = "b68b6f9f63a0b6a38bc447d4ce84e2b388f3ec95c99c641c8ff0dd3ef89a6379" dependencies = [ "cc", "memchr", "rustc_version", "toml 0.8.19", "vswhom", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -2430,9 +3183,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -2468,7 +3221,7 @@ checksum = "ba7795da175654fe16979af73f81f26a8ea27638d8d9823d317016888a63dc4c" dependencies = [ "num-traits", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -2489,7 +3242,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -2502,6 +3255,19 @@ dependencies = [ "regex", ] +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "env_logger" version = "0.11.5" @@ -2543,9 +3309,9 @@ dependencies = [ [[package]] name = "error-code" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" [[package]] name = "event-listener" @@ -2587,12 +3353,11 @@ dependencies = [ [[package]] name = "exr" -version = "1.72.0" +version = "1.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" dependencies = [ "bit_field", - "flume", "half", "lebe", "miniz_oxide", @@ -2608,8 +3373,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" dependencies = [ "bit-set", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata", + "regex-syntax", ] [[package]] @@ -2623,28 +3388,38 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fdeflate" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] [[package]] name = "fern" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" +checksum = "69ff9c9d5fb3e6da8ac2f77ab76fe7e8087d512ce095200f8f29ac5b656cf6dc" dependencies = [ "log", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ff" version = "0.13.0" @@ -2672,10 +3447,24 @@ dependencies = [ ] [[package]] -name = "filetime" -version = "0.2.24" +name = "figment" +version = "0.10.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" +dependencies = [ + "atomic", + "pear", + "serde", + "toml 0.8.19", + "uncased", + "version_check", +] + +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -2685,9 +3474,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -2699,30 +3488,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -[[package]] -name = "fluent-uri" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "spin", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "fontconfig-parser" version = "0.5.7" @@ -2773,7 +3550,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -2814,7 +3591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db9c27b72f19a99a895f8ca89e2d26e4ef31013376e56fdafef697627306c3e4" dependencies = [ "nom", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2844,9 +3621,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -2859,9 +3636,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -2869,15 +3646,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -2886,9 +3663,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -2907,11 +3684,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" dependencies = [ - "fastrand 2.1.0", + "fastrand 2.2.0", "futures-core", "futures-io", "parking", @@ -2920,26 +3697,26 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -2949,9 +3726,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -3073,19 +3850,6 @@ dependencies = [ "x11", ] -[[package]] -name = "generator" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows 0.48.0", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -3107,6 +3871,16 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "gethostname" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc3655aa6818d65bc620d6911f05aa7b6aeb596291e1e9f79e52df85583d1e30" +dependencies = [ + "rustix 0.38.41", + "windows-targets 0.52.6", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -3153,9 +3927,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "gio" @@ -3173,7 +3947,7 @@ dependencies = [ "once_cell", "pin-project-lite", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3209,7 +3983,7 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3223,7 +3997,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -3244,15 +4018,15 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata", + "regex-syntax", ] [[package]] @@ -3266,13 +4040,35 @@ dependencies = [ "system-deps", ] +[[package]] +name = "goblin" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.0", "rand_core 0.6.4", "subtle", ] @@ -3326,22 +4122,41 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "h2" -version = "0.4.5" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http", - "indexmap 2.4.0", + "http 1.1.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -3360,16 +4175,17 @@ dependencies = [ [[package]] name = "handlebars" -version = "6.0.0" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5226a0e122dc74917f3a701484482bed3ee86d016c7356836abbaa033133a157" +checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315" dependencies = [ "log", + "num-order", "pest", "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3391,6 +4207,17 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "heck" version = "0.4.1" @@ -3471,6 +4298,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.14", +] + [[package]] name = "http" version = "1.1.0" @@ -3479,7 +4317,18 @@ checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", - "itoa 1.0.11", + "itoa 1.0.14", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", ] [[package]] @@ -3489,7 +4338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -3500,16 +4349,16 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -3525,19 +4374,43 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.4.1" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa 1.0.14", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.7", + "http 1.1.0", + "http-body 1.0.1", "httparse", "httpdate", - "itoa 1.0.11", + "itoa 1.0.14", "pin-project-lite", "smallvec", "tokio", @@ -3546,15 +4419,31 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.31", + "log", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.5.1", "hyper-util", - "rustls 0.23.12", + "rustls 0.23.18", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -3569,7 +4458,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper", + "hyper 1.5.1", "hyper-util", "native-tls", "tokio", @@ -3579,29 +4468,28 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.5.1", "pin-project-lite", "socket2 0.5.7", "tokio", - "tower", "tower-service", "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3630,6 +4518,124 @@ dependencies = [ "png", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "idea" version = "0.5.1" @@ -3647,25 +4653,36 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", "log", "memchr", - "regex-automata 0.4.7", + "regex-automata", "same-file", "walkdir", "winapi-util", @@ -3673,34 +4690,16 @@ dependencies = [ [[package]] name = "image" -version = "0.24.9" +version = "0.25.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "jpeg-decoder", - "num-traits", - "png", - "qoi", - "tiff", -] - -[[package]] -name = "image" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", "byteorder-lite", "color_quant", "exr", "gif", - "image-webp", + "image-webp 0.2.0", "num-traits", "png", "qoi", @@ -3722,6 +4721,16 @@ dependencies = [ "quick-error", ] +[[package]] +name = "image-webp" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" +dependencies = [ + "byteorder-lite", + "quick-error", +] + [[package]] name = "imagesize" version = "0.13.0" @@ -3730,9 +4739,9 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "imgref" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" [[package]] name = "include_dir" @@ -3766,12 +4775,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "serde", ] @@ -3786,13 +4795,19 @@ dependencies = [ [[package]] name = "infer" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb33622da908807a06f9513c19b3c1ad50fab3e4137d82a78107d502075aa199" +checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847" dependencies = [ "cfb", ] +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + [[package]] name = "inotify" version = "0.9.6" @@ -3819,6 +4834,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding", "generic-array", ] @@ -3839,7 +4855,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -3855,9 +4871,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is-docker" @@ -3868,6 +4884,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is-wsl" version = "0.4.0" @@ -3878,6 +4905,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is_executable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a1b5bad6f9072935961dfbf1cced2f3d129963d091b6f69f007fe04e758ae2" +dependencies = [ + "winapi", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -3895,9 +4931,18 @@ dependencies = [ [[package]] name = "iter-read" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a598c1abae8e3456ebda517868b254b6bc2a9bb6501ffd5b9d0875bf332e048b" +checksum = "071ed4cc1afd86650602c7b11aa2e1ce30762a1c27193201cb5cee9c6ebb1294" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] [[package]] name = "itertools" @@ -3925,9 +4970,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "java-properties" @@ -3974,7 +5019,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] @@ -3999,15 +5044,12 @@ name = "jpeg-decoder" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" -dependencies = [ - "rayon", -] [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -4020,19 +5062,19 @@ checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "json-patch" -version = "2.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" dependencies = [ "jsonptr", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4048,20 +5090,19 @@ dependencies = [ [[package]] name = "jsonptr" -version = "0.4.7" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" dependencies = [ - "fluent-uri", "serde", "serde_json", ] [[package]] name = "jsonrpsee" -version = "0.24.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec465b607a36dc5dd45d48b7689bc83f679f66a3ac6b6b21cc787a11e0f8685" +checksum = "c5c71d8c1a731cc4227c2f698d377e7848ca12c8a48866fc5e6951c43a4db843" dependencies = [ "jsonrpsee-core", "jsonrpsee-server", @@ -4071,17 +5112,17 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.24.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f0977f9c15694371b8024c35ab58ca043dbbf4b51ccb03db8858a021241df1" +checksum = "548125b159ba1314104f5bb5f38519e03a41862786aa3925cf349aae9cdd546e" dependencies = [ "base64 0.22.1", "futures-util", - "http", + "http 1.1.0", "jsonrpsee-core", "pin-project", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-util", "tracing", @@ -4090,16 +5131,16 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.24.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e942c55635fbf5dc421938b8558a8141c7e773720640f4f1dbe1f4164ca4e221" +checksum = "f2882f6f8acb9fdaec7cefc4fd607119a9bd709831df7d7672a1d3b644628280" dependencies = [ "async-trait", "bytes", "futures-timer", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", "jsonrpsee-types", "parking_lot", @@ -4108,7 +5149,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -4116,15 +5157,15 @@ dependencies = [ [[package]] name = "jsonrpsee-server" -version = "0.24.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038fb697a709bec7134e9ccbdbecfea0e2d15183f7140254afef7c5610a3f488" +checksum = "82ad8ddc14be1d4290cd68046e7d1d37acd408efed6d3ca08aefcc3ad6da069c" dependencies = [ "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.5.1", "hyper-util", "jsonrpsee-core", "jsonrpsee-types", @@ -4133,33 +5174,33 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", - "tower", + "tower 0.4.13", "tracing", ] [[package]] name = "jsonrpsee-types" -version = "0.24.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b67d6e008164f027afbc2e7bb79662650158d26df200040282d2aa1cbb093b" +checksum = "a178c60086f24cc35bb82f57c651d0d25d99c4742b4d335de04e97fa1f08a8a1" dependencies = [ - "http", + "http 1.1.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "jsonrpsee-ws-client" -version = "0.24.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992bf67d1132f88edf4a4f8cff474cf01abb2be203004a2b8e11c2b20795b99e" +checksum = "0fe322e0896d0955a3ebdd5bf813571c53fea29edd713bc315b76620b327e86d" dependencies = [ - "http", + "http 1.1.0", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", @@ -4168,27 +5209,27 @@ dependencies = [ [[package]] name = "jsonschema" -version = "0.18.0" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0afd06142c9bcb03f4a8787c77897a87b6be9c4918f1946c33caa714c27578" +checksum = "fa0f4bea31643be4c6a678e9aa4ae44f0db9e5609d5ca9dc9083d06eb3e9a27a" dependencies = [ "ahash 0.8.11", "anyhow", "base64 0.22.1", "bytecount", - "clap 4.5.16", + "clap 4.5.21", "fancy-regex", "fraction", "getrandom 0.2.15", "iso8601", - "itoa 1.0.11", + "itoa 1.0.14", "memchr", "num-cmp", "once_cell", "parking_lot", "percent-encoding", "regex", - "reqwest", + "reqwest 0.12.9", "serde", "serde_json", "time", @@ -4197,17 +5238,38 @@ dependencies = [ ] [[package]] -name = "k256" -version = "0.13.3" +name = "jsonwebtoken" +version = "9.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" +dependencies = [ + "base64 0.21.7", + "js-sys", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "jzon" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ab85f84ca42c5ec520e6f3c9966ba1fd62909ce260f8837e248857d2560509" + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "sha2", - "signature", + "signature 2.2.0", ] [[package]] @@ -4230,6 +5292,26 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "konst" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65f00fb3910881e52bf0850ae2a82aea411488a557e1c02820ceaa60963dce3" +dependencies = [ + "const_panic", + "konst_kernel", + "typewit", +] + +[[package]] +name = "konst_kernel" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "599c1232f55c72c7fc378335a3efe1c878c92720838c8e6a4fd87784ef7764de" +dependencies = [ + "typewit", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -4265,9 +5347,9 @@ dependencies = [ [[package]] name = "kurbo" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5aa9f0f96a938266bdb12928a67169e8d22c6a786fda8ed984b85e6ba93c3c" +checksum = "89234b2cc610a7dd927ebde6b41dd1a5d4214cffaef4cf1fb2195d592f92518f" dependencies = [ "arrayvec 0.7.6", "smallvec", @@ -4308,25 +5390,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" dependencies = [ "gtk-sys", - "libloading", + "libloading 0.7.4", "once_cell", ] [[package]] name = "libc" -version = "0.2.158" +version = "0.2.165" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" dependencies = [ "arbitrary", "cc", - "once_cell", ] [[package]] @@ -4340,10 +5421,20 @@ dependencies = [ ] [[package]] -name = "libm" -version = "0.2.8" +name = "libloading" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libredox" @@ -4353,7 +5444,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.7", ] [[package]] @@ -4369,15 +5460,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] -name = "local-ip-address" -version = "0.6.1" +name = "litemap" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136ef34e18462b17bf39a7826f8f3bbc223341f8e83822beb8b77db9a3d49696" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "local-ip-address" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3669cf5561f8d27e8fc84cc15e58350e70f557d4d65f70e3154e54cd2f8e1782" dependencies = [ "libc", "neli", - "thiserror", - "windows-sys 0.48.0", + "thiserror 1.0.69", + "windows-sys 0.59.0", ] [[package]] @@ -4405,21 +5502,6 @@ dependencies = [ "value-bag", ] -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - [[package]] name = "loop9" version = "0.1.5" @@ -4429,6 +5511,15 @@ dependencies = [ "imgref", ] +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.2", +] + [[package]] name = "lzma-sys" version = "0.1.20" @@ -4448,9 +5539,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "mac-notification-sys" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fca4d74ff9dbaac16a01b924bc3693fa2bba0862c2c633abc73f9a8ea21f64" +checksum = "dce8f34f3717aa37177e723df6c1fc5fb02b2a1087374ea3fe0ea42316dc8f91" dependencies = [ "cc", "dirs-next", @@ -4495,15 +5586,6 @@ dependencies = [ "tendril", ] -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - [[package]] name = "matches" version = "0.1.10" @@ -4523,6 +5605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" dependencies = [ "cfg-if", + "rayon", ] [[package]] @@ -4549,9 +5632,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] @@ -4576,27 +5659,27 @@ dependencies = [ [[package]] name = "miette" -version = "7.2.0" +version = "7.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +checksum = "551cefdb9e93e2a40037f24cd139d88009a7660158c9d5d6076afeca5c8cfb82" dependencies = [ "cfg-if", "miette-derive", "owo-colors", "textwrap 0.16.1", - "thiserror", + "thiserror 1.0.69", "unicode-width", ] [[package]] name = "miette-derive" -version = "7.2.0" +version = "7.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +checksum = "acd70bb0b631435c30f187b3c2b528d0b78c65654f542ead7857915e37c177da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -4605,6 +5688,26 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minicbor" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d15f4203d71fdf90903c2696e55426ac97a363c67b218488a73b534ce7aca10" +dependencies = [ + "minicbor-derive", +] + +[[package]] +name = "minicbor-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -4624,11 +5727,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", "simd-adler32", ] @@ -4658,20 +5761,21 @@ dependencies = [ [[package]] name = "muda" -version = "0.14.0" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86c410a9d21523a819e84881603fbc00331c8001eb899964952046671deddb9c" +checksum = "fdae9c00e61cc0579bcac625e8ad22104c60548a025bfc972dc83868a28e1484" dependencies = [ - "cocoa 0.26.0", "crossbeam-channel", "dpi", "gtk", "keyboard-types", - "objc", + "objc2", + "objc2-app-kit", + "objc2-foundation", "once_cell", "png", "serde", - "thiserror", + "thiserror 1.0.69", "windows-sys 0.59.0", ] @@ -4704,7 +5808,7 @@ dependencies = [ "ndk-sys", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4838,9 +5942,9 @@ dependencies = [ [[package]] name = "notify-rust" -version = "4.11.1" +version = "4.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a1d03b6305ecefdd9c6c60150179bb8d9f0cd4e64bbcad1e41419e7bf5e414" +checksum = "5134a72dc570b178bff81b01e81ab14a6fcc015391ed4b3b14853090658cd3a3" dependencies = [ "log", "mac-notification-sys", @@ -4849,16 +5953,6 @@ dependencies = [ "zbus 4.4.0", ] -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "num" version = "0.4.3" @@ -4930,7 +6024,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -4953,6 +6047,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + [[package]] name = "num-rational" version = "0.4.2" @@ -4989,10 +6098,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -5011,7 +6120,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", - "objc_exception", ] [[package]] @@ -5030,6 +6138,9 @@ name = "objc-sys" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" +dependencies = [ + "cc", +] [[package]] name = "objc2" @@ -5057,6 +6168,30 @@ dependencies = [ "objc2-quartz-core", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + [[package]] name = "objc2-core-data" version = "0.2.2" @@ -5081,6 +6216,18 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + [[package]] name = "objc2-encode" version = "4.0.3" @@ -5100,6 +6247,18 @@ dependencies = [ "objc2", ] +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + [[package]] name = "objc2-metal" version = "0.2.2" @@ -5126,12 +6285,71 @@ dependencies = [ ] [[package]] -name = "objc_exception" -version = "0.1.2" +name = "objc2-symbols" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "cc", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-web-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", ] [[package]] @@ -5145,9 +6363,23 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "crc32fast", + "flate2", + "hashbrown 0.14.5", + "indexmap 2.6.0", + "memchr", + "ruzstd", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -5164,6 +6396,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once-cell-regex" version = "0.2.1" @@ -5176,9 +6417,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -5188,9 +6429,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "open" -version = "5.3.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3" +checksum = "3ecd52f0b8d15c40ce4820aa251ed5de032e5d91fab27f7db2f40d42a8bdf69c" dependencies = [ "is-wsl", "libc", @@ -5199,9 +6440,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -5220,7 +6461,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -5231,9 +6472,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -5298,22 +6539,22 @@ dependencies = [ ] [[package]] -name = "overload" -version = "0.1.1" +name = "outref" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" [[package]] name = "owo-colors" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "oxc_allocator" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20afc1d4a7b0b878d28f7b7f9f1f7ab670a7c7e8feb29101fb49eac1faa483fa" +checksum = "466379b9ab2e05996bfedfae9c96753a633bb5a53aaf0898eb0e0ab09e169514" dependencies = [ "allocator-api2", "bumpalo", @@ -5321,9 +6562,9 @@ dependencies = [ [[package]] name = "oxc_ast" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1599f878d8ac6fcc229be06426f04134f7663dcd5c71046414d8ddd12a20ad3b" +checksum = "34bd4f56fe32adea489153f6d681d9ee01f0336b9b6a89f062611488d8f80797" dependencies = [ "bitflags 2.6.0", "num-bigint", @@ -5335,20 +6576,20 @@ dependencies = [ [[package]] name = "oxc_ast_macros" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a07c44bbe07756ba25605059fa4a94543f6a75730fd8bd1105795d0b3d668d" +checksum = "197b36739db0e80919e19a90785233eea5664697d4cd829bd49af34838ec43d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "oxc_diagnostics" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c53d201660e8accd6e53f1af7efda36967316aa4263d0a6847c631bdd8705e0f" +checksum = "2cd4bb48b9527f5825c84acb688ec1485df4a5edadc17b3582626bb49736752b" dependencies = [ "miette", "owo-colors", @@ -5358,15 +6599,15 @@ dependencies = [ [[package]] name = "oxc_index" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1d58c483b1ec74c7219b1525648b4b6beea7ff4685b02ad74693190df43308" +checksum = "bc9aa9446f6d2a64d0baa02fe20dc3d64e3e112083854b84fdacb82261be2b84" [[package]] name = "oxc_parser" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce38833b8b0d1121779b2ceaa9aa07d4142105ccc6941f73112a8d836b87cd" +checksum = "8f3432e80a58cfb38f9a138203e64d0f9a621d4c4e9d18e3e3bd870b51ce1f0e" dependencies = [ "assert-unchecked", "bitflags 2.6.0", @@ -5376,6 +6617,7 @@ dependencies = [ "oxc_allocator", "oxc_ast", "oxc_diagnostics", + "oxc_regular_expression", "oxc_span", "oxc_syntax", "rustc-hash", @@ -5383,10 +6625,24 @@ dependencies = [ ] [[package]] -name = "oxc_span" -version = "0.24.3" +name = "oxc_regular_expression" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a4f6e525a64e61bcfa256e4707e46be54f3261e0b524670d0a1c6827c28931" +checksum = "8fc6d05fec98ad6cc864ba8cfe7ece2e258106059a9a57e35b02450650b06979" +dependencies = [ + "oxc_allocator", + "oxc_diagnostics", + "oxc_span", + "phf 0.11.2", + "rustc-hash", + "unicode-id-start", +] + +[[package]] +name = "oxc_span" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a862a896ac3abd269863a19d4f77302b019458d90513705c7a017b138c8449b" dependencies = [ "compact_str", "miette", @@ -5396,9 +6652,9 @@ dependencies = [ [[package]] name = "oxc_syntax" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcb27d1a7e00a63e5d490fa4ee9a008d45e45db3d505ca21f0e63de2097cf743" +checksum = "d50c7ea034fb12f65376cfffc8ae4bfde3cda0a1e14407f82ffba1d26431703d" dependencies = [ "bitflags 2.6.0", "dashmap", @@ -5412,14 +6668,42 @@ dependencies = [ "unicode-id-start", ] +[[package]] +name = "p12" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4873306de53fe82e7e484df31e1e947d61514b6ea2ed6cd7b45d63006fd9224" +dependencies = [ + "cbc", + "cipher", + "des", + "getrandom 0.2.15", + "hmac", + "lazy_static", + "rc2", + "sha1", + "yasna", +] + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2", +] + [[package]] name = "p256" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "primeorder", "sha2", ] @@ -5430,8 +6714,8 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "primeorder", "sha2", ] @@ -5442,9 +6726,9 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" dependencies = [ - "base16ct", - "ecdsa", - "elliptic-curve", + "base16ct 0.2.0", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "primeorder", "rand_core 0.6.4", "sha2", @@ -5477,9 +6761,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -5499,7 +6783,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.7", "smallvec", "windows-targets 0.52.6", ] @@ -5535,9 +6819,9 @@ dependencies = [ [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pbkdf2" @@ -5549,6 +6833,29 @@ dependencies = [ "hmac", ] +[[package]] +name = "pear" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi", +] + +[[package]] +name = "pear_codegen" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.89", +] + [[package]] name = "pem" version = "3.0.4" @@ -5576,20 +6883,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -5597,22 +6904,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "pest_meta" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -5648,9 +6955,9 @@ dependencies = [ "digest", "dsa", "eax", - "ecdsa", + "ecdsa 0.16.9", "ed25519-dalek", - "elliptic-curve", + "elliptic-curve 0.13.8", "flate2", "generic-array", "hex", @@ -5665,7 +6972,7 @@ dependencies = [ "num-traits", "num_enum", "ocb3", - "p256", + "p256 0.13.2", "p384", "p521", "rand 0.8.5", @@ -5675,9 +6982,9 @@ dependencies = [ "sha1-checked", "sha2", "sha3", - "signature", + "signature 2.2.0", "smallvec", - "thiserror", + "thiserror 1.0.69", "twofish", "x25519-dalek", "zeroize", @@ -5787,7 +7094,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -5825,29 +7132,29 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -5862,7 +7169,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.1.0", + "fastrand 2.2.0", "futures-io", ] @@ -5872,9 +7179,19 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der", - "pkcs8", - "spki", + "der 0.7.9", + "pkcs8 0.10.2", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", ] [[package]] @@ -5883,15 +7200,21 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.9", + "spki 0.7.3", ] [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "plist" @@ -5900,7 +7223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.4.0", + "indexmap 2.6.0", "quick-xml 0.32.0", "serde", "time", @@ -5908,9 +7231,9 @@ dependencies = [ [[package]] name = "png" -version = "0.17.13" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -5937,15 +7260,15 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.3" +version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.34", + "rustix 0.38.41", "tracing", "windows-sys 0.59.0", ] @@ -5989,7 +7312,7 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", ] [[package]] @@ -6013,11 +7336,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit 0.22.22", ] [[package]] @@ -6052,30 +7375,43 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] -name = "profiling" -version = "1.0.15" +name = "proc-macro2-diagnostics" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "version_check", + "yansi", +] + +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -6132,10 +7468,19 @@ dependencies = [ ] [[package]] -name = "quote" -version = "1.0.36" +name = "quick-xml" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -6227,6 +7572,44 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rasn" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9b0d03fbc7d2dcfdd35086c43ce30ac5ff62ed7eff4397e4f4f2995a2b0e2a" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "bitvec-nom2", + "bytes", + "chrono", + "either", + "jzon", + "konst", + "nom", + "num-bigint", + "num-integer", + "num-traits", + "once_cell", + "rasn-derive", + "snafu", +] + +[[package]] +name = "rasn-derive" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbaf7105cd254b632f4732fbcc243ce750cef87d8335826125ef6df5733b5a0c" +dependencies = [ + "either", + "itertools 0.10.5", + "proc-macro2", + "quote", + "rayon", + "syn 1.0.109", + "uuid", +] + [[package]] name = "rav1e" version = "0.7.1" @@ -6257,22 +7640,23 @@ dependencies = [ "rand_chacha 0.3.1", "simd_helpers", "system-deps", - "thiserror", + "thiserror 1.0.69", "v_frame", "wasm-bindgen", ] [[package]] name = "ravif" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f0bfd976333248de2078d350bfdf182ff96e168a24d23d2436cef320dd4bdd" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" dependencies = [ "avif-serialize", "imgref", "loop9", "quick-error", "rav1e", + "rayon", "rgb", ] @@ -6302,6 +7686,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rc2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62c64daa8e9438b84aaae55010a93f396f8e60e3911590fcba770d04643fc1dd" +dependencies = [ + "cipher", +] + [[package]] name = "redox_syscall" version = "0.1.57" @@ -6310,9 +7703,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -6330,58 +7723,49 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.1.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax", ] [[package]] -name = "regex-syntax" -version = "0.6.29" +name = "regex-lite" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" @@ -6394,9 +7778,51 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.5" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.31", + "hyper-rustls 0.24.2", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", + "tokio", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", @@ -6404,12 +7830,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.7", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.5.1", + "hyper-rustls 0.27.3", "hyper-tls", "hyper-util", "ipnet", @@ -6420,12 +7846,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 2.2.0", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", - "system-configuration", + "sync_wrapper 1.0.2", + "system-configuration 0.6.1", "tokio", "tokio-native-tls", "tokio-util", @@ -6435,7 +7861,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "winreg", + "windows-registry 0.2.0", ] [[package]] @@ -6445,7 +7871,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7314563c59c7ce31c18e23ad3dd092c37b928a0fa4e1c0a1a6504351ab411d1" dependencies = [ "gif", - "image-webp", + "image-webp 0.1.3", "log", "pico-args", "rgb", @@ -6455,6 +7881,17 @@ dependencies = [ "zune-jpeg", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -6467,21 +7904,20 @@ dependencies = [ [[package]] name = "rfd" -version = "0.14.1" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" +checksum = "46f6f80a9b882647d9014673ca9925d30ffc9750f2eed2b4490e189eaebd01e8" dependencies = [ - "ashpd 0.8.1", - "block", - "dispatch", + "ashpd 0.10.2", + "block2", "glib-sys", "gobject-sys", "gtk-sys", "js-sys", "log", - "objc", - "objc-foundation", - "objc_id", + "objc2", + "objc2-app-kit", + "objc2-foundation", "raw-window-handle", "wasm-bindgen", "wasm-bindgen-futures", @@ -6491,9 +7927,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f86ae463694029097b846d8f99fd5536740602ae00022c0c50c5600720b2f71" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" dependencies = [ "bytemuck", ] @@ -6524,9 +7960,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -6542,9 +7978,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -6599,7 +8035,7 @@ dependencies = [ "pgp", "sha1", "sha2", - "thiserror", + "thiserror 1.0.69", "xz2", "zstd", ] @@ -6616,10 +8052,10 @@ dependencies = [ "num-integer", "num-traits", "pkcs1", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", "subtle", "zeroize", ] @@ -6658,9 +8094,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec 0.7.6", "borsh", @@ -6686,13 +8122,22 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustix" version = "0.37.27" @@ -6709,9 +8154,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -6720,55 +8165,111 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + [[package]] name = "rustls" version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ + "log", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] [[package]] -name = "rustls-pemfile" -version = "2.1.3" +name = "rustls-native-certs" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -6777,9 +8278,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rustybuzz" @@ -6799,6 +8300,17 @@ dependencies = [ "unicode-script", ] +[[package]] +name = "ruzstd" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" +dependencies = [ + "byteorder", + "derive_more", + "twox-hash", +] + [[package]] name = "ryu" version = "1.0.18" @@ -6825,11 +8337,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6844,6 +8356,7 @@ dependencies = [ "serde", "serde_json", "url", + "uuid", ] [[package]] @@ -6855,7 +8368,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -6870,6 +8383,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scroll" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "scrypt" version = "0.11.0" @@ -6881,22 +8414,46 @@ dependencies = [ "sha2", ] +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "seahash" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.9", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -6916,9 +8473,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -6961,9 +8518,9 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.208" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -6990,14 +8547,26 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.208" +name = "serde-xml-rs" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" +dependencies = [ + "log", + "serde", + "thiserror 1.0.69", + "xml-rs", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -7008,7 +8577,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -7022,12 +8591,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "indexmap 2.4.0", - "itoa 1.0.11", + "indexmap 2.6.0", + "itoa 1.0.14", "memchr", "ryu", "serde", @@ -7039,7 +8608,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ - "itoa 1.0.11", + "itoa 1.0.14", "serde", ] @@ -7051,14 +8620,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -7070,22 +8639,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.11", + "itoa 1.0.14", "ryu", "serde", ] [[package]] name = "serde_with" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.4.0", + "indexmap 2.6.0", "serde", "serde_derive", "serde_json", @@ -7095,14 +8664,27 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.6.0", + "itoa 1.0.14", + "ryu", + "serde", + "unsafe-libyaml", ] [[package]] @@ -7194,15 +8776,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shared_child" version = "1.0.1" @@ -7234,6 +8807,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "signature" version = "2.2.0" @@ -7261,9 +8844,27 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "simple-file-manifest" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd19be0257552dd56d1bb6946f89f193c6e5b9f13cc9327c4bc84a357507c74" + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror 1.0.69", + "time", +] [[package]] name = "simplecss" @@ -7316,6 +8917,29 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "snafu" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +dependencies = [ + "backtrace", + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "socket2" version = "0.4.10" @@ -7349,25 +8973,24 @@ dependencies = [ [[package]] name = "softbuffer" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d623bff5d06f60d738990980d782c8c866997d9194cfe79ecad00aa2f76826dd" +checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" dependencies = [ "bytemuck", "cfg_aliases", - "core-graphics 0.23.2", + "core-graphics 0.24.0", "foreign-types 0.5.0", "js-sys", "log", "objc2", - "objc2-app-kit", "objc2-foundation", "objc2-quartz-core", "raw-window-handle", - "redox_syscall 0.5.3", + "redox_syscall 0.5.7", "wasm-bindgen", "web-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7379,7 +9002,7 @@ dependencies = [ "base64 0.22.1", "bytes", "futures", - "http", + "http 1.1.0", "httparse", "log", "rand 0.8.5", @@ -7412,13 +9035,32 @@ dependencies = [ "system-deps", ] +[[package]] +name = "spake2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5482afe85a0b6ce956c945401598dbc527593c77ba51d0a87a586938b1b893a" +dependencies = [ + "curve25519-dalek", + "hkdf", + "rand_core 0.6.4", + "sha2", +] + [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ - "lock_api", + "base64ct", + "der 0.6.1", ] [[package]] @@ -7428,7 +9070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.9", ] [[package]] @@ -7437,15 +9079,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "state" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" -dependencies = [ - "loom", -] - [[package]] name = "static_assertions" version = "1.1.0" @@ -7531,15 +9164,15 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sval" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53eb957fbc79a55306d5d25d87daf3627bc3800681491cda0709eef36c748bfe" +checksum = "f6dc0f9830c49db20e73273ffae9b5240f63c42e515af1da1fceefb69fceafd8" [[package]] name = "sval_buffer" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96e860aef60e9cbf37888d4953a13445abf523c534640d1f6174d310917c410d" +checksum = "429922f7ad43c0ef8fd7309e14d750e38899e32eb7e8da656ea169dd28ee212f" dependencies = [ "sval", "sval_ref", @@ -7547,40 +9180,40 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3f2b07929a1127d204ed7cb3905049381708245727680e9139dac317ed556f" +checksum = "68f16ff5d839396c11a30019b659b0976348f3803db0626f736764c473b50ff4" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e188677497de274a1367c4bda15bd2296de4070d91729aac8f0a09c1abf64d" +checksum = "c01c27a80b6151b0557f9ccbe89c11db571dc5f68113690c1e028d7e974bae94" dependencies = [ - "itoa 1.0.11", + "itoa 1.0.14", "ryu", "sval", ] [[package]] name = "sval_json" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f456c07dae652744781f2245d5e3b78e6a9ebad70790ac11eb15dbdbce5282" +checksum = "0deef63c70da622b2a8069d8600cf4b05396459e665862e7bdb290fd6cf3f155" dependencies = [ - "itoa 1.0.11", + "itoa 1.0.14", "ryu", "sval", ] [[package]] name = "sval_nested" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886feb24709f0476baaebbf9ac10671a50163caa7e439d7a7beb7f6d81d0a6fb" +checksum = "a39ce5976ae1feb814c35d290cf7cf8cd4f045782fe1548d6bc32e21f6156e9f" dependencies = [ "sval", "sval_buffer", @@ -7589,18 +9222,18 @@ dependencies = [ [[package]] name = "sval_ref" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2e7fc517d778f44f8cb64140afa36010999565528d48985f55e64d45f369ce" +checksum = "bb7c6ee3751795a728bc9316a092023529ffea1783499afbc5c66f5fabebb1fa" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79bf66549a997ff35cd2114a27ac4b0c2843280f2cfa84b240d169ecaa0add46" +checksum = "2a5572d0321b68109a343634e3a5d576bf131b82180c6c442dee06349dfc652a" dependencies = [ "serde", "sval", @@ -7609,9 +9242,9 @@ dependencies = [ [[package]] name = "svgtypes" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fae3064df9b89391c9a76a0425a69d124aee9c5c28455204709e72c39868a43c" +checksum = "794de53cc48eaabeed0ab6a3404a65f40b3e38c067e4435883a65d2aa4ca000e" dependencies = [ "kurbo", "siphasher 1.0.1", @@ -7641,27 +9274,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.75" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.75", -] - [[package]] name = "sync_wrapper" version = "0.1.2" @@ -7670,15 +9291,41 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] [[package]] name = "sys-locale" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" dependencies = [ "libc", ] @@ -7692,7 +9339,7 @@ dependencies = [ "bitflags 1.3.2", "byteorder", "libc", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -7704,7 +9351,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.9.4", + "system-configuration-sys 0.6.0", ] [[package]] @@ -7717,6 +9375,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -7732,12 +9400,12 @@ dependencies = [ [[package]] name = "tao" -version = "0.29.1" +version = "0.30.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a97abbc7d6cfd0720da3e06fcb1cf2ac87cbfdb5bbbce103a1279a211c4d81" +checksum = "6682a07cf5bab0b8a2bd20d0a542917ab928b5edb75ebd4eda6b05cbaab872da" dependencies = [ "bitflags 2.6.0", - "cocoa 0.26.0", + "cocoa", "core-foundation 0.10.0", "core-graphics 0.24.0", "crossbeam-channel", @@ -7771,13 +9439,13 @@ dependencies = [ [[package]] name = "tao-macros" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] @@ -7788,9 +9456,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.41" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", @@ -7805,13 +9473,12 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.0.0-rc.8" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8345ccc676ef16e26b61fc0f5340b4e770678b1e1f53f08c69ebdac5e56b422" +checksum = "e545de0a2dfe296fa67db208266cd397c5a55ae782da77973ef4c4fac90e9f2c" dependencies = [ "anyhow", "bytes", - "cocoa 0.26.0", "dirs 5.0.1", "dunce", "embed_plist", @@ -7820,29 +9487,31 @@ dependencies = [ "glob", "gtk", "heck 0.5.0", - "http", - "image 0.24.9", + "http 1.1.0", + "image", "jni", "libc", "log", "mime", "muda", - "objc", + "objc2", + "objc2-app-kit", + "objc2-foundation", "percent-encoding", + "plist", "raw-window-handle", - "reqwest", + "reqwest 0.12.9", "serde", "serde_json", "serde_repr", "serialize-to-javascript", - "state", "swift-rs", "tauri-build", "tauri-macros", "tauri-runtime", "tauri-runtime-wry", - "tauri-utils 2.0.0-rc.7", - "thiserror", + "tauri-utils 2.1.0", + "thiserror 2.0.3", "tokio", "tray-icon", "url", @@ -7855,21 +9524,21 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.0-rc.7" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5ad5fcfaf02cf79aa6727f6c5df38567d8dce172b00b62690c6bc46c08b7ce" +checksum = "7bd2a4bcfaf5fb9f4be72520eefcb61ae565038f8ccba2a497d8c28f463b8c01" dependencies = [ "anyhow", "cargo_toml", "dirs 5.0.1", "glob", "heck 0.5.0", - "json-patch 2.0.0", + "json-patch 3.0.1", "schemars", "semver", "serde", "serde_json", - "tauri-utils 2.0.0-rc.7", + "tauri-utils 2.1.0", "tauri-winres", "toml 0.8.19", "walkdir", @@ -7877,9 +9546,9 @@ dependencies = [ [[package]] name = "tauri-bundler" -version = "2.0.1-rc.6" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00a0e120d67416e774923fc07a7b531ba6898ed08f0d6e07fe79d7e3da7e0c04" +checksum = "a829580e402e515d2d1947f7c945c46cb8b843b0f80965d363aa6c62160e2663" dependencies = [ "anyhow", "ar", @@ -7891,7 +9560,7 @@ dependencies = [ "handlebars", "heck 0.5.0", "hex", - "image 0.25.2", + "image", "log", "md5", "os_pipe", @@ -7907,29 +9576,31 @@ dependencies = [ "tar", "tauri-icns", "tauri-macos-sign", - "tauri-utils 2.0.0-rc.7", + "tauri-utils 2.1.0", "tempfile", - "thiserror", + "thiserror 2.0.3", "time", "ureq", + "url", "uuid", "walkdir", - "windows-registry", + "windows-registry 0.3.0", "windows-sys 0.59.0", - "zip", + "zip 2.2.1", ] [[package]] name = "tauri-cli" -version = "2.0.0-rc.8" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc42d318b25224c40f88550308f8cc8746a38534d450ce9c553f8c93f335499" +checksum = "41bd283c8aba340b8db472647f43511768ad280fe49e3bd3e76b4117903e7590" dependencies = [ "anyhow", + "ar", "axum", "base64 0.22.1", "cargo-mobile2", - "clap 4.5.16", + "clap 4.5.21", "clap_complete", "colored", "common-path", @@ -7939,16 +9610,16 @@ dependencies = [ "duct", "dunce", "elf", - "env_logger", + "env_logger 0.11.5", "glob", "handlebars", "heck 0.5.0", "html5ever", "ignore", - "image 0.25.2", + "image", "include_dir", "itertools 0.13.0", - "json-patch 2.0.0", + "json-patch 3.0.1", "jsonrpsee", "jsonrpsee-client-transport", "jsonrpsee-core", @@ -7963,6 +9634,7 @@ dependencies = [ "minisign", "notify", "notify-debouncer-mini", + "object 0.36.5", "os_info", "os_pipe", "oxc_allocator", @@ -7971,6 +9643,7 @@ dependencies = [ "oxc_span", "phf 0.11.2", "plist", + "rand 0.8.5", "regex", "resvg", "semver", @@ -7983,27 +9656,28 @@ dependencies = [ "tauri-icns", "tauri-macos-sign", "tauri-utils 1.6.0", - "tauri-utils 2.0.0-rc.7", + "tauri-utils 2.1.0", "tempfile", "tokio", "toml 0.8.19", - "toml_edit 0.22.20", + "toml_edit 0.22.22", "ureq", "url", + "uuid", "walkdir", "windows-sys 0.59.0", ] [[package]] name = "tauri-codegen" -version = "2.0.0-rc.7" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809ef6316726fc72593d296cf6f4e7461326e310c313d6a6c42b6e7f1e2671cf" +checksum = "bf79faeecf301d3e969b1fae977039edb77a4c1f25cc0a961be298b54bff97cf" dependencies = [ "base64 0.22.1", "brotli", "ico", - "json-patch 2.0.0", + "json-patch 3.0.1", "plist", "png", "proc-macro2", @@ -8012,9 +9686,9 @@ dependencies = [ "serde", "serde_json", "sha2", - "syn 2.0.75", - "tauri-utils 2.0.0-rc.7", - "thiserror", + "syn 2.0.89", + "tauri-utils 2.1.0", + "thiserror 2.0.3", "time", "url", "uuid", @@ -8033,15 +9707,18 @@ dependencies = [ [[package]] name = "tauri-macos-sign" -version = "0.1.1-rc.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea6debc5d6182af338fb92bda2b399332d6495d3cbc1238e5cbbf82ad56c09b" +checksum = "be95e2d37d1e3605831da071234418c786684af48982509af1b7f50b31af4546" dependencies = [ "anyhow", + "apple-codesign", + "chrono", "dirs-next", "log", "once-cell-regex", "os_pipe", + "p12", "plist", "rand 0.8.5", "serde", @@ -8052,23 +9729,23 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.0-rc.6" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1359e8861d210d25731f8b1bfbb4d111dd06406cf73c59659366ef450364d811" +checksum = "c52027c8c5afb83166dacddc092ee8fff50772f9646d461d8c33ee887e447a03" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", "tauri-codegen", - "tauri-utils 2.0.0-rc.7", + "tauri-utils 2.1.0", ] [[package]] name = "tauri-plugin" -version = "2.0.0-rc.3" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec01af01098a286d3e430c1fa947bfd77bc8011ecb209438af4444b02d82b29e" +checksum = "e753f2a30933a9bbf0a202fa47d7cc4a3401f06e8d6dcc53b79aa62954828c79" dependencies = [ "anyhow", "glob", @@ -8076,34 +9753,32 @@ dependencies = [ "schemars", "serde", "serde_json", - "tauri-utils 2.0.0-rc.7", + "tauri-utils 2.1.0", "toml 0.8.19", "walkdir", ] [[package]] name = "tauri-plugin-clipboard-manager" -version = "2.0.0-rc.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6719e5f3fcc6c6f5afda68da944a44a50c28f30a3506c457ea7dbcc13377bfe0" +checksum = "2a66feaa0fb7fce8e5073323d11ca381c9da7ac06f458e42b9ff77364b76a360" dependencies = [ "arboard", - "image 0.24.9", "log", "serde", "serde_json", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "tauri-plugin-dialog" -version = "2.0.0-rc.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf99017391fdc40b6c8ae0dae8d970cc8151a8177d48b8805f320f52cac0e3c" +checksum = "4307310e1d2c09ab110235834722e7c2b85099b683e1eb7342ab351b0be5ada3" dependencies = [ - "dunce", "log", "raw-window-handle", "rfd", @@ -8112,37 +9787,40 @@ dependencies = [ "tauri", "tauri-plugin", "tauri-plugin-fs", - "thiserror", + "thiserror 1.0.69", + "url", ] [[package]] name = "tauri-plugin-fs" -version = "2.0.0-rc.0" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df6b25b1f2b7b61565e66c4dbee9eb39e5635d2a763206e380e07cc3f601a67" +checksum = "96ba7d46e86db8c830d143ef90ab5a453328365b0cc834c24edea4267b16aba0" dependencies = [ "anyhow", + "dunce", "glob", + "percent-encoding", "schemars", "serde", "serde_json", "serde_repr", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.69", "url", "uuid", ] [[package]] name = "tauri-plugin-log" -version = "2.0.0-rc.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380d27f23c39cde6a73024e65d8ec9b5b0af861e968dbe16b3aad86cd2c578e5" +checksum = "8aa13d15daf90230ba26d5a9b4a4612975fa64ce17290cb7f6e0f89bb6997d82" dependencies = [ "android_logger", "byte-unit", - "cocoa 0.25.0", + "cocoa", "fern", "log", "objc", @@ -8152,15 +9830,15 @@ dependencies = [ "swift-rs", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.69", "time", ] [[package]] name = "tauri-plugin-notification" -version = "2.0.0-rc.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35677cdcdb4dc3f3ef6891f31b8ea314045064752912d66e676a4f1577b57ffa" +checksum = "ef492a2d19b6376bb4c9e0c4fab3f3bf8a220ea112d24f35027b737ff55de20c" dependencies = [ "log", "notify-rust", @@ -8170,18 +9848,18 @@ dependencies = [ "serde_repr", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.69", "time", "url", ] [[package]] name = "tauri-plugin-os" -version = "2.0.0-rc.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b54cfeb26356822d3be3db4282041b03552f573a694b6b28aded7d95c62a039" +checksum = "fbc5f23a86f37687c7f4fecfdc706b279087bc44f7a46702f7307ff1551ee03a" dependencies = [ - "gethostname", + "gethostname 0.5.0", "log", "os_info", "serde", @@ -8190,14 +9868,14 @@ dependencies = [ "sys-locale", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "tauri-plugin-shell" -version = "2.0.0-rc.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2133e5c6fe2ae0263ff5920feed477d3b1413f89033f537966831b0cb6f61f8e" +checksum = "0ad7880c5586b6b2104be451e3d7fc0f3800c84bda69e9ba81c828f87cb34267" dependencies = [ "encoding_rs", "log", @@ -8210,30 +9888,30 @@ dependencies = [ "shared_child", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.69", "tokio", ] [[package]] name = "tauri-plugin-single-instance" -version = "2.0.0-rc.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de552151b4c9ba9ff72c7244dccaadd47f88d1f0d5caa2603c5c1c12b7636edc" +checksum = "a25ac834491d089699a2bc9266a662faf373c9f779f05a2235bc6e4d9e61769a" dependencies = [ "log", "serde", "serde_json", "tauri", - "thiserror", - "windows-sys 0.52.0", + "thiserror 1.0.69", + "windows-sys 0.59.0", "zbus 4.4.0", ] [[package]] name = "tauri-plugin-window-state" -version = "2.0.0-rc.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb6839228cbd225b95681c766cc51113e9dad62c4b3f6ebb102234413ba85ee2" +checksum = "683c8764751fbbcebf3a594bcee24cf84c62773fa0080d1b40fc80698472421e" dependencies = [ "bitflags 2.6.0", "log", @@ -8241,45 +9919,47 @@ dependencies = [ "serde_json", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "tauri-runtime" -version = "2.0.0-rc.7" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c72b844f387bfc3341c355f3e16b8cbf4161848fa4e348670effb222cd3ba5" +checksum = "cce18d43f80d4aba3aa8a0c953bbe835f3d0f2370aca75e8dbb14bd4bab27958" dependencies = [ "dpi", "gtk", - "http", + "http 1.1.0", "jni", "raw-window-handle", "serde", "serde_json", - "tauri-utils 2.0.0-rc.7", - "thiserror", + "tauri-utils 2.1.0", + "thiserror 2.0.3", "url", "windows 0.58.0", ] [[package]] name = "tauri-runtime-wry" -version = "2.0.0-rc.7" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73accf936a7cd01d1382de7850726fdf6c1f6ab3b01ccb7a0950cb852e332596" +checksum = "9f442a38863e10129ffe2cec7bd09c2dcf8a098a3a27801a476a304d5bb991d2" dependencies = [ - "cocoa 0.26.0", "gtk", - "http", + "http 1.1.0", "jni", "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", "percent-encoding", "raw-window-handle", "softbuffer", "tao", "tauri-runtime", - "tauri-utils 2.0.0-rc.7", + "tauri-utils 2.1.0", "url", "webkit2gtk", "webview2-com", @@ -8312,7 +9992,7 @@ dependencies = [ "serde_json", "serde_with", "serialize-to-javascript", - "thiserror", + "thiserror 1.0.69", "toml 0.7.8", "url", "windows-version", @@ -8320,9 +10000,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.0.0-rc.7" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53d9fe87e985b273696ae22ce2b9f099a8f1b44bc8fb127467bda5fcb3e4371" +checksum = "9271a88f99b4adea0dc71d0baca4505475a0bbd139fb135f62958721aaa8fe54" dependencies = [ "aes-gcm", "brotli", @@ -8332,8 +10012,9 @@ dependencies = [ "getrandom 0.2.15", "glob", "html5ever", - "infer 0.15.0", - "json-patch 2.0.0", + "http 1.1.0", + "infer 0.16.0", + "json-patch 3.0.1", "json5", "kuchikiki", "log", @@ -8350,10 +10031,11 @@ dependencies = [ "serde_with", "serialize-to-javascript", "swift-rs", - "thiserror", + "thiserror 2.0.3", "toml 0.8.19", "url", "urlpattern", + "uuid", "walkdir", ] @@ -8391,14 +10073,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", - "fastrand 2.1.0", + "fastrand 2.2.0", "once_cell", - "rustix 0.38.34", + "rustix 0.38.41", "windows-sys 0.59.0", ] @@ -8413,6 +10095,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "terminal_size" version = "0.2.6" @@ -8452,32 +10143,42 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] -name = "thread_local" -version = "1.1.8" +name = "thiserror-impl" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ - "cfg-if", - "once_cell", + "proc-macro2", + "quote", + "syn 2.0.89", ] [[package]] @@ -8498,7 +10199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", - "itoa 1.0.11", + "itoa 1.0.14", "libc", "num-conv", "num_threads", @@ -8559,6 +10260,16 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -8576,9 +10287,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -8600,7 +10311,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -8613,6 +10324,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.25.0" @@ -8630,16 +10351,16 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.12", + "rustls 0.23.18", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -8649,21 +10370,21 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.21.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.24.0", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -8683,7 +10404,7 @@ dependencies = [ "bytes", "futures-core", "futures-sink", - "http", + "http 1.1.0", "httparse", "rand 0.8.5", "ring", @@ -8711,11 +10432,11 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit 0.22.22", ] [[package]] @@ -8733,7 +10454,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -8746,33 +10467,22 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.6.0", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.4.0", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" -dependencies = [ - "indexmap 2.4.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow 0.6.20", ] [[package]] @@ -8785,6 +10495,21 @@ dependencies = [ "futures-util", "pin-project", "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", "tokio", "tower-layer", "tower-service", @@ -8823,53 +10548,23 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", ] [[package]] name = "tray-icon" -version = "0.16.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131a65b2cef2081bc14dbcd414c906edbfa3bb5323dd7e748cc298614681196b" +checksum = "d48a05076dd272615d03033bf04f480199f7d1b66a8ac64d75c625fc4a70c06b" dependencies = [ "core-graphics 0.24.0", "crossbeam-channel", @@ -8882,7 +10577,7 @@ dependencies = [ "once_cell", "png", "serde", - "thiserror", + "thiserror 1.0.69", "windows-sys 0.59.0", ] @@ -8910,13 +10605,34 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.1.0", + "httparse", + "log", + "rand 0.8.5", + "rustls 0.22.4", + "rustls-native-certs 0.7.3", + "rustls-pki-types", + "sha1", + "thiserror 1.0.69", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", "httparse", "log", "rand 0.8.5", "sha1", - "thiserror", - "url", + "thiserror 1.0.69", "utf-8", ] @@ -8929,6 +10645,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + [[package]] name = "typeid" version = "1.0.2" @@ -8942,10 +10668,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "ucd-trie" -version = "0.1.6" +name = "typewit" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "d51dbd25812f740f45e2a9769f84711982e000483b13b73a8a1852e092abac8c" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uds_windows" @@ -8967,6 +10708,15 @@ dependencies = [ "libc", ] +[[package]] +name = "uncased" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "version_check", +] + [[package]] name = "unic-char-property" version = "0.9.0" @@ -9010,9 +10760,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-bidi-mirroring" @@ -9028,15 +10778,15 @@ checksum = "260bc6647b3893a9a90668360803a15f96b85a5257b1c3a0c3daf6ae2496de42" [[package]] name = "unicode-id-start" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc3882f69607a2ac8cc4de3ee7993d8f68bb06f2974271195065b3bd07f2edea" +checksum = "2f322b60f6b9736017344fa0635d64be2f458fbc04eef65f6be22976dd1ffd5b" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-linebreak" @@ -9044,32 +10794,23 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-script" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd" +checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-vo" @@ -9079,9 +10820,15 @@ checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -9093,6 +10840,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "untrusted" version = "0.9.0" @@ -9109,18 +10862,18 @@ dependencies = [ "flate2", "log", "once_cell", - "rustls 0.23.12", + "rustls 0.23.18", "rustls-pki-types", "socks", "url", - "webpki-roots", + "webpki-roots 0.26.7", ] [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -9129,12 +10882,17 @@ dependencies = [ ] [[package]] -name = "urlpattern" -version = "0.2.0" +name = "urlencoding" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9bd5ff03aea02fa45b13a7980151fe45009af1980ba69f651ec367121a31609" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "urlpattern" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" dependencies = [ - "derive_more", "regex", "serde", "unic-ucd-ident", @@ -9174,12 +10932,24 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + [[package]] name = "utf8-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -9188,11 +10958,12 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom 0.2.15", + "serde", "sha1_smol", ] @@ -9207,17 +10978,11 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "value-bag" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -9225,9 +10990,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccacf50c5cb077a9abb723c5bcb5e0754c1a433f1e1de89edc328e2760b6328b" +checksum = "4bb773bd36fd59c7ca6e336c94454d9c66386416734817927ac93d81cb3c5b0b" dependencies = [ "erased-serde", "serde", @@ -9236,9 +11001,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1785bae486022dfb9703915d42287dcb284c1ee37bd1080eeba78cc04721285b" +checksum = "53a916a702cac43a88694c97657d449775667bcd14b70419441d05b7fea4a83a" dependencies = [ "sval", "sval_buffer", @@ -9279,6 +11044,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "vswhom" version = "0.1.0" @@ -9338,9 +11109,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -9349,24 +11120,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -9376,9 +11147,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -9386,28 +11157,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-streams" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -9417,10 +11188,70 @@ dependencies = [ ] [[package]] -name = "web-sys" -version = "0.3.70" +name = "wayland-backend" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +dependencies = [ + "cc", + "downcast-rs", + "rustix 0.38.41", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +dependencies = [ + "bitflags 2.6.0", + "rustix 0.38.41", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +dependencies = [ + "proc-macro2", + "quick-xml 0.36.2", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +dependencies = [ + "dlib", + "log", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -9472,9 +11303,15 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -9501,7 +11338,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -9510,7 +11347,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3a3e2eeb58f82361c93f9777014668eb3d07e7d174ee4c819575a9208011886" dependencies = [ - "thiserror", + "thiserror 1.0.69", "windows 0.58.0", "windows-core 0.58.0", ] @@ -9529,7 +11366,7 @@ checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" dependencies = [ "either", "home", - "rustix 0.38.34", + "rustix 0.38.41", "winsafe", ] @@ -9572,26 +11409,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window-vibrancy" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8cdd6999298d969289d8078dae02ce798ad23452075985cccba8b6326711ecf" +checksum = "3ea403deff7b51fff19e261330f71608ff2cdef5721d72b64180bb95be7c4150" dependencies = [ - "cocoa 0.26.0", - "objc", + "objc2", + "objc2-app-kit", + "objc2-foundation", "raw-window-handle", "windows-sys 0.59.0", "windows-version", ] -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows" version = "0.54.0" @@ -9662,7 +11491,7 @@ dependencies = [ "windows-implement 0.58.0", "windows-interface 0.58.0", "windows-result 0.2.0", - "windows-strings", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] @@ -9674,7 +11503,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -9685,7 +11514,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -9696,7 +11525,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -9707,7 +11536,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", ] [[package]] @@ -9717,7 +11546,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ "windows-result 0.2.0", - "windows-strings", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-registry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bafa604f2104cf5ae2cc2db1dee84b7e6a5d11b05f737b60def0ffdc398cbc0a" +dependencies = [ + "windows-result 0.2.0", + "windows-strings 0.2.0", "windows-targets 0.52.6", ] @@ -9760,6 +11600,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978d65aedf914c664c510d9de43c8fd85ca745eaff1ed53edf409b479e441663" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -9994,13 +11843,23 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winreg" version = "0.52.0" @@ -10018,36 +11877,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] -name = "wry" -version = "0.42.0" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b8049c8f239cdbfaaea4bacb9646f6b208938ceec0acd5b3e99cd05f70903f" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "wry" +version = "0.47.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ce51277d65170f6379d8cda935c80e3c2d1f0ff712a123c8bddb11b31a4b73" dependencies = [ "base64 0.22.1", - "block", - "cocoa 0.26.0", - "core-graphics 0.24.0", + "block2", + "cookie", "crossbeam-channel", "dpi", "dunce", "gdkx11", "gtk", "html5ever", - "http", + "http 1.1.0", "javascriptcore-rs", "jni", "kuchikiki", "libc", "ndk", - "objc", - "objc_id", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", "once_cell", "percent-encoding", "raw-window-handle", "sha2", "soup3", "tao-macros", - "thiserror", + "thiserror 1.0.69", + "url", "webkit2gtk", "webkit2gtk-sys", "webview2-com", @@ -10093,8 +11967,8 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ - "gethostname", - "rustix 0.38.34", + "gethostname 0.4.3", + "rustix 0.38.41", "x11rb-protocol", ] @@ -10116,6 +11990,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x509" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3cec94c3999f31341553f358ef55f65fc031291a022cd42ec0ce7219560c76" +dependencies = [ + "chrono", + "cookie-factory", +] + [[package]] name = "x509-certificate" version = "0.23.1" @@ -10125,13 +12009,13 @@ dependencies = [ "bcder", "bytes", "chrono", - "der", + "der 0.7.9", "hex", "pem", "ring", - "signature", - "spki", - "thiserror", + "signature 2.2.0", + "spki 0.7.3", + "thiserror 1.0.69", "zeroize", ] @@ -10143,7 +12027,7 @@ checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", "linux-raw-sys 0.4.14", - "rustix 0.38.34", + "rustix 0.38.41", ] [[package]] @@ -10162,6 +12046,18 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "xml-rs" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" + +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "xmlwriter" version = "0.1.0" @@ -10177,6 +12073,42 @@ dependencies = [ "lzma-sys", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure 0.13.1", +] + [[package]] name = "zbus" version = "3.15.2" @@ -10227,9 +12159,9 @@ dependencies = [ "async-broadcast 0.7.1", "async-executor", "async-fs 2.1.2", - "async-io 2.3.4", + "async-io 2.4.0", "async-lock 3.4.0", - "async-process 2.2.4", + "async-process 2.3.0", "async-recursion", "async-task", "async-trait", @@ -10247,7 +12179,6 @@ dependencies = [ "serde_repr", "sha1", "static_assertions", - "tokio", "tracing", "uds_windows", "windows-sys 0.52.0", @@ -10257,6 +12188,36 @@ dependencies = [ "zvariant 4.2.0", ] +[[package]] +name = "zbus" +version = "5.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1162094dc63b1629fcc44150bcceeaa80798cd28bcbe7fa987b65a034c258608" +dependencies = [ + "async-broadcast 0.7.1", + "async-recursion", + "async-trait", + "enumflags2", + "event-listener 5.3.1", + "futures-core", + "futures-util", + "hex", + "nix 0.29.0", + "ordered-stream", + "serde", + "serde_repr", + "static_assertions", + "tokio", + "tracing", + "uds_windows", + "windows-sys 0.59.0", + "winnow 0.6.20", + "xdg-home", + "zbus_macros 5.1.1", + "zbus_names 4.1.0", + "zvariant 5.1.0", +] + [[package]] name = "zbus_macros" version = "3.15.2" @@ -10277,13 +12238,28 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", "zvariant_utils 2.1.0", ] +[[package]] +name = "zbus_macros" +version = "5.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd2dcdce3e2727f7d74b7e33b5a89539b3cc31049562137faf7ae4eb86cd16d" +dependencies = [ + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.89", + "zbus_names 4.1.0", + "zvariant 5.1.0", + "zvariant_utils 3.0.2", +] + [[package]] name = "zbus_names" version = "2.6.1" @@ -10306,6 +12282,18 @@ dependencies = [ "zvariant 4.2.0", ] +[[package]] +name = "zbus_names" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "856b7a38811f71846fd47856ceee8bccaec8399ff53fb370247e66081ace647b" +dependencies = [ + "serde", + "static_assertions", + "winnow 0.6.20", + "zvariant 5.1.0", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -10324,7 +12312,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure 0.13.1", ] [[package]] @@ -10344,26 +12353,71 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", ] [[package]] name = "zip" -version = "2.1.6" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40dd8c92efc296286ce1fbd16657c5dbefff44f1b4ca01cc5f517d8b7b3d3e2e" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + +[[package]] +name = "zip" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d52293fc86ea7cf13971b3bb81eb21683636e7ae24c729cdaf1b7c4157a352" dependencies = [ "arbitrary", "crc32fast", "crossbeam-utils", "displaydoc", "flate2", - "indexmap 2.4.0", + "indexmap 2.6.0", "memchr", - "thiserror", + "thiserror 2.0.3", "zopfli", ] +[[package]] +name = "zip_structs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce824a6bfffe8942820fa36d24973b7c83a40896749a42e33de0abdd11750ee5" +dependencies = [ + "byteorder", + "bytesize", + "thiserror 1.0.69", +] + [[package]] name = "zopfli" version = "0.8.1" @@ -10455,10 +12509,25 @@ dependencies = [ "enumflags2", "serde", "static_assertions", - "url", "zvariant_derive 4.2.0", ] +[[package]] +name = "zvariant" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1200ee6ac32f1e5a312e455a949a4794855515d34f9909f4a3e082d14e1a56f" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "url", + "winnow 0.6.20", + "zvariant_derive 5.1.0", + "zvariant_utils 3.0.2", +] + [[package]] name = "zvariant_derive" version = "3.15.2" @@ -10478,13 +12547,26 @@ version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", "zvariant_utils 2.1.0", ] +[[package]] +name = "zvariant_derive" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687e3b97fae6c9104fbbd36c73d27d149abf04fb874e2efbd84838763daa8916" +dependencies = [ + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.89", + "zvariant_utils 3.0.2", +] + [[package]] name = "zvariant_utils" version = "1.0.1" @@ -10504,5 +12586,19 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.89", +] + +[[package]] +name = "zvariant_utils" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d1d011a38f12360e5fcccceeff5e2c42a8eb7f27f0dcba97a0862ede05c9c6" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "static_assertions", + "syn 2.0.89", + "winnow 0.6.20", ] diff --git a/desktop/tauri/src-tauri/Cargo.toml b/desktop/tauri/src-tauri/Cargo.toml index db19639b..0b9c5d38 100644 --- a/desktop/tauri/src-tauri/Cargo.toml +++ b/desktop/tauri/src-tauri/Cargo.toml @@ -12,21 +12,21 @@ rust-version = "1.60" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -tauri-build = { version = "2.0.0-rc.7", features = [] } +tauri-build = { version = "2.0.3", features = [] } [dependencies] # Tauri -tauri = { version = "2.0.0-rc.8", features = ["tray-icon", "image-png", "config-json5", "devtools"] } -tauri-plugin-shell = "2.0.0-rc" -tauri-plugin-dialog = "2.0.0-rc" -tauri-plugin-clipboard-manager = "2.0.0-rc" -tauri-plugin-os = "2.0.0-rc" -tauri-plugin-single-instance = "2.0.0-rc" -tauri-plugin-notification = "2.0.0-rc" -tauri-plugin-log = "2.0.0-rc" -tauri-plugin-window-state = "2.0.0-rc" +tauri = { version = "2.1.1", features = ["tray-icon", "image-png", "config-json5", "devtools"] } +tauri-plugin-shell = "2.0.2" +tauri-plugin-dialog = "2.0.3" +tauri-plugin-clipboard-manager = "2.0.2" +tauri-plugin-os = "2.0.1" +tauri-plugin-single-instance = "2.0.1" +tauri-plugin-notification = "2.0.1" +tauri-plugin-log = "2.0.2" +tauri-plugin-window-state = "2.0.2" -tauri-cli = "2.0.0-rc.8" +tauri-cli = "2.1.0" clap = { version = "4" } # General diff --git a/desktop/tauri/src-tauri/gen/schemas/acl-manifests.json b/desktop/tauri/src-tauri/gen/schemas/acl-manifests.json index 233ccc01..1d974eb0 100644 --- a/desktop/tauri/src-tauri/gen/schemas/acl-manifests.json +++ b/desktop/tauri/src-tauri/gen/schemas/acl-manifests.json @@ -1 +1 @@ -{"clipboard-manager":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n","permissions":[]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-read-image":{"identifier":"allow-read-image","description":"Enables the read_image command without any pre-configured scope.","commands":{"allow":["read_image"],"deny":[]}},"allow-read-text":{"identifier":"allow-read-text","description":"Enables the read_text command without any pre-configured scope.","commands":{"allow":["read_text"],"deny":[]}},"allow-write-html":{"identifier":"allow-write-html","description":"Enables the write_html command without any pre-configured scope.","commands":{"allow":["write_html"],"deny":[]}},"allow-write-image":{"identifier":"allow-write-image","description":"Enables the write_image command without any pre-configured scope.","commands":{"allow":["write_image"],"deny":[]}},"allow-write-text":{"identifier":"allow-write-text","description":"Enables the write_text command without any pre-configured scope.","commands":{"allow":["write_text"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-read-image":{"identifier":"deny-read-image","description":"Denies the read_image command without any pre-configured scope.","commands":{"allow":[],"deny":["read_image"]}},"deny-read-text":{"identifier":"deny-read-text","description":"Denies the read_text command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text"]}},"deny-write-html":{"identifier":"deny-write-html","description":"Denies the write_html command without any pre-configured scope.","commands":{"allow":[],"deny":["write_html"]}},"deny-write-image":{"identifier":"deny-write-image","description":"Denies the write_image command without any pre-configured scope.","commands":{"allow":[],"deny":["write_image"]}},"deny-write-text":{"identifier":"deny-write-text","description":"Denies the write_text command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text"]}}},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"log":{"default_permission":{"identifier":"default","description":"Allows the log command","permissions":["allow-log"]},"permissions":{"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}}},"permission_sets":{},"global_scope_schema":null},"notification":{"default_permission":{"identifier":"default","description":"This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n","permissions":["allow-is-permission-granted","allow-request-permission","allow-notify","allow-register-action-types","allow-register-listener","allow-cancel","allow-get-pending","allow-remove-active","allow-get-active","allow-check-permissions","allow-show","allow-batch","allow-list-channels","allow-delete-channel","allow-create-channel","allow-permission-state"]},"permissions":{"allow-batch":{"identifier":"allow-batch","description":"Enables the batch command without any pre-configured scope.","commands":{"allow":["batch"],"deny":[]}},"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-check-permissions":{"identifier":"allow-check-permissions","description":"Enables the check_permissions command without any pre-configured scope.","commands":{"allow":["check_permissions"],"deny":[]}},"allow-create-channel":{"identifier":"allow-create-channel","description":"Enables the create_channel command without any pre-configured scope.","commands":{"allow":["create_channel"],"deny":[]}},"allow-delete-channel":{"identifier":"allow-delete-channel","description":"Enables the delete_channel command without any pre-configured scope.","commands":{"allow":["delete_channel"],"deny":[]}},"allow-get-active":{"identifier":"allow-get-active","description":"Enables the get_active command without any pre-configured scope.","commands":{"allow":["get_active"],"deny":[]}},"allow-get-pending":{"identifier":"allow-get-pending","description":"Enables the get_pending command without any pre-configured scope.","commands":{"allow":["get_pending"],"deny":[]}},"allow-is-permission-granted":{"identifier":"allow-is-permission-granted","description":"Enables the is_permission_granted command without any pre-configured scope.","commands":{"allow":["is_permission_granted"],"deny":[]}},"allow-list-channels":{"identifier":"allow-list-channels","description":"Enables the list_channels command without any pre-configured scope.","commands":{"allow":["list_channels"],"deny":[]}},"allow-notify":{"identifier":"allow-notify","description":"Enables the notify command without any pre-configured scope.","commands":{"allow":["notify"],"deny":[]}},"allow-permission-state":{"identifier":"allow-permission-state","description":"Enables the permission_state command without any pre-configured scope.","commands":{"allow":["permission_state"],"deny":[]}},"allow-register-action-types":{"identifier":"allow-register-action-types","description":"Enables the register_action_types command without any pre-configured scope.","commands":{"allow":["register_action_types"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-active":{"identifier":"allow-remove-active","description":"Enables the remove_active command without any pre-configured scope.","commands":{"allow":["remove_active"],"deny":[]}},"allow-request-permission":{"identifier":"allow-request-permission","description":"Enables the request_permission command without any pre-configured scope.","commands":{"allow":["request_permission"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"deny-batch":{"identifier":"deny-batch","description":"Denies the batch command without any pre-configured scope.","commands":{"allow":[],"deny":["batch"]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-check-permissions":{"identifier":"deny-check-permissions","description":"Denies the check_permissions command without any pre-configured scope.","commands":{"allow":[],"deny":["check_permissions"]}},"deny-create-channel":{"identifier":"deny-create-channel","description":"Denies the create_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["create_channel"]}},"deny-delete-channel":{"identifier":"deny-delete-channel","description":"Denies the delete_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_channel"]}},"deny-get-active":{"identifier":"deny-get-active","description":"Denies the get_active command without any pre-configured scope.","commands":{"allow":[],"deny":["get_active"]}},"deny-get-pending":{"identifier":"deny-get-pending","description":"Denies the get_pending command without any pre-configured scope.","commands":{"allow":[],"deny":["get_pending"]}},"deny-is-permission-granted":{"identifier":"deny-is-permission-granted","description":"Denies the is_permission_granted command without any pre-configured scope.","commands":{"allow":[],"deny":["is_permission_granted"]}},"deny-list-channels":{"identifier":"deny-list-channels","description":"Denies the list_channels command without any pre-configured scope.","commands":{"allow":[],"deny":["list_channels"]}},"deny-notify":{"identifier":"deny-notify","description":"Denies the notify command without any pre-configured scope.","commands":{"allow":[],"deny":["notify"]}},"deny-permission-state":{"identifier":"deny-permission-state","description":"Denies the permission_state command without any pre-configured scope.","commands":{"allow":[],"deny":["permission_state"]}},"deny-register-action-types":{"identifier":"deny-register-action-types","description":"Denies the register_action_types command without any pre-configured scope.","commands":{"allow":[],"deny":["register_action_types"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-active":{"identifier":"deny-remove-active","description":"Denies the remove_active command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_active"]}},"deny-request-permission":{"identifier":"deny-request-permission","description":"Denies the request_permission command without any pre-configured scope.","commands":{"allow":[],"deny":["request_permission"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}}},"permission_sets":{},"global_scope_schema":null},"os":{"default_permission":{"identifier":"default","description":"This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n","permissions":["allow-arch","allow-exe-extension","allow-family","allow-locale","allow-os-type","allow-platform","allow-version"]},"permissions":{"allow-arch":{"identifier":"allow-arch","description":"Enables the arch command without any pre-configured scope.","commands":{"allow":["arch"],"deny":[]}},"allow-exe-extension":{"identifier":"allow-exe-extension","description":"Enables the exe_extension command without any pre-configured scope.","commands":{"allow":["exe_extension"],"deny":[]}},"allow-family":{"identifier":"allow-family","description":"Enables the family command without any pre-configured scope.","commands":{"allow":["family"],"deny":[]}},"allow-hostname":{"identifier":"allow-hostname","description":"Enables the hostname command without any pre-configured scope.","commands":{"allow":["hostname"],"deny":[]}},"allow-locale":{"identifier":"allow-locale","description":"Enables the locale command without any pre-configured scope.","commands":{"allow":["locale"],"deny":[]}},"allow-os-type":{"identifier":"allow-os-type","description":"Enables the os_type command without any pre-configured scope.","commands":{"allow":["os_type"],"deny":[]}},"allow-platform":{"identifier":"allow-platform","description":"Enables the platform command without any pre-configured scope.","commands":{"allow":["platform"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-arch":{"identifier":"deny-arch","description":"Denies the arch command without any pre-configured scope.","commands":{"allow":[],"deny":["arch"]}},"deny-exe-extension":{"identifier":"deny-exe-extension","description":"Denies the exe_extension command without any pre-configured scope.","commands":{"allow":[],"deny":["exe_extension"]}},"deny-family":{"identifier":"deny-family","description":"Denies the family command without any pre-configured scope.","commands":{"allow":[],"deny":["family"]}},"deny-hostname":{"identifier":"deny-hostname","description":"Denies the hostname command without any pre-configured scope.","commands":{"allow":[],"deny":["hostname"]}},"deny-locale":{"identifier":"deny-locale","description":"Denies the locale command without any pre-configured scope.","commands":{"allow":[],"deny":["locale"]}},"deny-os-type":{"identifier":"deny-os-type","description":"Denies the os_type command without any pre-configured scope.","commands":{"allow":[],"deny":["os_type"]}},"deny-platform":{"identifier":"deny-platform","description":"Denies the platform command without any pre-configured scope.","commands":{"allow":[],"deny":["platform"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","definitions":{"ShellAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"A command allowed to be executed by the webview API.","properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["args","cmd","name","sidecar"],"title":"Entry","type":"object"}},"window-state":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-filename","allow-restore-state","allow-save-window-state"]},"permissions":{"allow-filename":{"identifier":"allow-filename","description":"Enables the filename command without any pre-configured scope.","commands":{"allow":["filename"],"deny":[]}},"allow-restore-state":{"identifier":"allow-restore-state","description":"Enables the restore_state command without any pre-configured scope.","commands":{"allow":["restore_state"],"deny":[]}},"allow-save-window-state":{"identifier":"allow-save-window-state","description":"Enables the save_window_state command without any pre-configured scope.","commands":{"allow":["save_window_state"],"deny":[]}},"deny-filename":{"identifier":"deny-filename","description":"Denies the filename command without any pre-configured scope.","commands":{"allow":[],"deny":["filename"]}},"deny-restore-state":{"identifier":"deny-restore-state","description":"Denies the restore_state command without any pre-configured scope.","commands":{"allow":[],"deny":["restore_state"]}},"deny-save-window-state":{"identifier":"deny-save-window-state","description":"Denies the save_window_state command without any pre-configured scope.","commands":{"allow":[],"deny":["save_window_state"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file +{"clipboard-manager":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n","permissions":[]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-read-image":{"identifier":"allow-read-image","description":"Enables the read_image command without any pre-configured scope.","commands":{"allow":["read_image"],"deny":[]}},"allow-read-text":{"identifier":"allow-read-text","description":"Enables the read_text command without any pre-configured scope.","commands":{"allow":["read_text"],"deny":[]}},"allow-write-html":{"identifier":"allow-write-html","description":"Enables the write_html command without any pre-configured scope.","commands":{"allow":["write_html"],"deny":[]}},"allow-write-image":{"identifier":"allow-write-image","description":"Enables the write_image command without any pre-configured scope.","commands":{"allow":["write_image"],"deny":[]}},"allow-write-text":{"identifier":"allow-write-text","description":"Enables the write_text command without any pre-configured scope.","commands":{"allow":["write_text"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-read-image":{"identifier":"deny-read-image","description":"Denies the read_image command without any pre-configured scope.","commands":{"allow":[],"deny":["read_image"]}},"deny-read-text":{"identifier":"deny-read-text","description":"Denies the read_text command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text"]}},"deny-write-html":{"identifier":"deny-write-html","description":"Denies the write_html command without any pre-configured scope.","commands":{"allow":[],"deny":["write_html"]}},"deny-write-image":{"identifier":"deny-write-image","description":"Denies the write_image command without any pre-configured scope.","commands":{"allow":[],"deny":["write_image"]}},"deny-write-text":{"identifier":"deny-write-text","description":"Denies the write_text command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text"]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-ask","allow-confirm","allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope.","commands":{"allow":["ask"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope.","commands":{"allow":["confirm"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope.","commands":{"allow":[],"deny":["ask"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope.","commands":{"allow":[],"deny":["confirm"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"log":{"default_permission":{"identifier":"default","description":"Allows the log command","permissions":["allow-log"]},"permissions":{"allow-log":{"identifier":"allow-log","description":"Enables the log command without any pre-configured scope.","commands":{"allow":["log"],"deny":[]}},"deny-log":{"identifier":"deny-log","description":"Denies the log command without any pre-configured scope.","commands":{"allow":[],"deny":["log"]}}},"permission_sets":{},"global_scope_schema":null},"notification":{"default_permission":{"identifier":"default","description":"This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n","permissions":["allow-is-permission-granted","allow-request-permission","allow-notify","allow-register-action-types","allow-register-listener","allow-cancel","allow-get-pending","allow-remove-active","allow-get-active","allow-check-permissions","allow-show","allow-batch","allow-list-channels","allow-delete-channel","allow-create-channel","allow-permission-state"]},"permissions":{"allow-batch":{"identifier":"allow-batch","description":"Enables the batch command without any pre-configured scope.","commands":{"allow":["batch"],"deny":[]}},"allow-cancel":{"identifier":"allow-cancel","description":"Enables the cancel command without any pre-configured scope.","commands":{"allow":["cancel"],"deny":[]}},"allow-check-permissions":{"identifier":"allow-check-permissions","description":"Enables the check_permissions command without any pre-configured scope.","commands":{"allow":["check_permissions"],"deny":[]}},"allow-create-channel":{"identifier":"allow-create-channel","description":"Enables the create_channel command without any pre-configured scope.","commands":{"allow":["create_channel"],"deny":[]}},"allow-delete-channel":{"identifier":"allow-delete-channel","description":"Enables the delete_channel command without any pre-configured scope.","commands":{"allow":["delete_channel"],"deny":[]}},"allow-get-active":{"identifier":"allow-get-active","description":"Enables the get_active command without any pre-configured scope.","commands":{"allow":["get_active"],"deny":[]}},"allow-get-pending":{"identifier":"allow-get-pending","description":"Enables the get_pending command without any pre-configured scope.","commands":{"allow":["get_pending"],"deny":[]}},"allow-is-permission-granted":{"identifier":"allow-is-permission-granted","description":"Enables the is_permission_granted command without any pre-configured scope.","commands":{"allow":["is_permission_granted"],"deny":[]}},"allow-list-channels":{"identifier":"allow-list-channels","description":"Enables the list_channels command without any pre-configured scope.","commands":{"allow":["list_channels"],"deny":[]}},"allow-notify":{"identifier":"allow-notify","description":"Enables the notify command without any pre-configured scope.","commands":{"allow":["notify"],"deny":[]}},"allow-permission-state":{"identifier":"allow-permission-state","description":"Enables the permission_state command without any pre-configured scope.","commands":{"allow":["permission_state"],"deny":[]}},"allow-register-action-types":{"identifier":"allow-register-action-types","description":"Enables the register_action_types command without any pre-configured scope.","commands":{"allow":["register_action_types"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-active":{"identifier":"allow-remove-active","description":"Enables the remove_active command without any pre-configured scope.","commands":{"allow":["remove_active"],"deny":[]}},"allow-request-permission":{"identifier":"allow-request-permission","description":"Enables the request_permission command without any pre-configured scope.","commands":{"allow":["request_permission"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"deny-batch":{"identifier":"deny-batch","description":"Denies the batch command without any pre-configured scope.","commands":{"allow":[],"deny":["batch"]}},"deny-cancel":{"identifier":"deny-cancel","description":"Denies the cancel command without any pre-configured scope.","commands":{"allow":[],"deny":["cancel"]}},"deny-check-permissions":{"identifier":"deny-check-permissions","description":"Denies the check_permissions command without any pre-configured scope.","commands":{"allow":[],"deny":["check_permissions"]}},"deny-create-channel":{"identifier":"deny-create-channel","description":"Denies the create_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["create_channel"]}},"deny-delete-channel":{"identifier":"deny-delete-channel","description":"Denies the delete_channel command without any pre-configured scope.","commands":{"allow":[],"deny":["delete_channel"]}},"deny-get-active":{"identifier":"deny-get-active","description":"Denies the get_active command without any pre-configured scope.","commands":{"allow":[],"deny":["get_active"]}},"deny-get-pending":{"identifier":"deny-get-pending","description":"Denies the get_pending command without any pre-configured scope.","commands":{"allow":[],"deny":["get_pending"]}},"deny-is-permission-granted":{"identifier":"deny-is-permission-granted","description":"Denies the is_permission_granted command without any pre-configured scope.","commands":{"allow":[],"deny":["is_permission_granted"]}},"deny-list-channels":{"identifier":"deny-list-channels","description":"Denies the list_channels command without any pre-configured scope.","commands":{"allow":[],"deny":["list_channels"]}},"deny-notify":{"identifier":"deny-notify","description":"Denies the notify command without any pre-configured scope.","commands":{"allow":[],"deny":["notify"]}},"deny-permission-state":{"identifier":"deny-permission-state","description":"Denies the permission_state command without any pre-configured scope.","commands":{"allow":[],"deny":["permission_state"]}},"deny-register-action-types":{"identifier":"deny-register-action-types","description":"Denies the register_action_types command without any pre-configured scope.","commands":{"allow":[],"deny":["register_action_types"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-active":{"identifier":"deny-remove-active","description":"Denies the remove_active command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_active"]}},"deny-request-permission":{"identifier":"deny-request-permission","description":"Denies the request_permission command without any pre-configured scope.","commands":{"allow":[],"deny":["request_permission"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}}},"permission_sets":{},"global_scope_schema":null},"os":{"default_permission":{"identifier":"default","description":"This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n","permissions":["allow-arch","allow-exe-extension","allow-family","allow-locale","allow-os-type","allow-platform","allow-version"]},"permissions":{"allow-arch":{"identifier":"allow-arch","description":"Enables the arch command without any pre-configured scope.","commands":{"allow":["arch"],"deny":[]}},"allow-exe-extension":{"identifier":"allow-exe-extension","description":"Enables the exe_extension command without any pre-configured scope.","commands":{"allow":["exe_extension"],"deny":[]}},"allow-family":{"identifier":"allow-family","description":"Enables the family command without any pre-configured scope.","commands":{"allow":["family"],"deny":[]}},"allow-hostname":{"identifier":"allow-hostname","description":"Enables the hostname command without any pre-configured scope.","commands":{"allow":["hostname"],"deny":[]}},"allow-locale":{"identifier":"allow-locale","description":"Enables the locale command without any pre-configured scope.","commands":{"allow":["locale"],"deny":[]}},"allow-os-type":{"identifier":"allow-os-type","description":"Enables the os_type command without any pre-configured scope.","commands":{"allow":["os_type"],"deny":[]}},"allow-platform":{"identifier":"allow-platform","description":"Enables the platform command without any pre-configured scope.","commands":{"allow":["platform"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-arch":{"identifier":"deny-arch","description":"Denies the arch command without any pre-configured scope.","commands":{"allow":[],"deny":["arch"]}},"deny-exe-extension":{"identifier":"deny-exe-extension","description":"Denies the exe_extension command without any pre-configured scope.","commands":{"allow":[],"deny":["exe_extension"]}},"deny-family":{"identifier":"deny-family","description":"Denies the family command without any pre-configured scope.","commands":{"allow":[],"deny":["family"]}},"deny-hostname":{"identifier":"deny-hostname","description":"Denies the hostname command without any pre-configured scope.","commands":{"allow":[],"deny":["hostname"]}},"deny-locale":{"identifier":"deny-locale","description":"Denies the locale command without any pre-configured scope.","commands":{"allow":[],"deny":["locale"]}},"deny-os-type":{"identifier":"deny-os-type","description":"Denies the os_type command without any pre-configured scope.","commands":{"allow":[],"deny":["os_type"]}},"deny-platform":{"identifier":"deny-platform","description":"Denies the platform command without any pre-configured scope.","commands":{"allow":[],"deny":["platform"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"window-state":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-filename","allow-restore-state","allow-save-window-state"]},"permissions":{"allow-filename":{"identifier":"allow-filename","description":"Enables the filename command without any pre-configured scope.","commands":{"allow":["filename"],"deny":[]}},"allow-restore-state":{"identifier":"allow-restore-state","description":"Enables the restore_state command without any pre-configured scope.","commands":{"allow":["restore_state"],"deny":[]}},"allow-save-window-state":{"identifier":"allow-save-window-state","description":"Enables the save_window_state command without any pre-configured scope.","commands":{"allow":["save_window_state"],"deny":[]}},"deny-filename":{"identifier":"deny-filename","description":"Denies the filename command without any pre-configured scope.","commands":{"allow":[],"deny":["filename"]}},"deny-restore-state":{"identifier":"deny-restore-state","description":"Denies the restore_state command without any pre-configured scope.","commands":{"allow":[],"deny":["restore_state"]}},"deny-save-window-state":{"identifier":"deny-save-window-state","description":"Denies the save_window_state command without any pre-configured scope.","commands":{"allow":[],"deny":["save_window_state"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file diff --git a/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json b/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json index 797ccb5c..905008b7 100644 --- a/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json +++ b/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" @@ -133,2803 +133,2202 @@ { "description": "Reference a permission or permission set by identifier and extends its scope.", "type": "object", - "oneOf": [ + "allOf": [ { - "type": "object", - "required": [ - "identifier" - ], + "if": { + "properties": { + "identifier": { + "anyOf": [ + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "const": "shell:default" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute" + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + } + ] + } + } + }, + "then": { + "properties": { + "allow": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + }, + "deny": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + } + } + }, "properties": { "identifier": { - "oneOf": [ + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", - "type": "string", - "enum": [ - "shell:default" - ] - }, + "$ref": "#/definitions/Identifier" + } + ] + } + } + }, + { + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-execute" - ] - }, - { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-kill" - ] - }, - { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-open" - ] - }, - { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-spawn" - ] - }, - { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] - }, - { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-execute" - ] - }, - { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-kill" - ] - }, - { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-open" - ] - }, - { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-spawn" - ] - }, - { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "$ref": "#/definitions/Identifier" } ] }, "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } }, "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } } } } + ], + "required": [ + "identifier" ] } ] }, "Identifier": { + "description": "Permission identifier", "oneOf": [ { - "description": "clipboard-manager:default -> No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", + "description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", "type": "string", - "enum": [ - "clipboard-manager:default" - ] + "const": "clipboard-manager:default" }, { - "description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.", + "description": "Enables the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-clear" - ] + "const": "clipboard-manager:allow-clear" }, { - "description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.", + "description": "Enables the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-image" - ] + "const": "clipboard-manager:allow-read-image" }, { - "description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.", + "description": "Enables the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-text" - ] + "const": "clipboard-manager:allow-read-text" }, { - "description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.", + "description": "Enables the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-html" - ] + "const": "clipboard-manager:allow-write-html" }, { - "description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.", + "description": "Enables the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-image" - ] + "const": "clipboard-manager:allow-write-image" }, { - "description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.", + "description": "Enables the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-text" - ] + "const": "clipboard-manager:allow-write-text" }, { - "description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.", + "description": "Denies the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-clear" - ] + "const": "clipboard-manager:deny-clear" }, { - "description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.", + "description": "Denies the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-image" - ] + "const": "clipboard-manager:deny-read-image" }, { - "description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.", + "description": "Denies the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-text" - ] + "const": "clipboard-manager:deny-read-text" }, { - "description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.", + "description": "Denies the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-html" - ] + "const": "clipboard-manager:deny-write-html" }, { - "description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.", + "description": "Denies the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-image" - ] + "const": "clipboard-manager:deny-write-image" }, { - "description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.", + "description": "Denies the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-text" - ] + "const": "clipboard-manager:deny-write-text" }, { - "description": "core:app:default -> Default permissions for the plugin.", + "description": "Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n", "type": "string", - "enum": [ - "core:app:default" - ] + "const": "core:default" }, { - "description": "core:app:allow-app-hide -> Enables the app_hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:app:allow-app-hide" - ] + "const": "core:app:default" }, { - "description": "core:app:allow-app-show -> Enables the app_show command without any pre-configured scope.", + "description": "Enables the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-app-show" - ] + "const": "core:app:allow-app-hide" }, { - "description": "core:app:allow-default-window-icon -> Enables the default_window_icon command without any pre-configured scope.", + "description": "Enables the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-default-window-icon" - ] + "const": "core:app:allow-app-show" }, { - "description": "core:app:allow-name -> Enables the name command without any pre-configured scope.", + "description": "Enables the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-name" - ] + "const": "core:app:allow-default-window-icon" }, { - "description": "core:app:allow-tauri-version -> Enables the tauri_version command without any pre-configured scope.", + "description": "Enables the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-tauri-version" - ] + "const": "core:app:allow-name" }, { - "description": "core:app:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Enables the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-version" - ] + "const": "core:app:allow-set-app-theme" }, { - "description": "core:app:deny-app-hide -> Denies the app_hide command without any pre-configured scope.", + "description": "Enables the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-hide" - ] + "const": "core:app:allow-tauri-version" }, { - "description": "core:app:deny-app-show -> Denies the app_show command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-show" - ] + "const": "core:app:allow-version" }, { - "description": "core:app:deny-default-window-icon -> Denies the default_window_icon command without any pre-configured scope.", + "description": "Denies the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-default-window-icon" - ] + "const": "core:app:deny-app-hide" }, { - "description": "core:app:deny-name -> Denies the name command without any pre-configured scope.", + "description": "Denies the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-name" - ] + "const": "core:app:deny-app-show" }, { - "description": "core:app:deny-tauri-version -> Denies the tauri_version command without any pre-configured scope.", + "description": "Denies the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-tauri-version" - ] + "const": "core:app:deny-default-window-icon" }, { - "description": "core:app:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Denies the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-version" - ] + "const": "core:app:deny-name" }, { - "description": "core:event:default -> Default permissions for the plugin.", + "description": "Denies the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:default" - ] + "const": "core:app:deny-set-app-theme" }, { - "description": "core:event:allow-emit -> Enables the emit command without any pre-configured scope.", + "description": "Denies the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit" - ] + "const": "core:app:deny-tauri-version" }, { - "description": "core:event:allow-emit-to -> Enables the emit_to command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit-to" - ] + "const": "core:app:deny-version" }, { - "description": "core:event:allow-listen -> Enables the listen command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:event:allow-listen" - ] + "const": "core:event:default" }, { - "description": "core:event:allow-unlisten -> Enables the unlisten command without any pre-configured scope.", + "description": "Enables the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-unlisten" - ] + "const": "core:event:allow-emit" }, { - "description": "core:event:deny-emit -> Denies the emit command without any pre-configured scope.", + "description": "Enables the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit" - ] + "const": "core:event:allow-emit-to" }, { - "description": "core:event:deny-emit-to -> Denies the emit_to command without any pre-configured scope.", + "description": "Enables the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit-to" - ] + "const": "core:event:allow-listen" }, { - "description": "core:event:deny-listen -> Denies the listen command without any pre-configured scope.", + "description": "Enables the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-listen" - ] + "const": "core:event:allow-unlisten" }, { - "description": "core:event:deny-unlisten -> Denies the unlisten command without any pre-configured scope.", + "description": "Denies the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-unlisten" - ] + "const": "core:event:deny-emit" }, { - "description": "core:image:default -> Default permissions for the plugin.", + "description": "Denies the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:default" - ] + "const": "core:event:deny-emit-to" }, { - "description": "core:image:allow-from-bytes -> Enables the from_bytes command without any pre-configured scope.", + "description": "Denies the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-bytes" - ] + "const": "core:event:deny-listen" }, { - "description": "core:image:allow-from-path -> Enables the from_path command without any pre-configured scope.", + "description": "Denies the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-path" - ] + "const": "core:event:deny-unlisten" }, { - "description": "core:image:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:image:allow-new" - ] + "const": "core:image:default" }, { - "description": "core:image:allow-rgba -> Enables the rgba command without any pre-configured scope.", + "description": "Enables the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-rgba" - ] + "const": "core:image:allow-from-bytes" }, { - "description": "core:image:allow-size -> Enables the size command without any pre-configured scope.", + "description": "Enables the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-size" - ] + "const": "core:image:allow-from-path" }, { - "description": "core:image:deny-from-bytes -> Denies the from_bytes command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-bytes" - ] + "const": "core:image:allow-new" }, { - "description": "core:image:deny-from-path -> Denies the from_path command without any pre-configured scope.", + "description": "Enables the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-path" - ] + "const": "core:image:allow-rgba" }, { - "description": "core:image:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-new" - ] + "const": "core:image:allow-size" }, { - "description": "core:image:deny-rgba -> Denies the rgba command without any pre-configured scope.", + "description": "Denies the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-rgba" - ] + "const": "core:image:deny-from-bytes" }, { - "description": "core:image:deny-size -> Denies the size command without any pre-configured scope.", + "description": "Denies the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-size" - ] + "const": "core:image:deny-from-path" }, { - "description": "core:menu:default -> Default permissions for the plugin.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:default" - ] + "const": "core:image:deny-new" }, { - "description": "core:menu:allow-append -> Enables the append command without any pre-configured scope.", + "description": "Denies the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-append" - ] + "const": "core:image:deny-rgba" }, { - "description": "core:menu:allow-create-default -> Enables the create_default command without any pre-configured scope.", + "description": "Denies the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-create-default" - ] + "const": "core:image:deny-size" }, { - "description": "core:menu:allow-get -> Enables the get command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:menu:allow-get" - ] + "const": "core:menu:default" }, { - "description": "core:menu:allow-insert -> Enables the insert command without any pre-configured scope.", + "description": "Enables the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-insert" - ] + "const": "core:menu:allow-append" }, { - "description": "core:menu:allow-is-checked -> Enables the is_checked command without any pre-configured scope.", + "description": "Enables the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-checked" - ] + "const": "core:menu:allow-create-default" }, { - "description": "core:menu:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "description": "Enables the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-enabled" - ] + "const": "core:menu:allow-get" }, { - "description": "core:menu:allow-items -> Enables the items command without any pre-configured scope.", + "description": "Enables the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-items" - ] + "const": "core:menu:allow-insert" }, { - "description": "core:menu:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Enables the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-new" - ] + "const": "core:menu:allow-is-checked" }, { - "description": "core:menu:allow-popup -> Enables the popup command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-popup" - ] + "const": "core:menu:allow-is-enabled" }, { - "description": "core:menu:allow-prepend -> Enables the prepend command without any pre-configured scope.", + "description": "Enables the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-prepend" - ] + "const": "core:menu:allow-items" }, { - "description": "core:menu:allow-remove -> Enables the remove command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove" - ] + "const": "core:menu:allow-new" }, { - "description": "core:menu:allow-remove-at -> Enables the remove_at command without any pre-configured scope.", + "description": "Enables the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove-at" - ] + "const": "core:menu:allow-popup" }, { - "description": "core:menu:allow-set-accelerator -> Enables the set_accelerator command without any pre-configured scope.", + "description": "Enables the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-accelerator" - ] + "const": "core:menu:allow-prepend" }, { - "description": "core:menu:allow-set-as-app-menu -> Enables the set_as_app_menu command without any pre-configured scope.", + "description": "Enables the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-app-menu" - ] + "const": "core:menu:allow-remove" }, { - "description": "core:menu:allow-set-as-help-menu-for-nsapp -> Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:allow-remove-at" }, { - "description": "core:menu:allow-set-as-window-menu -> Enables the set_as_window_menu command without any pre-configured scope.", + "description": "Enables the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-window-menu" - ] + "const": "core:menu:allow-set-accelerator" }, { - "description": "core:menu:allow-set-as-windows-menu-for-nsapp -> Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:allow-set-as-app-menu" }, { - "description": "core:menu:allow-set-checked -> Enables the set_checked command without any pre-configured scope.", + "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-checked" - ] + "const": "core:menu:allow-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:allow-set-enabled -> Enables the set_enabled command without any pre-configured scope.", + "description": "Enables the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-enabled" - ] + "const": "core:menu:allow-set-as-window-menu" }, { - "description": "core:menu:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-icon" - ] + "const": "core:menu:allow-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:allow-set-text -> Enables the set_text command without any pre-configured scope.", + "description": "Enables the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-text" - ] + "const": "core:menu:allow-set-checked" }, { - "description": "core:menu:allow-text -> Enables the text command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-text" - ] + "const": "core:menu:allow-set-enabled" }, { - "description": "core:menu:deny-append -> Denies the append command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-append" - ] + "const": "core:menu:allow-set-icon" }, { - "description": "core:menu:deny-create-default -> Denies the create_default command without any pre-configured scope.", + "description": "Enables the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-create-default" - ] + "const": "core:menu:allow-set-text" }, { - "description": "core:menu:deny-get -> Denies the get command without any pre-configured scope.", + "description": "Enables the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-get" - ] + "const": "core:menu:allow-text" }, { - "description": "core:menu:deny-insert -> Denies the insert command without any pre-configured scope.", + "description": "Denies the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-insert" - ] + "const": "core:menu:deny-append" }, { - "description": "core:menu:deny-is-checked -> Denies the is_checked command without any pre-configured scope.", + "description": "Denies the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-checked" - ] + "const": "core:menu:deny-create-default" }, { - "description": "core:menu:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "description": "Denies the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-enabled" - ] + "const": "core:menu:deny-get" }, { - "description": "core:menu:deny-items -> Denies the items command without any pre-configured scope.", + "description": "Denies the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-items" - ] + "const": "core:menu:deny-insert" }, { - "description": "core:menu:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Denies the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-new" - ] + "const": "core:menu:deny-is-checked" }, { - "description": "core:menu:deny-popup -> Denies the popup command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-popup" - ] + "const": "core:menu:deny-is-enabled" }, { - "description": "core:menu:deny-prepend -> Denies the prepend command without any pre-configured scope.", + "description": "Denies the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-prepend" - ] + "const": "core:menu:deny-items" }, { - "description": "core:menu:deny-remove -> Denies the remove command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove" - ] + "const": "core:menu:deny-new" }, { - "description": "core:menu:deny-remove-at -> Denies the remove_at command without any pre-configured scope.", + "description": "Denies the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove-at" - ] + "const": "core:menu:deny-popup" }, { - "description": "core:menu:deny-set-accelerator -> Denies the set_accelerator command without any pre-configured scope.", + "description": "Denies the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-accelerator" - ] + "const": "core:menu:deny-prepend" }, { - "description": "core:menu:deny-set-as-app-menu -> Denies the set_as_app_menu command without any pre-configured scope.", + "description": "Denies the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-app-menu" - ] + "const": "core:menu:deny-remove" }, { - "description": "core:menu:deny-set-as-help-menu-for-nsapp -> Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:deny-remove-at" }, { - "description": "core:menu:deny-set-as-window-menu -> Denies the set_as_window_menu command without any pre-configured scope.", + "description": "Denies the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-window-menu" - ] + "const": "core:menu:deny-set-accelerator" }, { - "description": "core:menu:deny-set-as-windows-menu-for-nsapp -> Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:deny-set-as-app-menu" }, { - "description": "core:menu:deny-set-checked -> Denies the set_checked command without any pre-configured scope.", + "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-checked" - ] + "const": "core:menu:deny-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:deny-set-enabled -> Denies the set_enabled command without any pre-configured scope.", + "description": "Denies the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-enabled" - ] + "const": "core:menu:deny-set-as-window-menu" }, { - "description": "core:menu:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-icon" - ] + "const": "core:menu:deny-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:deny-set-text -> Denies the set_text command without any pre-configured scope.", + "description": "Denies the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-text" - ] + "const": "core:menu:deny-set-checked" }, { - "description": "core:menu:deny-text -> Denies the text command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-text" - ] + "const": "core:menu:deny-set-enabled" }, { - "description": "core:path:default -> Default permissions for the plugin.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:default" - ] + "const": "core:menu:deny-set-icon" }, { - "description": "core:path:allow-basename -> Enables the basename command without any pre-configured scope.", + "description": "Denies the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-basename" - ] + "const": "core:menu:deny-set-text" }, { - "description": "core:path:allow-dirname -> Enables the dirname command without any pre-configured scope.", + "description": "Denies the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-dirname" - ] + "const": "core:menu:deny-text" }, { - "description": "core:path:allow-extname -> Enables the extname command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:path:allow-extname" - ] + "const": "core:path:default" }, { - "description": "core:path:allow-is-absolute -> Enables the is_absolute command without any pre-configured scope.", + "description": "Enables the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-is-absolute" - ] + "const": "core:path:allow-basename" }, { - "description": "core:path:allow-join -> Enables the join command without any pre-configured scope.", + "description": "Enables the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-join" - ] + "const": "core:path:allow-dirname" }, { - "description": "core:path:allow-normalize -> Enables the normalize command without any pre-configured scope.", + "description": "Enables the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-normalize" - ] + "const": "core:path:allow-extname" }, { - "description": "core:path:allow-resolve -> Enables the resolve command without any pre-configured scope.", + "description": "Enables the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve" - ] + "const": "core:path:allow-is-absolute" }, { - "description": "core:path:allow-resolve-directory -> Enables the resolve_directory command without any pre-configured scope.", + "description": "Enables the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve-directory" - ] + "const": "core:path:allow-join" }, { - "description": "core:path:deny-basename -> Denies the basename command without any pre-configured scope.", + "description": "Enables the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-basename" - ] + "const": "core:path:allow-normalize" }, { - "description": "core:path:deny-dirname -> Denies the dirname command without any pre-configured scope.", + "description": "Enables the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-dirname" - ] + "const": "core:path:allow-resolve" }, { - "description": "core:path:deny-extname -> Denies the extname command without any pre-configured scope.", + "description": "Enables the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-extname" - ] + "const": "core:path:allow-resolve-directory" }, { - "description": "core:path:deny-is-absolute -> Denies the is_absolute command without any pre-configured scope.", + "description": "Denies the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-is-absolute" - ] + "const": "core:path:deny-basename" }, { - "description": "core:path:deny-join -> Denies the join command without any pre-configured scope.", + "description": "Denies the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-join" - ] + "const": "core:path:deny-dirname" }, { - "description": "core:path:deny-normalize -> Denies the normalize command without any pre-configured scope.", + "description": "Denies the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-normalize" - ] + "const": "core:path:deny-extname" }, { - "description": "core:path:deny-resolve -> Denies the resolve command without any pre-configured scope.", + "description": "Denies the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve" - ] + "const": "core:path:deny-is-absolute" }, { - "description": "core:path:deny-resolve-directory -> Denies the resolve_directory command without any pre-configured scope.", + "description": "Denies the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve-directory" - ] + "const": "core:path:deny-join" }, { - "description": "core:resources:default -> Default permissions for the plugin.", + "description": "Denies the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:default" - ] + "const": "core:path:deny-normalize" }, { - "description": "core:resources:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:allow-close" - ] + "const": "core:path:deny-resolve" }, { - "description": "core:resources:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Denies the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:deny-close" - ] + "const": "core:path:deny-resolve-directory" }, { - "description": "core:tray:default -> Default permissions for the plugin.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:default" - ] + "const": "core:resources:default" }, { - "description": "core:tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-get-by-id" - ] + "const": "core:resources:allow-close" }, { - "description": "core:tray:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-new" - ] + "const": "core:resources:deny-close" }, { - "description": "core:tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:allow-remove-by-id" - ] + "const": "core:tray:default" }, { - "description": "core:tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon" - ] + "const": "core:tray:allow-get-by-id" }, { - "description": "core:tray:allow-set-icon-as-template -> Enables the set_icon_as_template command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon-as-template" - ] + "const": "core:tray:allow-new" }, { - "description": "core:tray:allow-set-menu -> Enables the set_menu command without any pre-configured scope.", + "description": "Enables the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-menu" - ] + "const": "core:tray:allow-remove-by-id" }, { - "description": "core:tray:allow-set-show-menu-on-left-click -> Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-show-menu-on-left-click" - ] + "const": "core:tray:allow-set-icon" }, { - "description": "core:tray:allow-set-temp-dir-path -> Enables the set_temp_dir_path command without any pre-configured scope.", + "description": "Enables the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-temp-dir-path" - ] + "const": "core:tray:allow-set-icon-as-template" }, { - "description": "core:tray:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-title" - ] + "const": "core:tray:allow-set-menu" }, { - "description": "core:tray:allow-set-tooltip -> Enables the set_tooltip command without any pre-configured scope.", + "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-tooltip" - ] + "const": "core:tray:allow-set-show-menu-on-left-click" }, { - "description": "core:tray:allow-set-visible -> Enables the set_visible command without any pre-configured scope.", + "description": "Enables the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-visible" - ] + "const": "core:tray:allow-set-temp-dir-path" }, { - "description": "core:tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-get-by-id" - ] + "const": "core:tray:allow-set-title" }, { - "description": "core:tray:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-new" - ] + "const": "core:tray:allow-set-tooltip" }, { - "description": "core:tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.", + "description": "Enables the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-remove-by-id" - ] + "const": "core:tray:allow-set-visible" }, { - "description": "core:tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon" - ] + "const": "core:tray:deny-get-by-id" }, { - "description": "core:tray:deny-set-icon-as-template -> Denies the set_icon_as_template command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon-as-template" - ] + "const": "core:tray:deny-new" }, { - "description": "core:tray:deny-set-menu -> Denies the set_menu command without any pre-configured scope.", + "description": "Denies the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-menu" - ] + "const": "core:tray:deny-remove-by-id" }, { - "description": "core:tray:deny-set-show-menu-on-left-click -> Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-show-menu-on-left-click" - ] + "const": "core:tray:deny-set-icon" }, { - "description": "core:tray:deny-set-temp-dir-path -> Denies the set_temp_dir_path command without any pre-configured scope.", + "description": "Denies the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-temp-dir-path" - ] + "const": "core:tray:deny-set-icon-as-template" }, { - "description": "core:tray:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-title" - ] + "const": "core:tray:deny-set-menu" }, { - "description": "core:tray:deny-set-tooltip -> Denies the set_tooltip command without any pre-configured scope.", + "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-tooltip" - ] + "const": "core:tray:deny-set-show-menu-on-left-click" }, { - "description": "core:tray:deny-set-visible -> Denies the set_visible command without any pre-configured scope.", + "description": "Denies the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-visible" - ] + "const": "core:tray:deny-set-temp-dir-path" }, { - "description": "core:webview:default -> Default permissions for the plugin.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:default" - ] + "const": "core:tray:deny-set-title" }, { - "description": "core:webview:allow-create-webview -> Enables the create_webview command without any pre-configured scope.", + "description": "Denies the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview" - ] + "const": "core:tray:deny-set-tooltip" }, { - "description": "core:webview:allow-create-webview-window -> Enables the create_webview_window command without any pre-configured scope.", + "description": "Denies the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview-window" - ] + "const": "core:tray:deny-set-visible" }, { - "description": "core:webview:allow-get-all-webviews -> Enables the get_all_webviews command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:webview:allow-get-all-webviews" - ] + "const": "core:webview:default" }, { - "description": "core:webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-internal-toggle-devtools" - ] + "const": "core:webview:allow-clear-all-browsing-data" }, { - "description": "core:webview:allow-print -> Enables the print command without any pre-configured scope.", + "description": "Enables the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-print" - ] + "const": "core:webview:allow-create-webview" }, { - "description": "core:webview:allow-reparent -> Enables the reparent command without any pre-configured scope.", + "description": "Enables the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-reparent" - ] + "const": "core:webview:allow-create-webview-window" }, { - "description": "core:webview:allow-set-webview-focus -> Enables the set_webview_focus command without any pre-configured scope.", + "description": "Enables the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-focus" - ] + "const": "core:webview:allow-get-all-webviews" }, { - "description": "core:webview:allow-set-webview-position -> Enables the set_webview_position command without any pre-configured scope.", + "description": "Enables the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-position" - ] + "const": "core:webview:allow-internal-toggle-devtools" }, { - "description": "core:webview:allow-set-webview-size -> Enables the set_webview_size command without any pre-configured scope.", + "description": "Enables the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-size" - ] + "const": "core:webview:allow-print" }, { - "description": "core:webview:allow-set-webview-zoom -> Enables the set_webview_zoom command without any pre-configured scope.", + "description": "Enables the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-zoom" - ] + "const": "core:webview:allow-reparent" }, { - "description": "core:webview:allow-webview-close -> Enables the webview_close command without any pre-configured scope.", + "description": "Enables the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-close" - ] + "const": "core:webview:allow-set-webview-focus" }, { - "description": "core:webview:allow-webview-position -> Enables the webview_position command without any pre-configured scope.", + "description": "Enables the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-position" - ] + "const": "core:webview:allow-set-webview-position" }, { - "description": "core:webview:allow-webview-size -> Enables the webview_size command without any pre-configured scope.", + "description": "Enables the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-size" - ] + "const": "core:webview:allow-set-webview-size" }, { - "description": "core:webview:deny-create-webview -> Denies the create_webview command without any pre-configured scope.", + "description": "Enables the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview" - ] + "const": "core:webview:allow-set-webview-zoom" }, { - "description": "core:webview:deny-create-webview-window -> Denies the create_webview_window command without any pre-configured scope.", + "description": "Enables the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview-window" - ] + "const": "core:webview:allow-webview-close" }, { - "description": "core:webview:deny-get-all-webviews -> Denies the get_all_webviews command without any pre-configured scope.", + "description": "Enables the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-get-all-webviews" - ] + "const": "core:webview:allow-webview-hide" }, { - "description": "core:webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-internal-toggle-devtools" - ] + "const": "core:webview:allow-webview-position" }, { - "description": "core:webview:deny-print -> Denies the print command without any pre-configured scope.", + "description": "Enables the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-print" - ] + "const": "core:webview:allow-webview-show" }, { - "description": "core:webview:deny-reparent -> Denies the reparent command without any pre-configured scope.", + "description": "Enables the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-reparent" - ] + "const": "core:webview:allow-webview-size" }, { - "description": "core:webview:deny-set-webview-focus -> Denies the set_webview_focus command without any pre-configured scope.", + "description": "Denies the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-focus" - ] + "const": "core:webview:deny-clear-all-browsing-data" }, { - "description": "core:webview:deny-set-webview-position -> Denies the set_webview_position command without any pre-configured scope.", + "description": "Denies the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-position" - ] + "const": "core:webview:deny-create-webview" }, { - "description": "core:webview:deny-set-webview-size -> Denies the set_webview_size command without any pre-configured scope.", + "description": "Denies the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-size" - ] + "const": "core:webview:deny-create-webview-window" }, { - "description": "core:webview:deny-set-webview-zoom -> Denies the set_webview_zoom command without any pre-configured scope.", + "description": "Denies the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-zoom" - ] + "const": "core:webview:deny-get-all-webviews" }, { - "description": "core:webview:deny-webview-close -> Denies the webview_close command without any pre-configured scope.", + "description": "Denies the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-close" - ] + "const": "core:webview:deny-internal-toggle-devtools" }, { - "description": "core:webview:deny-webview-position -> Denies the webview_position command without any pre-configured scope.", + "description": "Denies the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-position" - ] + "const": "core:webview:deny-print" }, { - "description": "core:webview:deny-webview-size -> Denies the webview_size command without any pre-configured scope.", + "description": "Denies the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-size" - ] + "const": "core:webview:deny-reparent" }, { - "description": "core:window:default -> Default permissions for the plugin.", + "description": "Denies the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:default" - ] + "const": "core:webview:deny-set-webview-focus" }, { - "description": "core:window:allow-available-monitors -> Enables the available_monitors command without any pre-configured scope.", + "description": "Denies the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-available-monitors" - ] + "const": "core:webview:deny-set-webview-position" }, { - "description": "core:window:allow-center -> Enables the center command without any pre-configured scope.", + "description": "Denies the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-center" - ] + "const": "core:webview:deny-set-webview-size" }, { - "description": "core:window:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-close" - ] + "const": "core:webview:deny-set-webview-zoom" }, { - "description": "core:window:allow-create -> Enables the create command without any pre-configured scope.", + "description": "Denies the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-create" - ] + "const": "core:webview:deny-webview-close" }, { - "description": "core:window:allow-current-monitor -> Enables the current_monitor command without any pre-configured scope.", + "description": "Denies the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-current-monitor" - ] + "const": "core:webview:deny-webview-hide" }, { - "description": "core:window:allow-cursor-position -> Enables the cursor_position command without any pre-configured scope.", + "description": "Denies the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-cursor-position" - ] + "const": "core:webview:deny-webview-position" }, { - "description": "core:window:allow-destroy -> Enables the destroy command without any pre-configured scope.", + "description": "Denies the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-destroy" - ] + "const": "core:webview:deny-webview-show" }, { - "description": "core:window:allow-get-all-windows -> Enables the get_all_windows command without any pre-configured scope.", + "description": "Denies the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-get-all-windows" - ] + "const": "core:webview:deny-webview-size" }, { - "description": "core:window:allow-hide -> Enables the hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:window:allow-hide" - ] + "const": "core:window:default" }, { - "description": "core:window:allow-inner-position -> Enables the inner_position command without any pre-configured scope.", + "description": "Enables the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-position" - ] + "const": "core:window:allow-available-monitors" }, { - "description": "core:window:allow-inner-size -> Enables the inner_size command without any pre-configured scope.", + "description": "Enables the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-size" - ] + "const": "core:window:allow-center" }, { - "description": "core:window:allow-internal-toggle-maximize -> Enables the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-internal-toggle-maximize" - ] + "const": "core:window:allow-close" }, { - "description": "core:window:allow-is-closable -> Enables the is_closable command without any pre-configured scope.", + "description": "Enables the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-closable" - ] + "const": "core:window:allow-create" }, { - "description": "core:window:allow-is-decorated -> Enables the is_decorated command without any pre-configured scope.", + "description": "Enables the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-decorated" - ] + "const": "core:window:allow-current-monitor" }, { - "description": "core:window:allow-is-focused -> Enables the is_focused command without any pre-configured scope.", + "description": "Enables the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-focused" - ] + "const": "core:window:allow-cursor-position" }, { - "description": "core:window:allow-is-fullscreen -> Enables the is_fullscreen command without any pre-configured scope.", + "description": "Enables the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-fullscreen" - ] + "const": "core:window:allow-destroy" }, { - "description": "core:window:allow-is-maximizable -> Enables the is_maximizable command without any pre-configured scope.", + "description": "Enables the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximizable" - ] + "const": "core:window:allow-get-all-windows" }, { - "description": "core:window:allow-is-maximized -> Enables the is_maximized command without any pre-configured scope.", + "description": "Enables the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximized" - ] + "const": "core:window:allow-hide" }, { - "description": "core:window:allow-is-minimizable -> Enables the is_minimizable command without any pre-configured scope.", + "description": "Enables the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimizable" - ] + "const": "core:window:allow-inner-position" }, { - "description": "core:window:allow-is-minimized -> Enables the is_minimized command without any pre-configured scope.", + "description": "Enables the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimized" - ] + "const": "core:window:allow-inner-size" }, { - "description": "core:window:allow-is-resizable -> Enables the is_resizable command without any pre-configured scope.", + "description": "Enables the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-resizable" - ] + "const": "core:window:allow-internal-toggle-maximize" }, { - "description": "core:window:allow-is-visible -> Enables the is_visible command without any pre-configured scope.", + "description": "Enables the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-visible" - ] + "const": "core:window:allow-is-closable" }, { - "description": "core:window:allow-maximize -> Enables the maximize command without any pre-configured scope.", + "description": "Enables the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-maximize" - ] + "const": "core:window:allow-is-decorated" }, { - "description": "core:window:allow-minimize -> Enables the minimize command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-minimize" - ] + "const": "core:window:allow-is-enabled" }, { - "description": "core:window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.", + "description": "Enables the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-monitor-from-point" - ] + "const": "core:window:allow-is-focused" }, { - "description": "core:window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.", + "description": "Enables the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-position" - ] + "const": "core:window:allow-is-fullscreen" }, { - "description": "core:window:allow-outer-size -> Enables the outer_size command without any pre-configured scope.", + "description": "Enables the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-size" - ] + "const": "core:window:allow-is-maximizable" }, { - "description": "core:window:allow-primary-monitor -> Enables the primary_monitor command without any pre-configured scope.", + "description": "Enables the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-primary-monitor" - ] + "const": "core:window:allow-is-maximized" }, { - "description": "core:window:allow-request-user-attention -> Enables the request_user_attention command without any pre-configured scope.", + "description": "Enables the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-request-user-attention" - ] + "const": "core:window:allow-is-minimizable" }, { - "description": "core:window:allow-scale-factor -> Enables the scale_factor command without any pre-configured scope.", + "description": "Enables the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-scale-factor" - ] + "const": "core:window:allow-is-minimized" }, { - "description": "core:window:allow-set-always-on-bottom -> Enables the set_always_on_bottom command without any pre-configured scope.", + "description": "Enables the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-bottom" - ] + "const": "core:window:allow-is-resizable" }, { - "description": "core:window:allow-set-always-on-top -> Enables the set_always_on_top command without any pre-configured scope.", + "description": "Enables the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-top" - ] + "const": "core:window:allow-is-visible" }, { - "description": "core:window:allow-set-closable -> Enables the set_closable command without any pre-configured scope.", + "description": "Enables the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-closable" - ] + "const": "core:window:allow-maximize" }, { - "description": "core:window:allow-set-content-protected -> Enables the set_content_protected command without any pre-configured scope.", + "description": "Enables the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-content-protected" - ] + "const": "core:window:allow-minimize" }, { - "description": "core:window:allow-set-cursor-grab -> Enables the set_cursor_grab command without any pre-configured scope.", + "description": "Enables the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-grab" - ] + "const": "core:window:allow-monitor-from-point" }, { - "description": "core:window:allow-set-cursor-icon -> Enables the set_cursor_icon command without any pre-configured scope.", + "description": "Enables the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-icon" - ] + "const": "core:window:allow-outer-position" }, { - "description": "core:window:allow-set-cursor-position -> Enables the set_cursor_position command without any pre-configured scope.", + "description": "Enables the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-position" - ] + "const": "core:window:allow-outer-size" }, { - "description": "core:window:allow-set-cursor-visible -> Enables the set_cursor_visible command without any pre-configured scope.", + "description": "Enables the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-visible" - ] + "const": "core:window:allow-primary-monitor" }, { - "description": "core:window:allow-set-decorations -> Enables the set_decorations command without any pre-configured scope.", + "description": "Enables the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-decorations" - ] + "const": "core:window:allow-request-user-attention" }, { - "description": "core:window:allow-set-effects -> Enables the set_effects command without any pre-configured scope.", + "description": "Enables the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-effects" - ] + "const": "core:window:allow-scale-factor" }, { - "description": "core:window:allow-set-focus -> Enables the set_focus command without any pre-configured scope.", + "description": "Enables the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-focus" - ] + "const": "core:window:allow-set-always-on-bottom" }, { - "description": "core:window:allow-set-fullscreen -> Enables the set_fullscreen command without any pre-configured scope.", + "description": "Enables the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-fullscreen" - ] + "const": "core:window:allow-set-always-on-top" }, { - "description": "core:window:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-icon" - ] + "const": "core:window:allow-set-closable" }, { - "description": "core:window:allow-set-ignore-cursor-events -> Enables the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Enables the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-ignore-cursor-events" - ] + "const": "core:window:allow-set-content-protected" }, { - "description": "core:window:allow-set-max-size -> Enables the set_max_size command without any pre-configured scope.", + "description": "Enables the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-max-size" - ] + "const": "core:window:allow-set-cursor-grab" }, { - "description": "core:window:allow-set-maximizable -> Enables the set_maximizable command without any pre-configured scope.", + "description": "Enables the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-maximizable" - ] + "const": "core:window:allow-set-cursor-icon" }, { - "description": "core:window:allow-set-min-size -> Enables the set_min_size command without any pre-configured scope.", + "description": "Enables the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-min-size" - ] + "const": "core:window:allow-set-cursor-position" }, { - "description": "core:window:allow-set-minimizable -> Enables the set_minimizable command without any pre-configured scope.", + "description": "Enables the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-minimizable" - ] + "const": "core:window:allow-set-cursor-visible" }, { - "description": "core:window:allow-set-position -> Enables the set_position command without any pre-configured scope.", + "description": "Enables the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-position" - ] + "const": "core:window:allow-set-decorations" }, { - "description": "core:window:allow-set-progress-bar -> Enables the set_progress_bar command without any pre-configured scope.", + "description": "Enables the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-progress-bar" - ] + "const": "core:window:allow-set-effects" }, { - "description": "core:window:allow-set-resizable -> Enables the set_resizable command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-resizable" - ] + "const": "core:window:allow-set-enabled" }, { - "description": "core:window:allow-set-shadow -> Enables the set_shadow command without any pre-configured scope.", + "description": "Enables the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-shadow" - ] + "const": "core:window:allow-set-focus" }, { - "description": "core:window:allow-set-size -> Enables the set_size command without any pre-configured scope.", + "description": "Enables the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size" - ] + "const": "core:window:allow-set-fullscreen" }, { - "description": "core:window:allow-set-size-constraints -> Enables the set_size_constraints command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size-constraints" - ] + "const": "core:window:allow-set-icon" }, { - "description": "core:window:allow-set-skip-taskbar -> Enables the set_skip_taskbar command without any pre-configured scope.", + "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-skip-taskbar" - ] + "const": "core:window:allow-set-ignore-cursor-events" }, { - "description": "core:window:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title" - ] + "const": "core:window:allow-set-max-size" }, { - "description": "core:window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.", + "description": "Enables the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title-bar-style" - ] + "const": "core:window:allow-set-maximizable" }, { - "description": "core:window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Enables the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-visible-on-all-workspaces" - ] + "const": "core:window:allow-set-min-size" }, { - "description": "core:window:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-show" - ] + "const": "core:window:allow-set-minimizable" }, { - "description": "core:window:allow-start-dragging -> Enables the start_dragging command without any pre-configured scope.", + "description": "Enables the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-dragging" - ] + "const": "core:window:allow-set-position" }, { - "description": "core:window:allow-start-resize-dragging -> Enables the start_resize_dragging command without any pre-configured scope.", + "description": "Enables the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-resize-dragging" - ] + "const": "core:window:allow-set-progress-bar" }, { - "description": "core:window:allow-theme -> Enables the theme command without any pre-configured scope.", + "description": "Enables the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-theme" - ] + "const": "core:window:allow-set-resizable" }, { - "description": "core:window:allow-title -> Enables the title command without any pre-configured scope.", + "description": "Enables the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-title" - ] + "const": "core:window:allow-set-shadow" }, { - "description": "core:window:allow-toggle-maximize -> Enables the toggle_maximize command without any pre-configured scope.", + "description": "Enables the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-toggle-maximize" - ] + "const": "core:window:allow-set-size" }, { - "description": "core:window:allow-unmaximize -> Enables the unmaximize command without any pre-configured scope.", + "description": "Enables the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unmaximize" - ] + "const": "core:window:allow-set-size-constraints" }, { - "description": "core:window:allow-unminimize -> Enables the unminimize command without any pre-configured scope.", + "description": "Enables the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unminimize" - ] + "const": "core:window:allow-set-skip-taskbar" }, { - "description": "core:window:deny-available-monitors -> Denies the available_monitors command without any pre-configured scope.", + "description": "Enables the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-available-monitors" - ] + "const": "core:window:allow-set-theme" }, { - "description": "core:window:deny-center -> Denies the center command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-center" - ] + "const": "core:window:allow-set-title" }, { - "description": "core:window:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Enables the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-close" - ] + "const": "core:window:allow-set-title-bar-style" }, { - "description": "core:window:deny-create -> Denies the create command without any pre-configured scope.", + "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-create" - ] + "const": "core:window:allow-set-visible-on-all-workspaces" }, { - "description": "core:window:deny-current-monitor -> Denies the current_monitor command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-current-monitor" - ] + "const": "core:window:allow-show" }, { - "description": "core:window:deny-cursor-position -> Denies the cursor_position command without any pre-configured scope.", + "description": "Enables the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-cursor-position" - ] + "const": "core:window:allow-start-dragging" }, { - "description": "core:window:deny-destroy -> Denies the destroy command without any pre-configured scope.", + "description": "Enables the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-destroy" - ] + "const": "core:window:allow-start-resize-dragging" }, { - "description": "core:window:deny-get-all-windows -> Denies the get_all_windows command without any pre-configured scope.", + "description": "Enables the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-get-all-windows" - ] + "const": "core:window:allow-theme" }, { - "description": "core:window:deny-hide -> Denies the hide command without any pre-configured scope.", + "description": "Enables the title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-hide" - ] + "const": "core:window:allow-title" }, { - "description": "core:window:deny-inner-position -> Denies the inner_position command without any pre-configured scope.", + "description": "Enables the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-position" - ] + "const": "core:window:allow-toggle-maximize" }, { - "description": "core:window:deny-inner-size -> Denies the inner_size command without any pre-configured scope.", + "description": "Enables the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-size" - ] + "const": "core:window:allow-unmaximize" }, { - "description": "core:window:deny-internal-toggle-maximize -> Denies the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-internal-toggle-maximize" - ] + "const": "core:window:allow-unminimize" }, { - "description": "core:window:deny-is-closable -> Denies the is_closable command without any pre-configured scope.", + "description": "Denies the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-closable" - ] + "const": "core:window:deny-available-monitors" }, { - "description": "core:window:deny-is-decorated -> Denies the is_decorated command without any pre-configured scope.", + "description": "Denies the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-decorated" - ] + "const": "core:window:deny-center" }, { - "description": "core:window:deny-is-focused -> Denies the is_focused command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-focused" - ] + "const": "core:window:deny-close" }, { - "description": "core:window:deny-is-fullscreen -> Denies the is_fullscreen command without any pre-configured scope.", + "description": "Denies the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-fullscreen" - ] + "const": "core:window:deny-create" }, { - "description": "core:window:deny-is-maximizable -> Denies the is_maximizable command without any pre-configured scope.", + "description": "Denies the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximizable" - ] + "const": "core:window:deny-current-monitor" }, { - "description": "core:window:deny-is-maximized -> Denies the is_maximized command without any pre-configured scope.", + "description": "Denies the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximized" - ] + "const": "core:window:deny-cursor-position" }, { - "description": "core:window:deny-is-minimizable -> Denies the is_minimizable command without any pre-configured scope.", + "description": "Denies the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimizable" - ] + "const": "core:window:deny-destroy" }, { - "description": "core:window:deny-is-minimized -> Denies the is_minimized command without any pre-configured scope.", + "description": "Denies the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimized" - ] + "const": "core:window:deny-get-all-windows" }, { - "description": "core:window:deny-is-resizable -> Denies the is_resizable command without any pre-configured scope.", + "description": "Denies the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-resizable" - ] + "const": "core:window:deny-hide" }, { - "description": "core:window:deny-is-visible -> Denies the is_visible command without any pre-configured scope.", + "description": "Denies the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-visible" - ] + "const": "core:window:deny-inner-position" }, { - "description": "core:window:deny-maximize -> Denies the maximize command without any pre-configured scope.", + "description": "Denies the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-maximize" - ] + "const": "core:window:deny-inner-size" }, { - "description": "core:window:deny-minimize -> Denies the minimize command without any pre-configured scope.", + "description": "Denies the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-minimize" - ] + "const": "core:window:deny-internal-toggle-maximize" }, { - "description": "core:window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.", + "description": "Denies the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-monitor-from-point" - ] + "const": "core:window:deny-is-closable" }, { - "description": "core:window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.", + "description": "Denies the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-position" - ] + "const": "core:window:deny-is-decorated" }, { - "description": "core:window:deny-outer-size -> Denies the outer_size command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-size" - ] + "const": "core:window:deny-is-enabled" }, { - "description": "core:window:deny-primary-monitor -> Denies the primary_monitor command without any pre-configured scope.", + "description": "Denies the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-primary-monitor" - ] + "const": "core:window:deny-is-focused" }, { - "description": "core:window:deny-request-user-attention -> Denies the request_user_attention command without any pre-configured scope.", + "description": "Denies the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-request-user-attention" - ] + "const": "core:window:deny-is-fullscreen" }, { - "description": "core:window:deny-scale-factor -> Denies the scale_factor command without any pre-configured scope.", + "description": "Denies the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-scale-factor" - ] + "const": "core:window:deny-is-maximizable" }, { - "description": "core:window:deny-set-always-on-bottom -> Denies the set_always_on_bottom command without any pre-configured scope.", + "description": "Denies the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-bottom" - ] + "const": "core:window:deny-is-maximized" }, { - "description": "core:window:deny-set-always-on-top -> Denies the set_always_on_top command without any pre-configured scope.", + "description": "Denies the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-top" - ] + "const": "core:window:deny-is-minimizable" }, { - "description": "core:window:deny-set-closable -> Denies the set_closable command without any pre-configured scope.", + "description": "Denies the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-closable" - ] + "const": "core:window:deny-is-minimized" }, { - "description": "core:window:deny-set-content-protected -> Denies the set_content_protected command without any pre-configured scope.", + "description": "Denies the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-content-protected" - ] + "const": "core:window:deny-is-resizable" }, { - "description": "core:window:deny-set-cursor-grab -> Denies the set_cursor_grab command without any pre-configured scope.", + "description": "Denies the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-grab" - ] + "const": "core:window:deny-is-visible" }, { - "description": "core:window:deny-set-cursor-icon -> Denies the set_cursor_icon command without any pre-configured scope.", + "description": "Denies the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-icon" - ] + "const": "core:window:deny-maximize" }, { - "description": "core:window:deny-set-cursor-position -> Denies the set_cursor_position command without any pre-configured scope.", + "description": "Denies the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-position" - ] + "const": "core:window:deny-minimize" }, { - "description": "core:window:deny-set-cursor-visible -> Denies the set_cursor_visible command without any pre-configured scope.", + "description": "Denies the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-visible" - ] + "const": "core:window:deny-monitor-from-point" }, { - "description": "core:window:deny-set-decorations -> Denies the set_decorations command without any pre-configured scope.", + "description": "Denies the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-decorations" - ] + "const": "core:window:deny-outer-position" }, { - "description": "core:window:deny-set-effects -> Denies the set_effects command without any pre-configured scope.", + "description": "Denies the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-effects" - ] + "const": "core:window:deny-outer-size" }, { - "description": "core:window:deny-set-focus -> Denies the set_focus command without any pre-configured scope.", + "description": "Denies the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-focus" - ] + "const": "core:window:deny-primary-monitor" }, { - "description": "core:window:deny-set-fullscreen -> Denies the set_fullscreen command without any pre-configured scope.", + "description": "Denies the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-fullscreen" - ] + "const": "core:window:deny-request-user-attention" }, { - "description": "core:window:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-icon" - ] + "const": "core:window:deny-scale-factor" }, { - "description": "core:window:deny-set-ignore-cursor-events -> Denies the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Denies the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-ignore-cursor-events" - ] + "const": "core:window:deny-set-always-on-bottom" }, { - "description": "core:window:deny-set-max-size -> Denies the set_max_size command without any pre-configured scope.", + "description": "Denies the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-max-size" - ] + "const": "core:window:deny-set-always-on-top" }, { - "description": "core:window:deny-set-maximizable -> Denies the set_maximizable command without any pre-configured scope.", + "description": "Denies the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-maximizable" - ] + "const": "core:window:deny-set-closable" }, { - "description": "core:window:deny-set-min-size -> Denies the set_min_size command without any pre-configured scope.", + "description": "Denies the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-min-size" - ] + "const": "core:window:deny-set-content-protected" }, { - "description": "core:window:deny-set-minimizable -> Denies the set_minimizable command without any pre-configured scope.", + "description": "Denies the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-minimizable" - ] + "const": "core:window:deny-set-cursor-grab" }, { - "description": "core:window:deny-set-position -> Denies the set_position command without any pre-configured scope.", + "description": "Denies the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-position" - ] + "const": "core:window:deny-set-cursor-icon" }, { - "description": "core:window:deny-set-progress-bar -> Denies the set_progress_bar command without any pre-configured scope.", + "description": "Denies the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-progress-bar" - ] + "const": "core:window:deny-set-cursor-position" }, { - "description": "core:window:deny-set-resizable -> Denies the set_resizable command without any pre-configured scope.", + "description": "Denies the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-resizable" - ] + "const": "core:window:deny-set-cursor-visible" }, { - "description": "core:window:deny-set-shadow -> Denies the set_shadow command without any pre-configured scope.", + "description": "Denies the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-shadow" - ] + "const": "core:window:deny-set-decorations" }, { - "description": "core:window:deny-set-size -> Denies the set_size command without any pre-configured scope.", + "description": "Denies the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size" - ] + "const": "core:window:deny-set-effects" }, { - "description": "core:window:deny-set-size-constraints -> Denies the set_size_constraints command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size-constraints" - ] + "const": "core:window:deny-set-enabled" }, { - "description": "core:window:deny-set-skip-taskbar -> Denies the set_skip_taskbar command without any pre-configured scope.", + "description": "Denies the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-skip-taskbar" - ] + "const": "core:window:deny-set-focus" }, { - "description": "core:window:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title" - ] + "const": "core:window:deny-set-fullscreen" }, { - "description": "core:window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title-bar-style" - ] + "const": "core:window:deny-set-icon" }, { - "description": "core:window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-visible-on-all-workspaces" - ] + "const": "core:window:deny-set-ignore-cursor-events" }, { - "description": "core:window:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-show" - ] + "const": "core:window:deny-set-max-size" }, { - "description": "core:window:deny-start-dragging -> Denies the start_dragging command without any pre-configured scope.", + "description": "Denies the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-dragging" - ] + "const": "core:window:deny-set-maximizable" }, { - "description": "core:window:deny-start-resize-dragging -> Denies the start_resize_dragging command without any pre-configured scope.", + "description": "Denies the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-resize-dragging" - ] + "const": "core:window:deny-set-min-size" }, { - "description": "core:window:deny-theme -> Denies the theme command without any pre-configured scope.", + "description": "Denies the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-theme" - ] + "const": "core:window:deny-set-minimizable" }, { - "description": "core:window:deny-title -> Denies the title command without any pre-configured scope.", + "description": "Denies the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-title" - ] + "const": "core:window:deny-set-position" }, { - "description": "core:window:deny-toggle-maximize -> Denies the toggle_maximize command without any pre-configured scope.", + "description": "Denies the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-toggle-maximize" - ] + "const": "core:window:deny-set-progress-bar" }, { - "description": "core:window:deny-unmaximize -> Denies the unmaximize command without any pre-configured scope.", + "description": "Denies the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unmaximize" - ] + "const": "core:window:deny-set-resizable" }, { - "description": "core:window:deny-unminimize -> Denies the unminimize command without any pre-configured scope.", + "description": "Denies the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unminimize" - ] + "const": "core:window:deny-set-shadow" }, { - "description": "dialog:default -> This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", + "description": "Denies the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:default" - ] + "const": "core:window:deny-set-size" }, { - "description": "dialog:allow-ask -> Enables the ask command without any pre-configured scope.", + "description": "Denies the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-ask" - ] + "const": "core:window:deny-set-size-constraints" }, { - "description": "dialog:allow-confirm -> Enables the confirm command without any pre-configured scope.", + "description": "Denies the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-confirm" - ] + "const": "core:window:deny-set-skip-taskbar" }, { - "description": "dialog:allow-message -> Enables the message command without any pre-configured scope.", + "description": "Denies the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-message" - ] + "const": "core:window:deny-set-theme" }, { - "description": "dialog:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-open" - ] + "const": "core:window:deny-set-title" }, { - "description": "dialog:allow-save -> Enables the save command without any pre-configured scope.", + "description": "Denies the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-save" - ] + "const": "core:window:deny-set-title-bar-style" }, { - "description": "dialog:deny-ask -> Denies the ask command without any pre-configured scope.", + "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-ask" - ] + "const": "core:window:deny-set-visible-on-all-workspaces" }, { - "description": "dialog:deny-confirm -> Denies the confirm command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-confirm" - ] + "const": "core:window:deny-show" }, { - "description": "dialog:deny-message -> Denies the message command without any pre-configured scope.", + "description": "Denies the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-message" - ] + "const": "core:window:deny-start-dragging" }, { - "description": "dialog:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-open" - ] + "const": "core:window:deny-start-resize-dragging" }, { - "description": "dialog:deny-save -> Denies the save command without any pre-configured scope.", + "description": "Denies the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-save" - ] + "const": "core:window:deny-theme" }, { - "description": "log:default -> Allows the log command", + "description": "Denies the title command without any pre-configured scope.", "type": "string", - "enum": [ - "log:default" - ] + "const": "core:window:deny-title" }, { - "description": "log:allow-log -> Enables the log command without any pre-configured scope.", + "description": "Denies the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:allow-log" - ] + "const": "core:window:deny-toggle-maximize" }, { - "description": "log:deny-log -> Denies the log command without any pre-configured scope.", + "description": "Denies the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:deny-log" - ] + "const": "core:window:deny-unmaximize" }, { - "description": "notification:default -> This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", + "description": "Denies the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:default" - ] + "const": "core:window:deny-unminimize" }, { - "description": "notification:allow-batch -> Enables the batch command without any pre-configured scope.", + "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", "type": "string", - "enum": [ - "notification:allow-batch" - ] + "const": "dialog:default" }, { - "description": "notification:allow-cancel -> Enables the cancel command without any pre-configured scope.", + "description": "Enables the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-cancel" - ] + "const": "dialog:allow-ask" }, { - "description": "notification:allow-check-permissions -> Enables the check_permissions command without any pre-configured scope.", + "description": "Enables the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-check-permissions" - ] + "const": "dialog:allow-confirm" }, { - "description": "notification:allow-create-channel -> Enables the create_channel command without any pre-configured scope.", + "description": "Enables the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-create-channel" - ] + "const": "dialog:allow-message" }, { - "description": "notification:allow-delete-channel -> Enables the delete_channel command without any pre-configured scope.", + "description": "Enables the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-delete-channel" - ] + "const": "dialog:allow-open" }, { - "description": "notification:allow-get-active -> Enables the get_active command without any pre-configured scope.", + "description": "Enables the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-active" - ] + "const": "dialog:allow-save" }, { - "description": "notification:allow-get-pending -> Enables the get_pending command without any pre-configured scope.", + "description": "Denies the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-pending" - ] + "const": "dialog:deny-ask" }, { - "description": "notification:allow-is-permission-granted -> Enables the is_permission_granted command without any pre-configured scope.", + "description": "Denies the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-is-permission-granted" - ] + "const": "dialog:deny-confirm" }, { - "description": "notification:allow-list-channels -> Enables the list_channels command without any pre-configured scope.", + "description": "Denies the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-list-channels" - ] + "const": "dialog:deny-message" }, { - "description": "notification:allow-notify -> Enables the notify command without any pre-configured scope.", + "description": "Denies the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-notify" - ] + "const": "dialog:deny-open" }, { - "description": "notification:allow-permission-state -> Enables the permission_state command without any pre-configured scope.", + "description": "Denies the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-permission-state" - ] + "const": "dialog:deny-save" }, { - "description": "notification:allow-register-action-types -> Enables the register_action_types command without any pre-configured scope.", + "description": "Allows the log command", "type": "string", - "enum": [ - "notification:allow-register-action-types" - ] + "const": "log:default" }, { - "description": "notification:allow-register-listener -> Enables the register_listener command without any pre-configured scope.", + "description": "Enables the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-register-listener" - ] + "const": "log:allow-log" }, { - "description": "notification:allow-remove-active -> Enables the remove_active command without any pre-configured scope.", + "description": "Denies the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-remove-active" - ] + "const": "log:deny-log" }, { - "description": "notification:allow-request-permission -> Enables the request_permission command without any pre-configured scope.", + "description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", "type": "string", - "enum": [ - "notification:allow-request-permission" - ] + "const": "notification:default" }, { - "description": "notification:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-show" - ] + "const": "notification:allow-batch" }, { - "description": "notification:deny-batch -> Denies the batch command without any pre-configured scope.", + "description": "Enables the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-batch" - ] + "const": "notification:allow-cancel" }, { - "description": "notification:deny-cancel -> Denies the cancel command without any pre-configured scope.", + "description": "Enables the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-cancel" - ] + "const": "notification:allow-check-permissions" }, { - "description": "notification:deny-check-permissions -> Denies the check_permissions command without any pre-configured scope.", + "description": "Enables the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-check-permissions" - ] + "const": "notification:allow-create-channel" }, { - "description": "notification:deny-create-channel -> Denies the create_channel command without any pre-configured scope.", + "description": "Enables the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-create-channel" - ] + "const": "notification:allow-delete-channel" }, { - "description": "notification:deny-delete-channel -> Denies the delete_channel command without any pre-configured scope.", + "description": "Enables the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-delete-channel" - ] + "const": "notification:allow-get-active" }, { - "description": "notification:deny-get-active -> Denies the get_active command without any pre-configured scope.", + "description": "Enables the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-active" - ] + "const": "notification:allow-get-pending" }, { - "description": "notification:deny-get-pending -> Denies the get_pending command without any pre-configured scope.", + "description": "Enables the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-pending" - ] + "const": "notification:allow-is-permission-granted" }, { - "description": "notification:deny-is-permission-granted -> Denies the is_permission_granted command without any pre-configured scope.", + "description": "Enables the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-is-permission-granted" - ] + "const": "notification:allow-list-channels" }, { - "description": "notification:deny-list-channels -> Denies the list_channels command without any pre-configured scope.", + "description": "Enables the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-list-channels" - ] + "const": "notification:allow-notify" }, { - "description": "notification:deny-notify -> Denies the notify command without any pre-configured scope.", + "description": "Enables the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-notify" - ] + "const": "notification:allow-permission-state" }, { - "description": "notification:deny-permission-state -> Denies the permission_state command without any pre-configured scope.", + "description": "Enables the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-permission-state" - ] + "const": "notification:allow-register-action-types" }, { - "description": "notification:deny-register-action-types -> Denies the register_action_types command without any pre-configured scope.", + "description": "Enables the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-action-types" - ] + "const": "notification:allow-register-listener" }, { - "description": "notification:deny-register-listener -> Denies the register_listener command without any pre-configured scope.", + "description": "Enables the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-listener" - ] + "const": "notification:allow-remove-active" }, { - "description": "notification:deny-remove-active -> Denies the remove_active command without any pre-configured scope.", + "description": "Enables the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-remove-active" - ] + "const": "notification:allow-request-permission" }, { - "description": "notification:deny-request-permission -> Denies the request_permission command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-request-permission" - ] + "const": "notification:allow-show" }, { - "description": "notification:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-show" - ] + "const": "notification:deny-batch" }, { - "description": "os:default -> This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", + "description": "Denies the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:default" - ] + "const": "notification:deny-cancel" }, { - "description": "os:allow-arch -> Enables the arch command without any pre-configured scope.", + "description": "Denies the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-arch" - ] + "const": "notification:deny-check-permissions" }, { - "description": "os:allow-exe-extension -> Enables the exe_extension command without any pre-configured scope.", + "description": "Denies the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-exe-extension" - ] + "const": "notification:deny-create-channel" }, { - "description": "os:allow-family -> Enables the family command without any pre-configured scope.", + "description": "Denies the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-family" - ] + "const": "notification:deny-delete-channel" }, { - "description": "os:allow-hostname -> Enables the hostname command without any pre-configured scope.", + "description": "Denies the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-hostname" - ] + "const": "notification:deny-get-active" }, { - "description": "os:allow-locale -> Enables the locale command without any pre-configured scope.", + "description": "Denies the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-locale" - ] + "const": "notification:deny-get-pending" }, { - "description": "os:allow-os-type -> Enables the os_type command without any pre-configured scope.", + "description": "Denies the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-os-type" - ] + "const": "notification:deny-is-permission-granted" }, { - "description": "os:allow-platform -> Enables the platform command without any pre-configured scope.", + "description": "Denies the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-platform" - ] + "const": "notification:deny-list-channels" }, { - "description": "os:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Denies the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-version" - ] + "const": "notification:deny-notify" }, { - "description": "os:deny-arch -> Denies the arch command without any pre-configured scope.", + "description": "Denies the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-arch" - ] + "const": "notification:deny-permission-state" }, { - "description": "os:deny-exe-extension -> Denies the exe_extension command without any pre-configured scope.", + "description": "Denies the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-exe-extension" - ] + "const": "notification:deny-register-action-types" }, { - "description": "os:deny-family -> Denies the family command without any pre-configured scope.", + "description": "Denies the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-family" - ] + "const": "notification:deny-register-listener" }, { - "description": "os:deny-hostname -> Denies the hostname command without any pre-configured scope.", + "description": "Denies the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-hostname" - ] + "const": "notification:deny-remove-active" }, { - "description": "os:deny-locale -> Denies the locale command without any pre-configured scope.", + "description": "Denies the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-locale" - ] + "const": "notification:deny-request-permission" }, { - "description": "os:deny-os-type -> Denies the os_type command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-os-type" - ] + "const": "notification:deny-show" }, { - "description": "os:deny-platform -> Denies the platform command without any pre-configured scope.", + "description": "This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", "type": "string", - "enum": [ - "os:deny-platform" - ] + "const": "os:default" }, { - "description": "os:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Enables the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-version" - ] + "const": "os:allow-arch" }, { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "description": "Enables the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:default" - ] + "const": "os:allow-exe-extension" }, { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "description": "Enables the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-execute" - ] + "const": "os:allow-family" }, { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "description": "Enables the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-kill" - ] + "const": "os:allow-hostname" }, { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Enables the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-open" - ] + "const": "os:allow-locale" }, { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "description": "Enables the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-spawn" - ] + "const": "os:allow-os-type" }, { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "description": "Enables the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] + "const": "os:allow-platform" }, { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-execute" - ] + "const": "os:allow-version" }, { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "description": "Denies the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-kill" - ] + "const": "os:deny-arch" }, { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-open" - ] + "const": "os:deny-exe-extension" }, { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "description": "Denies the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-spawn" - ] + "const": "os:deny-family" }, { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "description": "Denies the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "const": "os:deny-hostname" }, { - "description": "window-state:default -> This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "description": "Denies the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:default" - ] + "const": "os:deny-locale" }, { - "description": "window-state:allow-filename -> Enables the filename command without any pre-configured scope.", + "description": "Denies the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-filename" - ] + "const": "os:deny-os-type" }, { - "description": "window-state:allow-restore-state -> Enables the restore_state command without any pre-configured scope.", + "description": "Denies the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-restore-state" - ] + "const": "os:deny-platform" }, { - "description": "window-state:allow-save-window-state -> Enables the save_window_state command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-save-window-state" - ] + "const": "os:deny-version" }, { - "description": "window-state:deny-filename -> Denies the filename command without any pre-configured scope.", + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", "type": "string", - "enum": [ - "window-state:deny-filename" - ] + "const": "shell:default" }, { - "description": "window-state:deny-restore-state -> Denies the restore_state command without any pre-configured scope.", + "description": "Enables the execute command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-restore-state" - ] + "const": "shell:allow-execute" }, { - "description": "window-state:deny-save-window-state -> Denies the save_window_state command without any pre-configured scope.", + "description": "Enables the kill command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-save-window-state" - ] + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + }, + { + "description": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "type": "string", + "const": "window-state:default" + }, + { + "description": "Enables the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-filename" + }, + { + "description": "Enables the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-restore-state" + }, + { + "description": "Enables the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-save-window-state" + }, + { + "description": "Denies the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-filename" + }, + { + "description": "Denies the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-restore-state" + }, + { + "description": "Denies the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-save-window-state" } ] }, @@ -3027,7 +2426,7 @@ } ] }, - "ShellAllowedArg": { + "ShellScopeEntryAllowedArg": { "description": "A command argument allowed to be executed by the webview API.", "anyOf": [ { @@ -3055,18 +2454,18 @@ } ] }, - "ShellAllowedArgs": { - "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "ShellScopeEntryAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", "anyOf": [ { "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", "type": "boolean" }, { - "description": "A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.", + "description": "A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.", "type": "array", "items": { - "$ref": "#/definitions/ShellAllowedArg" + "$ref": "#/definitions/ShellScopeEntryAllowedArg" } } ] diff --git a/desktop/tauri/src-tauri/gen/schemas/linux-schema.json b/desktop/tauri/src-tauri/gen/schemas/linux-schema.json index 797ccb5c..905008b7 100644 --- a/desktop/tauri/src-tauri/gen/schemas/linux-schema.json +++ b/desktop/tauri/src-tauri/gen/schemas/linux-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" @@ -133,2803 +133,2202 @@ { "description": "Reference a permission or permission set by identifier and extends its scope.", "type": "object", - "oneOf": [ + "allOf": [ { - "type": "object", - "required": [ - "identifier" - ], + "if": { + "properties": { + "identifier": { + "anyOf": [ + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "const": "shell:default" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute" + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + } + ] + } + } + }, + "then": { + "properties": { + "allow": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + }, + "deny": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + } + } + }, "properties": { "identifier": { - "oneOf": [ + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", - "type": "string", - "enum": [ - "shell:default" - ] - }, + "$ref": "#/definitions/Identifier" + } + ] + } + } + }, + { + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-execute" - ] - }, - { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-kill" - ] - }, - { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-open" - ] - }, - { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-spawn" - ] - }, - { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] - }, - { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-execute" - ] - }, - { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-kill" - ] - }, - { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-open" - ] - }, - { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-spawn" - ] - }, - { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "$ref": "#/definitions/Identifier" } ] }, "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } }, "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } } } } + ], + "required": [ + "identifier" ] } ] }, "Identifier": { + "description": "Permission identifier", "oneOf": [ { - "description": "clipboard-manager:default -> No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", + "description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", "type": "string", - "enum": [ - "clipboard-manager:default" - ] + "const": "clipboard-manager:default" }, { - "description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.", + "description": "Enables the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-clear" - ] + "const": "clipboard-manager:allow-clear" }, { - "description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.", + "description": "Enables the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-image" - ] + "const": "clipboard-manager:allow-read-image" }, { - "description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.", + "description": "Enables the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-text" - ] + "const": "clipboard-manager:allow-read-text" }, { - "description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.", + "description": "Enables the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-html" - ] + "const": "clipboard-manager:allow-write-html" }, { - "description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.", + "description": "Enables the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-image" - ] + "const": "clipboard-manager:allow-write-image" }, { - "description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.", + "description": "Enables the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-text" - ] + "const": "clipboard-manager:allow-write-text" }, { - "description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.", + "description": "Denies the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-clear" - ] + "const": "clipboard-manager:deny-clear" }, { - "description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.", + "description": "Denies the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-image" - ] + "const": "clipboard-manager:deny-read-image" }, { - "description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.", + "description": "Denies the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-text" - ] + "const": "clipboard-manager:deny-read-text" }, { - "description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.", + "description": "Denies the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-html" - ] + "const": "clipboard-manager:deny-write-html" }, { - "description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.", + "description": "Denies the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-image" - ] + "const": "clipboard-manager:deny-write-image" }, { - "description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.", + "description": "Denies the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-text" - ] + "const": "clipboard-manager:deny-write-text" }, { - "description": "core:app:default -> Default permissions for the plugin.", + "description": "Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n", "type": "string", - "enum": [ - "core:app:default" - ] + "const": "core:default" }, { - "description": "core:app:allow-app-hide -> Enables the app_hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:app:allow-app-hide" - ] + "const": "core:app:default" }, { - "description": "core:app:allow-app-show -> Enables the app_show command without any pre-configured scope.", + "description": "Enables the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-app-show" - ] + "const": "core:app:allow-app-hide" }, { - "description": "core:app:allow-default-window-icon -> Enables the default_window_icon command without any pre-configured scope.", + "description": "Enables the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-default-window-icon" - ] + "const": "core:app:allow-app-show" }, { - "description": "core:app:allow-name -> Enables the name command without any pre-configured scope.", + "description": "Enables the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-name" - ] + "const": "core:app:allow-default-window-icon" }, { - "description": "core:app:allow-tauri-version -> Enables the tauri_version command without any pre-configured scope.", + "description": "Enables the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-tauri-version" - ] + "const": "core:app:allow-name" }, { - "description": "core:app:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Enables the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-version" - ] + "const": "core:app:allow-set-app-theme" }, { - "description": "core:app:deny-app-hide -> Denies the app_hide command without any pre-configured scope.", + "description": "Enables the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-hide" - ] + "const": "core:app:allow-tauri-version" }, { - "description": "core:app:deny-app-show -> Denies the app_show command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-show" - ] + "const": "core:app:allow-version" }, { - "description": "core:app:deny-default-window-icon -> Denies the default_window_icon command without any pre-configured scope.", + "description": "Denies the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-default-window-icon" - ] + "const": "core:app:deny-app-hide" }, { - "description": "core:app:deny-name -> Denies the name command without any pre-configured scope.", + "description": "Denies the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-name" - ] + "const": "core:app:deny-app-show" }, { - "description": "core:app:deny-tauri-version -> Denies the tauri_version command without any pre-configured scope.", + "description": "Denies the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-tauri-version" - ] + "const": "core:app:deny-default-window-icon" }, { - "description": "core:app:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Denies the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-version" - ] + "const": "core:app:deny-name" }, { - "description": "core:event:default -> Default permissions for the plugin.", + "description": "Denies the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:default" - ] + "const": "core:app:deny-set-app-theme" }, { - "description": "core:event:allow-emit -> Enables the emit command without any pre-configured scope.", + "description": "Denies the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit" - ] + "const": "core:app:deny-tauri-version" }, { - "description": "core:event:allow-emit-to -> Enables the emit_to command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit-to" - ] + "const": "core:app:deny-version" }, { - "description": "core:event:allow-listen -> Enables the listen command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:event:allow-listen" - ] + "const": "core:event:default" }, { - "description": "core:event:allow-unlisten -> Enables the unlisten command without any pre-configured scope.", + "description": "Enables the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-unlisten" - ] + "const": "core:event:allow-emit" }, { - "description": "core:event:deny-emit -> Denies the emit command without any pre-configured scope.", + "description": "Enables the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit" - ] + "const": "core:event:allow-emit-to" }, { - "description": "core:event:deny-emit-to -> Denies the emit_to command without any pre-configured scope.", + "description": "Enables the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit-to" - ] + "const": "core:event:allow-listen" }, { - "description": "core:event:deny-listen -> Denies the listen command without any pre-configured scope.", + "description": "Enables the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-listen" - ] + "const": "core:event:allow-unlisten" }, { - "description": "core:event:deny-unlisten -> Denies the unlisten command without any pre-configured scope.", + "description": "Denies the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-unlisten" - ] + "const": "core:event:deny-emit" }, { - "description": "core:image:default -> Default permissions for the plugin.", + "description": "Denies the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:default" - ] + "const": "core:event:deny-emit-to" }, { - "description": "core:image:allow-from-bytes -> Enables the from_bytes command without any pre-configured scope.", + "description": "Denies the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-bytes" - ] + "const": "core:event:deny-listen" }, { - "description": "core:image:allow-from-path -> Enables the from_path command without any pre-configured scope.", + "description": "Denies the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-path" - ] + "const": "core:event:deny-unlisten" }, { - "description": "core:image:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:image:allow-new" - ] + "const": "core:image:default" }, { - "description": "core:image:allow-rgba -> Enables the rgba command without any pre-configured scope.", + "description": "Enables the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-rgba" - ] + "const": "core:image:allow-from-bytes" }, { - "description": "core:image:allow-size -> Enables the size command without any pre-configured scope.", + "description": "Enables the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-size" - ] + "const": "core:image:allow-from-path" }, { - "description": "core:image:deny-from-bytes -> Denies the from_bytes command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-bytes" - ] + "const": "core:image:allow-new" }, { - "description": "core:image:deny-from-path -> Denies the from_path command without any pre-configured scope.", + "description": "Enables the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-path" - ] + "const": "core:image:allow-rgba" }, { - "description": "core:image:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-new" - ] + "const": "core:image:allow-size" }, { - "description": "core:image:deny-rgba -> Denies the rgba command without any pre-configured scope.", + "description": "Denies the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-rgba" - ] + "const": "core:image:deny-from-bytes" }, { - "description": "core:image:deny-size -> Denies the size command without any pre-configured scope.", + "description": "Denies the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-size" - ] + "const": "core:image:deny-from-path" }, { - "description": "core:menu:default -> Default permissions for the plugin.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:default" - ] + "const": "core:image:deny-new" }, { - "description": "core:menu:allow-append -> Enables the append command without any pre-configured scope.", + "description": "Denies the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-append" - ] + "const": "core:image:deny-rgba" }, { - "description": "core:menu:allow-create-default -> Enables the create_default command without any pre-configured scope.", + "description": "Denies the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-create-default" - ] + "const": "core:image:deny-size" }, { - "description": "core:menu:allow-get -> Enables the get command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:menu:allow-get" - ] + "const": "core:menu:default" }, { - "description": "core:menu:allow-insert -> Enables the insert command without any pre-configured scope.", + "description": "Enables the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-insert" - ] + "const": "core:menu:allow-append" }, { - "description": "core:menu:allow-is-checked -> Enables the is_checked command without any pre-configured scope.", + "description": "Enables the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-checked" - ] + "const": "core:menu:allow-create-default" }, { - "description": "core:menu:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "description": "Enables the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-enabled" - ] + "const": "core:menu:allow-get" }, { - "description": "core:menu:allow-items -> Enables the items command without any pre-configured scope.", + "description": "Enables the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-items" - ] + "const": "core:menu:allow-insert" }, { - "description": "core:menu:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Enables the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-new" - ] + "const": "core:menu:allow-is-checked" }, { - "description": "core:menu:allow-popup -> Enables the popup command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-popup" - ] + "const": "core:menu:allow-is-enabled" }, { - "description": "core:menu:allow-prepend -> Enables the prepend command without any pre-configured scope.", + "description": "Enables the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-prepend" - ] + "const": "core:menu:allow-items" }, { - "description": "core:menu:allow-remove -> Enables the remove command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove" - ] + "const": "core:menu:allow-new" }, { - "description": "core:menu:allow-remove-at -> Enables the remove_at command without any pre-configured scope.", + "description": "Enables the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove-at" - ] + "const": "core:menu:allow-popup" }, { - "description": "core:menu:allow-set-accelerator -> Enables the set_accelerator command without any pre-configured scope.", + "description": "Enables the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-accelerator" - ] + "const": "core:menu:allow-prepend" }, { - "description": "core:menu:allow-set-as-app-menu -> Enables the set_as_app_menu command without any pre-configured scope.", + "description": "Enables the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-app-menu" - ] + "const": "core:menu:allow-remove" }, { - "description": "core:menu:allow-set-as-help-menu-for-nsapp -> Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:allow-remove-at" }, { - "description": "core:menu:allow-set-as-window-menu -> Enables the set_as_window_menu command without any pre-configured scope.", + "description": "Enables the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-window-menu" - ] + "const": "core:menu:allow-set-accelerator" }, { - "description": "core:menu:allow-set-as-windows-menu-for-nsapp -> Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:allow-set-as-app-menu" }, { - "description": "core:menu:allow-set-checked -> Enables the set_checked command without any pre-configured scope.", + "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-checked" - ] + "const": "core:menu:allow-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:allow-set-enabled -> Enables the set_enabled command without any pre-configured scope.", + "description": "Enables the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-enabled" - ] + "const": "core:menu:allow-set-as-window-menu" }, { - "description": "core:menu:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-icon" - ] + "const": "core:menu:allow-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:allow-set-text -> Enables the set_text command without any pre-configured scope.", + "description": "Enables the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-text" - ] + "const": "core:menu:allow-set-checked" }, { - "description": "core:menu:allow-text -> Enables the text command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-text" - ] + "const": "core:menu:allow-set-enabled" }, { - "description": "core:menu:deny-append -> Denies the append command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-append" - ] + "const": "core:menu:allow-set-icon" }, { - "description": "core:menu:deny-create-default -> Denies the create_default command without any pre-configured scope.", + "description": "Enables the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-create-default" - ] + "const": "core:menu:allow-set-text" }, { - "description": "core:menu:deny-get -> Denies the get command without any pre-configured scope.", + "description": "Enables the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-get" - ] + "const": "core:menu:allow-text" }, { - "description": "core:menu:deny-insert -> Denies the insert command without any pre-configured scope.", + "description": "Denies the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-insert" - ] + "const": "core:menu:deny-append" }, { - "description": "core:menu:deny-is-checked -> Denies the is_checked command without any pre-configured scope.", + "description": "Denies the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-checked" - ] + "const": "core:menu:deny-create-default" }, { - "description": "core:menu:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "description": "Denies the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-enabled" - ] + "const": "core:menu:deny-get" }, { - "description": "core:menu:deny-items -> Denies the items command without any pre-configured scope.", + "description": "Denies the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-items" - ] + "const": "core:menu:deny-insert" }, { - "description": "core:menu:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Denies the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-new" - ] + "const": "core:menu:deny-is-checked" }, { - "description": "core:menu:deny-popup -> Denies the popup command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-popup" - ] + "const": "core:menu:deny-is-enabled" }, { - "description": "core:menu:deny-prepend -> Denies the prepend command without any pre-configured scope.", + "description": "Denies the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-prepend" - ] + "const": "core:menu:deny-items" }, { - "description": "core:menu:deny-remove -> Denies the remove command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove" - ] + "const": "core:menu:deny-new" }, { - "description": "core:menu:deny-remove-at -> Denies the remove_at command without any pre-configured scope.", + "description": "Denies the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove-at" - ] + "const": "core:menu:deny-popup" }, { - "description": "core:menu:deny-set-accelerator -> Denies the set_accelerator command without any pre-configured scope.", + "description": "Denies the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-accelerator" - ] + "const": "core:menu:deny-prepend" }, { - "description": "core:menu:deny-set-as-app-menu -> Denies the set_as_app_menu command without any pre-configured scope.", + "description": "Denies the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-app-menu" - ] + "const": "core:menu:deny-remove" }, { - "description": "core:menu:deny-set-as-help-menu-for-nsapp -> Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:deny-remove-at" }, { - "description": "core:menu:deny-set-as-window-menu -> Denies the set_as_window_menu command without any pre-configured scope.", + "description": "Denies the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-window-menu" - ] + "const": "core:menu:deny-set-accelerator" }, { - "description": "core:menu:deny-set-as-windows-menu-for-nsapp -> Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:deny-set-as-app-menu" }, { - "description": "core:menu:deny-set-checked -> Denies the set_checked command without any pre-configured scope.", + "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-checked" - ] + "const": "core:menu:deny-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:deny-set-enabled -> Denies the set_enabled command without any pre-configured scope.", + "description": "Denies the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-enabled" - ] + "const": "core:menu:deny-set-as-window-menu" }, { - "description": "core:menu:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-icon" - ] + "const": "core:menu:deny-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:deny-set-text -> Denies the set_text command without any pre-configured scope.", + "description": "Denies the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-text" - ] + "const": "core:menu:deny-set-checked" }, { - "description": "core:menu:deny-text -> Denies the text command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-text" - ] + "const": "core:menu:deny-set-enabled" }, { - "description": "core:path:default -> Default permissions for the plugin.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:default" - ] + "const": "core:menu:deny-set-icon" }, { - "description": "core:path:allow-basename -> Enables the basename command without any pre-configured scope.", + "description": "Denies the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-basename" - ] + "const": "core:menu:deny-set-text" }, { - "description": "core:path:allow-dirname -> Enables the dirname command without any pre-configured scope.", + "description": "Denies the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-dirname" - ] + "const": "core:menu:deny-text" }, { - "description": "core:path:allow-extname -> Enables the extname command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:path:allow-extname" - ] + "const": "core:path:default" }, { - "description": "core:path:allow-is-absolute -> Enables the is_absolute command without any pre-configured scope.", + "description": "Enables the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-is-absolute" - ] + "const": "core:path:allow-basename" }, { - "description": "core:path:allow-join -> Enables the join command without any pre-configured scope.", + "description": "Enables the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-join" - ] + "const": "core:path:allow-dirname" }, { - "description": "core:path:allow-normalize -> Enables the normalize command without any pre-configured scope.", + "description": "Enables the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-normalize" - ] + "const": "core:path:allow-extname" }, { - "description": "core:path:allow-resolve -> Enables the resolve command without any pre-configured scope.", + "description": "Enables the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve" - ] + "const": "core:path:allow-is-absolute" }, { - "description": "core:path:allow-resolve-directory -> Enables the resolve_directory command without any pre-configured scope.", + "description": "Enables the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve-directory" - ] + "const": "core:path:allow-join" }, { - "description": "core:path:deny-basename -> Denies the basename command without any pre-configured scope.", + "description": "Enables the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-basename" - ] + "const": "core:path:allow-normalize" }, { - "description": "core:path:deny-dirname -> Denies the dirname command without any pre-configured scope.", + "description": "Enables the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-dirname" - ] + "const": "core:path:allow-resolve" }, { - "description": "core:path:deny-extname -> Denies the extname command without any pre-configured scope.", + "description": "Enables the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-extname" - ] + "const": "core:path:allow-resolve-directory" }, { - "description": "core:path:deny-is-absolute -> Denies the is_absolute command without any pre-configured scope.", + "description": "Denies the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-is-absolute" - ] + "const": "core:path:deny-basename" }, { - "description": "core:path:deny-join -> Denies the join command without any pre-configured scope.", + "description": "Denies the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-join" - ] + "const": "core:path:deny-dirname" }, { - "description": "core:path:deny-normalize -> Denies the normalize command without any pre-configured scope.", + "description": "Denies the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-normalize" - ] + "const": "core:path:deny-extname" }, { - "description": "core:path:deny-resolve -> Denies the resolve command without any pre-configured scope.", + "description": "Denies the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve" - ] + "const": "core:path:deny-is-absolute" }, { - "description": "core:path:deny-resolve-directory -> Denies the resolve_directory command without any pre-configured scope.", + "description": "Denies the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve-directory" - ] + "const": "core:path:deny-join" }, { - "description": "core:resources:default -> Default permissions for the plugin.", + "description": "Denies the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:default" - ] + "const": "core:path:deny-normalize" }, { - "description": "core:resources:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:allow-close" - ] + "const": "core:path:deny-resolve" }, { - "description": "core:resources:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Denies the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:deny-close" - ] + "const": "core:path:deny-resolve-directory" }, { - "description": "core:tray:default -> Default permissions for the plugin.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:default" - ] + "const": "core:resources:default" }, { - "description": "core:tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-get-by-id" - ] + "const": "core:resources:allow-close" }, { - "description": "core:tray:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-new" - ] + "const": "core:resources:deny-close" }, { - "description": "core:tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:allow-remove-by-id" - ] + "const": "core:tray:default" }, { - "description": "core:tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon" - ] + "const": "core:tray:allow-get-by-id" }, { - "description": "core:tray:allow-set-icon-as-template -> Enables the set_icon_as_template command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon-as-template" - ] + "const": "core:tray:allow-new" }, { - "description": "core:tray:allow-set-menu -> Enables the set_menu command without any pre-configured scope.", + "description": "Enables the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-menu" - ] + "const": "core:tray:allow-remove-by-id" }, { - "description": "core:tray:allow-set-show-menu-on-left-click -> Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-show-menu-on-left-click" - ] + "const": "core:tray:allow-set-icon" }, { - "description": "core:tray:allow-set-temp-dir-path -> Enables the set_temp_dir_path command without any pre-configured scope.", + "description": "Enables the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-temp-dir-path" - ] + "const": "core:tray:allow-set-icon-as-template" }, { - "description": "core:tray:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-title" - ] + "const": "core:tray:allow-set-menu" }, { - "description": "core:tray:allow-set-tooltip -> Enables the set_tooltip command without any pre-configured scope.", + "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-tooltip" - ] + "const": "core:tray:allow-set-show-menu-on-left-click" }, { - "description": "core:tray:allow-set-visible -> Enables the set_visible command without any pre-configured scope.", + "description": "Enables the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-visible" - ] + "const": "core:tray:allow-set-temp-dir-path" }, { - "description": "core:tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-get-by-id" - ] + "const": "core:tray:allow-set-title" }, { - "description": "core:tray:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-new" - ] + "const": "core:tray:allow-set-tooltip" }, { - "description": "core:tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.", + "description": "Enables the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-remove-by-id" - ] + "const": "core:tray:allow-set-visible" }, { - "description": "core:tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon" - ] + "const": "core:tray:deny-get-by-id" }, { - "description": "core:tray:deny-set-icon-as-template -> Denies the set_icon_as_template command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon-as-template" - ] + "const": "core:tray:deny-new" }, { - "description": "core:tray:deny-set-menu -> Denies the set_menu command without any pre-configured scope.", + "description": "Denies the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-menu" - ] + "const": "core:tray:deny-remove-by-id" }, { - "description": "core:tray:deny-set-show-menu-on-left-click -> Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-show-menu-on-left-click" - ] + "const": "core:tray:deny-set-icon" }, { - "description": "core:tray:deny-set-temp-dir-path -> Denies the set_temp_dir_path command without any pre-configured scope.", + "description": "Denies the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-temp-dir-path" - ] + "const": "core:tray:deny-set-icon-as-template" }, { - "description": "core:tray:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-title" - ] + "const": "core:tray:deny-set-menu" }, { - "description": "core:tray:deny-set-tooltip -> Denies the set_tooltip command without any pre-configured scope.", + "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-tooltip" - ] + "const": "core:tray:deny-set-show-menu-on-left-click" }, { - "description": "core:tray:deny-set-visible -> Denies the set_visible command without any pre-configured scope.", + "description": "Denies the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-visible" - ] + "const": "core:tray:deny-set-temp-dir-path" }, { - "description": "core:webview:default -> Default permissions for the plugin.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:default" - ] + "const": "core:tray:deny-set-title" }, { - "description": "core:webview:allow-create-webview -> Enables the create_webview command without any pre-configured scope.", + "description": "Denies the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview" - ] + "const": "core:tray:deny-set-tooltip" }, { - "description": "core:webview:allow-create-webview-window -> Enables the create_webview_window command without any pre-configured scope.", + "description": "Denies the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview-window" - ] + "const": "core:tray:deny-set-visible" }, { - "description": "core:webview:allow-get-all-webviews -> Enables the get_all_webviews command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:webview:allow-get-all-webviews" - ] + "const": "core:webview:default" }, { - "description": "core:webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-internal-toggle-devtools" - ] + "const": "core:webview:allow-clear-all-browsing-data" }, { - "description": "core:webview:allow-print -> Enables the print command without any pre-configured scope.", + "description": "Enables the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-print" - ] + "const": "core:webview:allow-create-webview" }, { - "description": "core:webview:allow-reparent -> Enables the reparent command without any pre-configured scope.", + "description": "Enables the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-reparent" - ] + "const": "core:webview:allow-create-webview-window" }, { - "description": "core:webview:allow-set-webview-focus -> Enables the set_webview_focus command without any pre-configured scope.", + "description": "Enables the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-focus" - ] + "const": "core:webview:allow-get-all-webviews" }, { - "description": "core:webview:allow-set-webview-position -> Enables the set_webview_position command without any pre-configured scope.", + "description": "Enables the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-position" - ] + "const": "core:webview:allow-internal-toggle-devtools" }, { - "description": "core:webview:allow-set-webview-size -> Enables the set_webview_size command without any pre-configured scope.", + "description": "Enables the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-size" - ] + "const": "core:webview:allow-print" }, { - "description": "core:webview:allow-set-webview-zoom -> Enables the set_webview_zoom command without any pre-configured scope.", + "description": "Enables the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-zoom" - ] + "const": "core:webview:allow-reparent" }, { - "description": "core:webview:allow-webview-close -> Enables the webview_close command without any pre-configured scope.", + "description": "Enables the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-close" - ] + "const": "core:webview:allow-set-webview-focus" }, { - "description": "core:webview:allow-webview-position -> Enables the webview_position command without any pre-configured scope.", + "description": "Enables the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-position" - ] + "const": "core:webview:allow-set-webview-position" }, { - "description": "core:webview:allow-webview-size -> Enables the webview_size command without any pre-configured scope.", + "description": "Enables the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-size" - ] + "const": "core:webview:allow-set-webview-size" }, { - "description": "core:webview:deny-create-webview -> Denies the create_webview command without any pre-configured scope.", + "description": "Enables the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview" - ] + "const": "core:webview:allow-set-webview-zoom" }, { - "description": "core:webview:deny-create-webview-window -> Denies the create_webview_window command without any pre-configured scope.", + "description": "Enables the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview-window" - ] + "const": "core:webview:allow-webview-close" }, { - "description": "core:webview:deny-get-all-webviews -> Denies the get_all_webviews command without any pre-configured scope.", + "description": "Enables the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-get-all-webviews" - ] + "const": "core:webview:allow-webview-hide" }, { - "description": "core:webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-internal-toggle-devtools" - ] + "const": "core:webview:allow-webview-position" }, { - "description": "core:webview:deny-print -> Denies the print command without any pre-configured scope.", + "description": "Enables the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-print" - ] + "const": "core:webview:allow-webview-show" }, { - "description": "core:webview:deny-reparent -> Denies the reparent command without any pre-configured scope.", + "description": "Enables the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-reparent" - ] + "const": "core:webview:allow-webview-size" }, { - "description": "core:webview:deny-set-webview-focus -> Denies the set_webview_focus command without any pre-configured scope.", + "description": "Denies the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-focus" - ] + "const": "core:webview:deny-clear-all-browsing-data" }, { - "description": "core:webview:deny-set-webview-position -> Denies the set_webview_position command without any pre-configured scope.", + "description": "Denies the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-position" - ] + "const": "core:webview:deny-create-webview" }, { - "description": "core:webview:deny-set-webview-size -> Denies the set_webview_size command without any pre-configured scope.", + "description": "Denies the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-size" - ] + "const": "core:webview:deny-create-webview-window" }, { - "description": "core:webview:deny-set-webview-zoom -> Denies the set_webview_zoom command without any pre-configured scope.", + "description": "Denies the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-zoom" - ] + "const": "core:webview:deny-get-all-webviews" }, { - "description": "core:webview:deny-webview-close -> Denies the webview_close command without any pre-configured scope.", + "description": "Denies the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-close" - ] + "const": "core:webview:deny-internal-toggle-devtools" }, { - "description": "core:webview:deny-webview-position -> Denies the webview_position command without any pre-configured scope.", + "description": "Denies the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-position" - ] + "const": "core:webview:deny-print" }, { - "description": "core:webview:deny-webview-size -> Denies the webview_size command without any pre-configured scope.", + "description": "Denies the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-size" - ] + "const": "core:webview:deny-reparent" }, { - "description": "core:window:default -> Default permissions for the plugin.", + "description": "Denies the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:default" - ] + "const": "core:webview:deny-set-webview-focus" }, { - "description": "core:window:allow-available-monitors -> Enables the available_monitors command without any pre-configured scope.", + "description": "Denies the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-available-monitors" - ] + "const": "core:webview:deny-set-webview-position" }, { - "description": "core:window:allow-center -> Enables the center command without any pre-configured scope.", + "description": "Denies the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-center" - ] + "const": "core:webview:deny-set-webview-size" }, { - "description": "core:window:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-close" - ] + "const": "core:webview:deny-set-webview-zoom" }, { - "description": "core:window:allow-create -> Enables the create command without any pre-configured scope.", + "description": "Denies the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-create" - ] + "const": "core:webview:deny-webview-close" }, { - "description": "core:window:allow-current-monitor -> Enables the current_monitor command without any pre-configured scope.", + "description": "Denies the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-current-monitor" - ] + "const": "core:webview:deny-webview-hide" }, { - "description": "core:window:allow-cursor-position -> Enables the cursor_position command without any pre-configured scope.", + "description": "Denies the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-cursor-position" - ] + "const": "core:webview:deny-webview-position" }, { - "description": "core:window:allow-destroy -> Enables the destroy command without any pre-configured scope.", + "description": "Denies the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-destroy" - ] + "const": "core:webview:deny-webview-show" }, { - "description": "core:window:allow-get-all-windows -> Enables the get_all_windows command without any pre-configured scope.", + "description": "Denies the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-get-all-windows" - ] + "const": "core:webview:deny-webview-size" }, { - "description": "core:window:allow-hide -> Enables the hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:window:allow-hide" - ] + "const": "core:window:default" }, { - "description": "core:window:allow-inner-position -> Enables the inner_position command without any pre-configured scope.", + "description": "Enables the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-position" - ] + "const": "core:window:allow-available-monitors" }, { - "description": "core:window:allow-inner-size -> Enables the inner_size command without any pre-configured scope.", + "description": "Enables the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-size" - ] + "const": "core:window:allow-center" }, { - "description": "core:window:allow-internal-toggle-maximize -> Enables the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-internal-toggle-maximize" - ] + "const": "core:window:allow-close" }, { - "description": "core:window:allow-is-closable -> Enables the is_closable command without any pre-configured scope.", + "description": "Enables the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-closable" - ] + "const": "core:window:allow-create" }, { - "description": "core:window:allow-is-decorated -> Enables the is_decorated command without any pre-configured scope.", + "description": "Enables the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-decorated" - ] + "const": "core:window:allow-current-monitor" }, { - "description": "core:window:allow-is-focused -> Enables the is_focused command without any pre-configured scope.", + "description": "Enables the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-focused" - ] + "const": "core:window:allow-cursor-position" }, { - "description": "core:window:allow-is-fullscreen -> Enables the is_fullscreen command without any pre-configured scope.", + "description": "Enables the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-fullscreen" - ] + "const": "core:window:allow-destroy" }, { - "description": "core:window:allow-is-maximizable -> Enables the is_maximizable command without any pre-configured scope.", + "description": "Enables the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximizable" - ] + "const": "core:window:allow-get-all-windows" }, { - "description": "core:window:allow-is-maximized -> Enables the is_maximized command without any pre-configured scope.", + "description": "Enables the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximized" - ] + "const": "core:window:allow-hide" }, { - "description": "core:window:allow-is-minimizable -> Enables the is_minimizable command without any pre-configured scope.", + "description": "Enables the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimizable" - ] + "const": "core:window:allow-inner-position" }, { - "description": "core:window:allow-is-minimized -> Enables the is_minimized command without any pre-configured scope.", + "description": "Enables the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimized" - ] + "const": "core:window:allow-inner-size" }, { - "description": "core:window:allow-is-resizable -> Enables the is_resizable command without any pre-configured scope.", + "description": "Enables the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-resizable" - ] + "const": "core:window:allow-internal-toggle-maximize" }, { - "description": "core:window:allow-is-visible -> Enables the is_visible command without any pre-configured scope.", + "description": "Enables the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-visible" - ] + "const": "core:window:allow-is-closable" }, { - "description": "core:window:allow-maximize -> Enables the maximize command without any pre-configured scope.", + "description": "Enables the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-maximize" - ] + "const": "core:window:allow-is-decorated" }, { - "description": "core:window:allow-minimize -> Enables the minimize command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-minimize" - ] + "const": "core:window:allow-is-enabled" }, { - "description": "core:window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.", + "description": "Enables the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-monitor-from-point" - ] + "const": "core:window:allow-is-focused" }, { - "description": "core:window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.", + "description": "Enables the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-position" - ] + "const": "core:window:allow-is-fullscreen" }, { - "description": "core:window:allow-outer-size -> Enables the outer_size command without any pre-configured scope.", + "description": "Enables the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-size" - ] + "const": "core:window:allow-is-maximizable" }, { - "description": "core:window:allow-primary-monitor -> Enables the primary_monitor command without any pre-configured scope.", + "description": "Enables the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-primary-monitor" - ] + "const": "core:window:allow-is-maximized" }, { - "description": "core:window:allow-request-user-attention -> Enables the request_user_attention command without any pre-configured scope.", + "description": "Enables the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-request-user-attention" - ] + "const": "core:window:allow-is-minimizable" }, { - "description": "core:window:allow-scale-factor -> Enables the scale_factor command without any pre-configured scope.", + "description": "Enables the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-scale-factor" - ] + "const": "core:window:allow-is-minimized" }, { - "description": "core:window:allow-set-always-on-bottom -> Enables the set_always_on_bottom command without any pre-configured scope.", + "description": "Enables the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-bottom" - ] + "const": "core:window:allow-is-resizable" }, { - "description": "core:window:allow-set-always-on-top -> Enables the set_always_on_top command without any pre-configured scope.", + "description": "Enables the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-top" - ] + "const": "core:window:allow-is-visible" }, { - "description": "core:window:allow-set-closable -> Enables the set_closable command without any pre-configured scope.", + "description": "Enables the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-closable" - ] + "const": "core:window:allow-maximize" }, { - "description": "core:window:allow-set-content-protected -> Enables the set_content_protected command without any pre-configured scope.", + "description": "Enables the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-content-protected" - ] + "const": "core:window:allow-minimize" }, { - "description": "core:window:allow-set-cursor-grab -> Enables the set_cursor_grab command without any pre-configured scope.", + "description": "Enables the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-grab" - ] + "const": "core:window:allow-monitor-from-point" }, { - "description": "core:window:allow-set-cursor-icon -> Enables the set_cursor_icon command without any pre-configured scope.", + "description": "Enables the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-icon" - ] + "const": "core:window:allow-outer-position" }, { - "description": "core:window:allow-set-cursor-position -> Enables the set_cursor_position command without any pre-configured scope.", + "description": "Enables the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-position" - ] + "const": "core:window:allow-outer-size" }, { - "description": "core:window:allow-set-cursor-visible -> Enables the set_cursor_visible command without any pre-configured scope.", + "description": "Enables the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-visible" - ] + "const": "core:window:allow-primary-monitor" }, { - "description": "core:window:allow-set-decorations -> Enables the set_decorations command without any pre-configured scope.", + "description": "Enables the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-decorations" - ] + "const": "core:window:allow-request-user-attention" }, { - "description": "core:window:allow-set-effects -> Enables the set_effects command without any pre-configured scope.", + "description": "Enables the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-effects" - ] + "const": "core:window:allow-scale-factor" }, { - "description": "core:window:allow-set-focus -> Enables the set_focus command without any pre-configured scope.", + "description": "Enables the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-focus" - ] + "const": "core:window:allow-set-always-on-bottom" }, { - "description": "core:window:allow-set-fullscreen -> Enables the set_fullscreen command without any pre-configured scope.", + "description": "Enables the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-fullscreen" - ] + "const": "core:window:allow-set-always-on-top" }, { - "description": "core:window:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-icon" - ] + "const": "core:window:allow-set-closable" }, { - "description": "core:window:allow-set-ignore-cursor-events -> Enables the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Enables the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-ignore-cursor-events" - ] + "const": "core:window:allow-set-content-protected" }, { - "description": "core:window:allow-set-max-size -> Enables the set_max_size command without any pre-configured scope.", + "description": "Enables the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-max-size" - ] + "const": "core:window:allow-set-cursor-grab" }, { - "description": "core:window:allow-set-maximizable -> Enables the set_maximizable command without any pre-configured scope.", + "description": "Enables the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-maximizable" - ] + "const": "core:window:allow-set-cursor-icon" }, { - "description": "core:window:allow-set-min-size -> Enables the set_min_size command without any pre-configured scope.", + "description": "Enables the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-min-size" - ] + "const": "core:window:allow-set-cursor-position" }, { - "description": "core:window:allow-set-minimizable -> Enables the set_minimizable command without any pre-configured scope.", + "description": "Enables the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-minimizable" - ] + "const": "core:window:allow-set-cursor-visible" }, { - "description": "core:window:allow-set-position -> Enables the set_position command without any pre-configured scope.", + "description": "Enables the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-position" - ] + "const": "core:window:allow-set-decorations" }, { - "description": "core:window:allow-set-progress-bar -> Enables the set_progress_bar command without any pre-configured scope.", + "description": "Enables the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-progress-bar" - ] + "const": "core:window:allow-set-effects" }, { - "description": "core:window:allow-set-resizable -> Enables the set_resizable command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-resizable" - ] + "const": "core:window:allow-set-enabled" }, { - "description": "core:window:allow-set-shadow -> Enables the set_shadow command without any pre-configured scope.", + "description": "Enables the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-shadow" - ] + "const": "core:window:allow-set-focus" }, { - "description": "core:window:allow-set-size -> Enables the set_size command without any pre-configured scope.", + "description": "Enables the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size" - ] + "const": "core:window:allow-set-fullscreen" }, { - "description": "core:window:allow-set-size-constraints -> Enables the set_size_constraints command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size-constraints" - ] + "const": "core:window:allow-set-icon" }, { - "description": "core:window:allow-set-skip-taskbar -> Enables the set_skip_taskbar command without any pre-configured scope.", + "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-skip-taskbar" - ] + "const": "core:window:allow-set-ignore-cursor-events" }, { - "description": "core:window:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title" - ] + "const": "core:window:allow-set-max-size" }, { - "description": "core:window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.", + "description": "Enables the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title-bar-style" - ] + "const": "core:window:allow-set-maximizable" }, { - "description": "core:window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Enables the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-visible-on-all-workspaces" - ] + "const": "core:window:allow-set-min-size" }, { - "description": "core:window:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-show" - ] + "const": "core:window:allow-set-minimizable" }, { - "description": "core:window:allow-start-dragging -> Enables the start_dragging command without any pre-configured scope.", + "description": "Enables the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-dragging" - ] + "const": "core:window:allow-set-position" }, { - "description": "core:window:allow-start-resize-dragging -> Enables the start_resize_dragging command without any pre-configured scope.", + "description": "Enables the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-resize-dragging" - ] + "const": "core:window:allow-set-progress-bar" }, { - "description": "core:window:allow-theme -> Enables the theme command without any pre-configured scope.", + "description": "Enables the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-theme" - ] + "const": "core:window:allow-set-resizable" }, { - "description": "core:window:allow-title -> Enables the title command without any pre-configured scope.", + "description": "Enables the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-title" - ] + "const": "core:window:allow-set-shadow" }, { - "description": "core:window:allow-toggle-maximize -> Enables the toggle_maximize command without any pre-configured scope.", + "description": "Enables the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-toggle-maximize" - ] + "const": "core:window:allow-set-size" }, { - "description": "core:window:allow-unmaximize -> Enables the unmaximize command without any pre-configured scope.", + "description": "Enables the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unmaximize" - ] + "const": "core:window:allow-set-size-constraints" }, { - "description": "core:window:allow-unminimize -> Enables the unminimize command without any pre-configured scope.", + "description": "Enables the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unminimize" - ] + "const": "core:window:allow-set-skip-taskbar" }, { - "description": "core:window:deny-available-monitors -> Denies the available_monitors command without any pre-configured scope.", + "description": "Enables the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-available-monitors" - ] + "const": "core:window:allow-set-theme" }, { - "description": "core:window:deny-center -> Denies the center command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-center" - ] + "const": "core:window:allow-set-title" }, { - "description": "core:window:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Enables the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-close" - ] + "const": "core:window:allow-set-title-bar-style" }, { - "description": "core:window:deny-create -> Denies the create command without any pre-configured scope.", + "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-create" - ] + "const": "core:window:allow-set-visible-on-all-workspaces" }, { - "description": "core:window:deny-current-monitor -> Denies the current_monitor command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-current-monitor" - ] + "const": "core:window:allow-show" }, { - "description": "core:window:deny-cursor-position -> Denies the cursor_position command without any pre-configured scope.", + "description": "Enables the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-cursor-position" - ] + "const": "core:window:allow-start-dragging" }, { - "description": "core:window:deny-destroy -> Denies the destroy command without any pre-configured scope.", + "description": "Enables the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-destroy" - ] + "const": "core:window:allow-start-resize-dragging" }, { - "description": "core:window:deny-get-all-windows -> Denies the get_all_windows command without any pre-configured scope.", + "description": "Enables the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-get-all-windows" - ] + "const": "core:window:allow-theme" }, { - "description": "core:window:deny-hide -> Denies the hide command without any pre-configured scope.", + "description": "Enables the title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-hide" - ] + "const": "core:window:allow-title" }, { - "description": "core:window:deny-inner-position -> Denies the inner_position command without any pre-configured scope.", + "description": "Enables the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-position" - ] + "const": "core:window:allow-toggle-maximize" }, { - "description": "core:window:deny-inner-size -> Denies the inner_size command without any pre-configured scope.", + "description": "Enables the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-size" - ] + "const": "core:window:allow-unmaximize" }, { - "description": "core:window:deny-internal-toggle-maximize -> Denies the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-internal-toggle-maximize" - ] + "const": "core:window:allow-unminimize" }, { - "description": "core:window:deny-is-closable -> Denies the is_closable command without any pre-configured scope.", + "description": "Denies the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-closable" - ] + "const": "core:window:deny-available-monitors" }, { - "description": "core:window:deny-is-decorated -> Denies the is_decorated command without any pre-configured scope.", + "description": "Denies the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-decorated" - ] + "const": "core:window:deny-center" }, { - "description": "core:window:deny-is-focused -> Denies the is_focused command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-focused" - ] + "const": "core:window:deny-close" }, { - "description": "core:window:deny-is-fullscreen -> Denies the is_fullscreen command without any pre-configured scope.", + "description": "Denies the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-fullscreen" - ] + "const": "core:window:deny-create" }, { - "description": "core:window:deny-is-maximizable -> Denies the is_maximizable command without any pre-configured scope.", + "description": "Denies the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximizable" - ] + "const": "core:window:deny-current-monitor" }, { - "description": "core:window:deny-is-maximized -> Denies the is_maximized command without any pre-configured scope.", + "description": "Denies the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximized" - ] + "const": "core:window:deny-cursor-position" }, { - "description": "core:window:deny-is-minimizable -> Denies the is_minimizable command without any pre-configured scope.", + "description": "Denies the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimizable" - ] + "const": "core:window:deny-destroy" }, { - "description": "core:window:deny-is-minimized -> Denies the is_minimized command without any pre-configured scope.", + "description": "Denies the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimized" - ] + "const": "core:window:deny-get-all-windows" }, { - "description": "core:window:deny-is-resizable -> Denies the is_resizable command without any pre-configured scope.", + "description": "Denies the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-resizable" - ] + "const": "core:window:deny-hide" }, { - "description": "core:window:deny-is-visible -> Denies the is_visible command without any pre-configured scope.", + "description": "Denies the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-visible" - ] + "const": "core:window:deny-inner-position" }, { - "description": "core:window:deny-maximize -> Denies the maximize command without any pre-configured scope.", + "description": "Denies the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-maximize" - ] + "const": "core:window:deny-inner-size" }, { - "description": "core:window:deny-minimize -> Denies the minimize command without any pre-configured scope.", + "description": "Denies the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-minimize" - ] + "const": "core:window:deny-internal-toggle-maximize" }, { - "description": "core:window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.", + "description": "Denies the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-monitor-from-point" - ] + "const": "core:window:deny-is-closable" }, { - "description": "core:window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.", + "description": "Denies the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-position" - ] + "const": "core:window:deny-is-decorated" }, { - "description": "core:window:deny-outer-size -> Denies the outer_size command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-size" - ] + "const": "core:window:deny-is-enabled" }, { - "description": "core:window:deny-primary-monitor -> Denies the primary_monitor command without any pre-configured scope.", + "description": "Denies the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-primary-monitor" - ] + "const": "core:window:deny-is-focused" }, { - "description": "core:window:deny-request-user-attention -> Denies the request_user_attention command without any pre-configured scope.", + "description": "Denies the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-request-user-attention" - ] + "const": "core:window:deny-is-fullscreen" }, { - "description": "core:window:deny-scale-factor -> Denies the scale_factor command without any pre-configured scope.", + "description": "Denies the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-scale-factor" - ] + "const": "core:window:deny-is-maximizable" }, { - "description": "core:window:deny-set-always-on-bottom -> Denies the set_always_on_bottom command without any pre-configured scope.", + "description": "Denies the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-bottom" - ] + "const": "core:window:deny-is-maximized" }, { - "description": "core:window:deny-set-always-on-top -> Denies the set_always_on_top command without any pre-configured scope.", + "description": "Denies the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-top" - ] + "const": "core:window:deny-is-minimizable" }, { - "description": "core:window:deny-set-closable -> Denies the set_closable command without any pre-configured scope.", + "description": "Denies the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-closable" - ] + "const": "core:window:deny-is-minimized" }, { - "description": "core:window:deny-set-content-protected -> Denies the set_content_protected command without any pre-configured scope.", + "description": "Denies the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-content-protected" - ] + "const": "core:window:deny-is-resizable" }, { - "description": "core:window:deny-set-cursor-grab -> Denies the set_cursor_grab command without any pre-configured scope.", + "description": "Denies the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-grab" - ] + "const": "core:window:deny-is-visible" }, { - "description": "core:window:deny-set-cursor-icon -> Denies the set_cursor_icon command without any pre-configured scope.", + "description": "Denies the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-icon" - ] + "const": "core:window:deny-maximize" }, { - "description": "core:window:deny-set-cursor-position -> Denies the set_cursor_position command without any pre-configured scope.", + "description": "Denies the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-position" - ] + "const": "core:window:deny-minimize" }, { - "description": "core:window:deny-set-cursor-visible -> Denies the set_cursor_visible command without any pre-configured scope.", + "description": "Denies the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-visible" - ] + "const": "core:window:deny-monitor-from-point" }, { - "description": "core:window:deny-set-decorations -> Denies the set_decorations command without any pre-configured scope.", + "description": "Denies the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-decorations" - ] + "const": "core:window:deny-outer-position" }, { - "description": "core:window:deny-set-effects -> Denies the set_effects command without any pre-configured scope.", + "description": "Denies the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-effects" - ] + "const": "core:window:deny-outer-size" }, { - "description": "core:window:deny-set-focus -> Denies the set_focus command without any pre-configured scope.", + "description": "Denies the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-focus" - ] + "const": "core:window:deny-primary-monitor" }, { - "description": "core:window:deny-set-fullscreen -> Denies the set_fullscreen command without any pre-configured scope.", + "description": "Denies the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-fullscreen" - ] + "const": "core:window:deny-request-user-attention" }, { - "description": "core:window:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-icon" - ] + "const": "core:window:deny-scale-factor" }, { - "description": "core:window:deny-set-ignore-cursor-events -> Denies the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Denies the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-ignore-cursor-events" - ] + "const": "core:window:deny-set-always-on-bottom" }, { - "description": "core:window:deny-set-max-size -> Denies the set_max_size command without any pre-configured scope.", + "description": "Denies the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-max-size" - ] + "const": "core:window:deny-set-always-on-top" }, { - "description": "core:window:deny-set-maximizable -> Denies the set_maximizable command without any pre-configured scope.", + "description": "Denies the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-maximizable" - ] + "const": "core:window:deny-set-closable" }, { - "description": "core:window:deny-set-min-size -> Denies the set_min_size command without any pre-configured scope.", + "description": "Denies the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-min-size" - ] + "const": "core:window:deny-set-content-protected" }, { - "description": "core:window:deny-set-minimizable -> Denies the set_minimizable command without any pre-configured scope.", + "description": "Denies the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-minimizable" - ] + "const": "core:window:deny-set-cursor-grab" }, { - "description": "core:window:deny-set-position -> Denies the set_position command without any pre-configured scope.", + "description": "Denies the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-position" - ] + "const": "core:window:deny-set-cursor-icon" }, { - "description": "core:window:deny-set-progress-bar -> Denies the set_progress_bar command without any pre-configured scope.", + "description": "Denies the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-progress-bar" - ] + "const": "core:window:deny-set-cursor-position" }, { - "description": "core:window:deny-set-resizable -> Denies the set_resizable command without any pre-configured scope.", + "description": "Denies the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-resizable" - ] + "const": "core:window:deny-set-cursor-visible" }, { - "description": "core:window:deny-set-shadow -> Denies the set_shadow command without any pre-configured scope.", + "description": "Denies the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-shadow" - ] + "const": "core:window:deny-set-decorations" }, { - "description": "core:window:deny-set-size -> Denies the set_size command without any pre-configured scope.", + "description": "Denies the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size" - ] + "const": "core:window:deny-set-effects" }, { - "description": "core:window:deny-set-size-constraints -> Denies the set_size_constraints command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size-constraints" - ] + "const": "core:window:deny-set-enabled" }, { - "description": "core:window:deny-set-skip-taskbar -> Denies the set_skip_taskbar command without any pre-configured scope.", + "description": "Denies the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-skip-taskbar" - ] + "const": "core:window:deny-set-focus" }, { - "description": "core:window:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title" - ] + "const": "core:window:deny-set-fullscreen" }, { - "description": "core:window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title-bar-style" - ] + "const": "core:window:deny-set-icon" }, { - "description": "core:window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-visible-on-all-workspaces" - ] + "const": "core:window:deny-set-ignore-cursor-events" }, { - "description": "core:window:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-show" - ] + "const": "core:window:deny-set-max-size" }, { - "description": "core:window:deny-start-dragging -> Denies the start_dragging command without any pre-configured scope.", + "description": "Denies the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-dragging" - ] + "const": "core:window:deny-set-maximizable" }, { - "description": "core:window:deny-start-resize-dragging -> Denies the start_resize_dragging command without any pre-configured scope.", + "description": "Denies the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-resize-dragging" - ] + "const": "core:window:deny-set-min-size" }, { - "description": "core:window:deny-theme -> Denies the theme command without any pre-configured scope.", + "description": "Denies the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-theme" - ] + "const": "core:window:deny-set-minimizable" }, { - "description": "core:window:deny-title -> Denies the title command without any pre-configured scope.", + "description": "Denies the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-title" - ] + "const": "core:window:deny-set-position" }, { - "description": "core:window:deny-toggle-maximize -> Denies the toggle_maximize command without any pre-configured scope.", + "description": "Denies the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-toggle-maximize" - ] + "const": "core:window:deny-set-progress-bar" }, { - "description": "core:window:deny-unmaximize -> Denies the unmaximize command without any pre-configured scope.", + "description": "Denies the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unmaximize" - ] + "const": "core:window:deny-set-resizable" }, { - "description": "core:window:deny-unminimize -> Denies the unminimize command without any pre-configured scope.", + "description": "Denies the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unminimize" - ] + "const": "core:window:deny-set-shadow" }, { - "description": "dialog:default -> This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", + "description": "Denies the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:default" - ] + "const": "core:window:deny-set-size" }, { - "description": "dialog:allow-ask -> Enables the ask command without any pre-configured scope.", + "description": "Denies the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-ask" - ] + "const": "core:window:deny-set-size-constraints" }, { - "description": "dialog:allow-confirm -> Enables the confirm command without any pre-configured scope.", + "description": "Denies the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-confirm" - ] + "const": "core:window:deny-set-skip-taskbar" }, { - "description": "dialog:allow-message -> Enables the message command without any pre-configured scope.", + "description": "Denies the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-message" - ] + "const": "core:window:deny-set-theme" }, { - "description": "dialog:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-open" - ] + "const": "core:window:deny-set-title" }, { - "description": "dialog:allow-save -> Enables the save command without any pre-configured scope.", + "description": "Denies the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-save" - ] + "const": "core:window:deny-set-title-bar-style" }, { - "description": "dialog:deny-ask -> Denies the ask command without any pre-configured scope.", + "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-ask" - ] + "const": "core:window:deny-set-visible-on-all-workspaces" }, { - "description": "dialog:deny-confirm -> Denies the confirm command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-confirm" - ] + "const": "core:window:deny-show" }, { - "description": "dialog:deny-message -> Denies the message command without any pre-configured scope.", + "description": "Denies the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-message" - ] + "const": "core:window:deny-start-dragging" }, { - "description": "dialog:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-open" - ] + "const": "core:window:deny-start-resize-dragging" }, { - "description": "dialog:deny-save -> Denies the save command without any pre-configured scope.", + "description": "Denies the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-save" - ] + "const": "core:window:deny-theme" }, { - "description": "log:default -> Allows the log command", + "description": "Denies the title command without any pre-configured scope.", "type": "string", - "enum": [ - "log:default" - ] + "const": "core:window:deny-title" }, { - "description": "log:allow-log -> Enables the log command without any pre-configured scope.", + "description": "Denies the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:allow-log" - ] + "const": "core:window:deny-toggle-maximize" }, { - "description": "log:deny-log -> Denies the log command without any pre-configured scope.", + "description": "Denies the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:deny-log" - ] + "const": "core:window:deny-unmaximize" }, { - "description": "notification:default -> This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", + "description": "Denies the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:default" - ] + "const": "core:window:deny-unminimize" }, { - "description": "notification:allow-batch -> Enables the batch command without any pre-configured scope.", + "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", "type": "string", - "enum": [ - "notification:allow-batch" - ] + "const": "dialog:default" }, { - "description": "notification:allow-cancel -> Enables the cancel command without any pre-configured scope.", + "description": "Enables the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-cancel" - ] + "const": "dialog:allow-ask" }, { - "description": "notification:allow-check-permissions -> Enables the check_permissions command without any pre-configured scope.", + "description": "Enables the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-check-permissions" - ] + "const": "dialog:allow-confirm" }, { - "description": "notification:allow-create-channel -> Enables the create_channel command without any pre-configured scope.", + "description": "Enables the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-create-channel" - ] + "const": "dialog:allow-message" }, { - "description": "notification:allow-delete-channel -> Enables the delete_channel command without any pre-configured scope.", + "description": "Enables the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-delete-channel" - ] + "const": "dialog:allow-open" }, { - "description": "notification:allow-get-active -> Enables the get_active command without any pre-configured scope.", + "description": "Enables the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-active" - ] + "const": "dialog:allow-save" }, { - "description": "notification:allow-get-pending -> Enables the get_pending command without any pre-configured scope.", + "description": "Denies the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-pending" - ] + "const": "dialog:deny-ask" }, { - "description": "notification:allow-is-permission-granted -> Enables the is_permission_granted command without any pre-configured scope.", + "description": "Denies the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-is-permission-granted" - ] + "const": "dialog:deny-confirm" }, { - "description": "notification:allow-list-channels -> Enables the list_channels command without any pre-configured scope.", + "description": "Denies the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-list-channels" - ] + "const": "dialog:deny-message" }, { - "description": "notification:allow-notify -> Enables the notify command without any pre-configured scope.", + "description": "Denies the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-notify" - ] + "const": "dialog:deny-open" }, { - "description": "notification:allow-permission-state -> Enables the permission_state command without any pre-configured scope.", + "description": "Denies the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-permission-state" - ] + "const": "dialog:deny-save" }, { - "description": "notification:allow-register-action-types -> Enables the register_action_types command without any pre-configured scope.", + "description": "Allows the log command", "type": "string", - "enum": [ - "notification:allow-register-action-types" - ] + "const": "log:default" }, { - "description": "notification:allow-register-listener -> Enables the register_listener command without any pre-configured scope.", + "description": "Enables the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-register-listener" - ] + "const": "log:allow-log" }, { - "description": "notification:allow-remove-active -> Enables the remove_active command without any pre-configured scope.", + "description": "Denies the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-remove-active" - ] + "const": "log:deny-log" }, { - "description": "notification:allow-request-permission -> Enables the request_permission command without any pre-configured scope.", + "description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", "type": "string", - "enum": [ - "notification:allow-request-permission" - ] + "const": "notification:default" }, { - "description": "notification:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-show" - ] + "const": "notification:allow-batch" }, { - "description": "notification:deny-batch -> Denies the batch command without any pre-configured scope.", + "description": "Enables the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-batch" - ] + "const": "notification:allow-cancel" }, { - "description": "notification:deny-cancel -> Denies the cancel command without any pre-configured scope.", + "description": "Enables the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-cancel" - ] + "const": "notification:allow-check-permissions" }, { - "description": "notification:deny-check-permissions -> Denies the check_permissions command without any pre-configured scope.", + "description": "Enables the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-check-permissions" - ] + "const": "notification:allow-create-channel" }, { - "description": "notification:deny-create-channel -> Denies the create_channel command without any pre-configured scope.", + "description": "Enables the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-create-channel" - ] + "const": "notification:allow-delete-channel" }, { - "description": "notification:deny-delete-channel -> Denies the delete_channel command without any pre-configured scope.", + "description": "Enables the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-delete-channel" - ] + "const": "notification:allow-get-active" }, { - "description": "notification:deny-get-active -> Denies the get_active command without any pre-configured scope.", + "description": "Enables the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-active" - ] + "const": "notification:allow-get-pending" }, { - "description": "notification:deny-get-pending -> Denies the get_pending command without any pre-configured scope.", + "description": "Enables the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-pending" - ] + "const": "notification:allow-is-permission-granted" }, { - "description": "notification:deny-is-permission-granted -> Denies the is_permission_granted command without any pre-configured scope.", + "description": "Enables the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-is-permission-granted" - ] + "const": "notification:allow-list-channels" }, { - "description": "notification:deny-list-channels -> Denies the list_channels command without any pre-configured scope.", + "description": "Enables the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-list-channels" - ] + "const": "notification:allow-notify" }, { - "description": "notification:deny-notify -> Denies the notify command without any pre-configured scope.", + "description": "Enables the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-notify" - ] + "const": "notification:allow-permission-state" }, { - "description": "notification:deny-permission-state -> Denies the permission_state command without any pre-configured scope.", + "description": "Enables the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-permission-state" - ] + "const": "notification:allow-register-action-types" }, { - "description": "notification:deny-register-action-types -> Denies the register_action_types command without any pre-configured scope.", + "description": "Enables the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-action-types" - ] + "const": "notification:allow-register-listener" }, { - "description": "notification:deny-register-listener -> Denies the register_listener command without any pre-configured scope.", + "description": "Enables the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-listener" - ] + "const": "notification:allow-remove-active" }, { - "description": "notification:deny-remove-active -> Denies the remove_active command without any pre-configured scope.", + "description": "Enables the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-remove-active" - ] + "const": "notification:allow-request-permission" }, { - "description": "notification:deny-request-permission -> Denies the request_permission command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-request-permission" - ] + "const": "notification:allow-show" }, { - "description": "notification:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-show" - ] + "const": "notification:deny-batch" }, { - "description": "os:default -> This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", + "description": "Denies the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:default" - ] + "const": "notification:deny-cancel" }, { - "description": "os:allow-arch -> Enables the arch command without any pre-configured scope.", + "description": "Denies the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-arch" - ] + "const": "notification:deny-check-permissions" }, { - "description": "os:allow-exe-extension -> Enables the exe_extension command without any pre-configured scope.", + "description": "Denies the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-exe-extension" - ] + "const": "notification:deny-create-channel" }, { - "description": "os:allow-family -> Enables the family command without any pre-configured scope.", + "description": "Denies the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-family" - ] + "const": "notification:deny-delete-channel" }, { - "description": "os:allow-hostname -> Enables the hostname command without any pre-configured scope.", + "description": "Denies the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-hostname" - ] + "const": "notification:deny-get-active" }, { - "description": "os:allow-locale -> Enables the locale command without any pre-configured scope.", + "description": "Denies the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-locale" - ] + "const": "notification:deny-get-pending" }, { - "description": "os:allow-os-type -> Enables the os_type command without any pre-configured scope.", + "description": "Denies the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-os-type" - ] + "const": "notification:deny-is-permission-granted" }, { - "description": "os:allow-platform -> Enables the platform command without any pre-configured scope.", + "description": "Denies the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-platform" - ] + "const": "notification:deny-list-channels" }, { - "description": "os:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Denies the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-version" - ] + "const": "notification:deny-notify" }, { - "description": "os:deny-arch -> Denies the arch command without any pre-configured scope.", + "description": "Denies the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-arch" - ] + "const": "notification:deny-permission-state" }, { - "description": "os:deny-exe-extension -> Denies the exe_extension command without any pre-configured scope.", + "description": "Denies the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-exe-extension" - ] + "const": "notification:deny-register-action-types" }, { - "description": "os:deny-family -> Denies the family command without any pre-configured scope.", + "description": "Denies the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-family" - ] + "const": "notification:deny-register-listener" }, { - "description": "os:deny-hostname -> Denies the hostname command without any pre-configured scope.", + "description": "Denies the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-hostname" - ] + "const": "notification:deny-remove-active" }, { - "description": "os:deny-locale -> Denies the locale command without any pre-configured scope.", + "description": "Denies the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-locale" - ] + "const": "notification:deny-request-permission" }, { - "description": "os:deny-os-type -> Denies the os_type command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-os-type" - ] + "const": "notification:deny-show" }, { - "description": "os:deny-platform -> Denies the platform command without any pre-configured scope.", + "description": "This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", "type": "string", - "enum": [ - "os:deny-platform" - ] + "const": "os:default" }, { - "description": "os:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Enables the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-version" - ] + "const": "os:allow-arch" }, { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "description": "Enables the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:default" - ] + "const": "os:allow-exe-extension" }, { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "description": "Enables the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-execute" - ] + "const": "os:allow-family" }, { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "description": "Enables the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-kill" - ] + "const": "os:allow-hostname" }, { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Enables the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-open" - ] + "const": "os:allow-locale" }, { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "description": "Enables the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-spawn" - ] + "const": "os:allow-os-type" }, { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "description": "Enables the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] + "const": "os:allow-platform" }, { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-execute" - ] + "const": "os:allow-version" }, { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "description": "Denies the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-kill" - ] + "const": "os:deny-arch" }, { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-open" - ] + "const": "os:deny-exe-extension" }, { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "description": "Denies the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-spawn" - ] + "const": "os:deny-family" }, { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "description": "Denies the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "const": "os:deny-hostname" }, { - "description": "window-state:default -> This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "description": "Denies the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:default" - ] + "const": "os:deny-locale" }, { - "description": "window-state:allow-filename -> Enables the filename command without any pre-configured scope.", + "description": "Denies the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-filename" - ] + "const": "os:deny-os-type" }, { - "description": "window-state:allow-restore-state -> Enables the restore_state command without any pre-configured scope.", + "description": "Denies the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-restore-state" - ] + "const": "os:deny-platform" }, { - "description": "window-state:allow-save-window-state -> Enables the save_window_state command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-save-window-state" - ] + "const": "os:deny-version" }, { - "description": "window-state:deny-filename -> Denies the filename command without any pre-configured scope.", + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", "type": "string", - "enum": [ - "window-state:deny-filename" - ] + "const": "shell:default" }, { - "description": "window-state:deny-restore-state -> Denies the restore_state command without any pre-configured scope.", + "description": "Enables the execute command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-restore-state" - ] + "const": "shell:allow-execute" }, { - "description": "window-state:deny-save-window-state -> Denies the save_window_state command without any pre-configured scope.", + "description": "Enables the kill command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-save-window-state" - ] + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + }, + { + "description": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "type": "string", + "const": "window-state:default" + }, + { + "description": "Enables the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-filename" + }, + { + "description": "Enables the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-restore-state" + }, + { + "description": "Enables the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-save-window-state" + }, + { + "description": "Denies the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-filename" + }, + { + "description": "Denies the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-restore-state" + }, + { + "description": "Denies the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-save-window-state" } ] }, @@ -3027,7 +2426,7 @@ } ] }, - "ShellAllowedArg": { + "ShellScopeEntryAllowedArg": { "description": "A command argument allowed to be executed by the webview API.", "anyOf": [ { @@ -3055,18 +2454,18 @@ } ] }, - "ShellAllowedArgs": { - "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "ShellScopeEntryAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", "anyOf": [ { "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", "type": "boolean" }, { - "description": "A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.", + "description": "A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.", "type": "array", "items": { - "$ref": "#/definitions/ShellAllowedArg" + "$ref": "#/definitions/ShellScopeEntryAllowedArg" } } ] diff --git a/desktop/tauri/src-tauri/gen/schemas/windows-schema.json b/desktop/tauri/src-tauri/gen/schemas/windows-schema.json index 797ccb5c..905008b7 100644 --- a/desktop/tauri/src-tauri/gen/schemas/windows-schema.json +++ b/desktop/tauri/src-tauri/gen/schemas/windows-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" @@ -133,2803 +133,2202 @@ { "description": "Reference a permission or permission set by identifier and extends its scope.", "type": "object", - "oneOf": [ + "allOf": [ { - "type": "object", - "required": [ - "identifier" - ], + "if": { + "properties": { + "identifier": { + "anyOf": [ + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "const": "shell:default" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute" + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + } + ] + } + } + }, + "then": { + "properties": { + "allow": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + }, + "deny": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + } + } + }, "properties": { "identifier": { - "oneOf": [ + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", - "type": "string", - "enum": [ - "shell:default" - ] - }, + "$ref": "#/definitions/Identifier" + } + ] + } + } + }, + { + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-execute" - ] - }, - { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-kill" - ] - }, - { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-open" - ] - }, - { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-spawn" - ] - }, - { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] - }, - { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-execute" - ] - }, - { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-kill" - ] - }, - { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-open" - ] - }, - { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-spawn" - ] - }, - { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "$ref": "#/definitions/Identifier" } ] }, "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } }, "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } } } } + ], + "required": [ + "identifier" ] } ] }, "Identifier": { + "description": "Permission identifier", "oneOf": [ { - "description": "clipboard-manager:default -> No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", + "description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", "type": "string", - "enum": [ - "clipboard-manager:default" - ] + "const": "clipboard-manager:default" }, { - "description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.", + "description": "Enables the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-clear" - ] + "const": "clipboard-manager:allow-clear" }, { - "description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.", + "description": "Enables the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-image" - ] + "const": "clipboard-manager:allow-read-image" }, { - "description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.", + "description": "Enables the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-text" - ] + "const": "clipboard-manager:allow-read-text" }, { - "description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.", + "description": "Enables the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-html" - ] + "const": "clipboard-manager:allow-write-html" }, { - "description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.", + "description": "Enables the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-image" - ] + "const": "clipboard-manager:allow-write-image" }, { - "description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.", + "description": "Enables the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-text" - ] + "const": "clipboard-manager:allow-write-text" }, { - "description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.", + "description": "Denies the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-clear" - ] + "const": "clipboard-manager:deny-clear" }, { - "description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.", + "description": "Denies the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-image" - ] + "const": "clipboard-manager:deny-read-image" }, { - "description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.", + "description": "Denies the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-text" - ] + "const": "clipboard-manager:deny-read-text" }, { - "description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.", + "description": "Denies the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-html" - ] + "const": "clipboard-manager:deny-write-html" }, { - "description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.", + "description": "Denies the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-image" - ] + "const": "clipboard-manager:deny-write-image" }, { - "description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.", + "description": "Denies the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-text" - ] + "const": "clipboard-manager:deny-write-text" }, { - "description": "core:app:default -> Default permissions for the plugin.", + "description": "Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n", "type": "string", - "enum": [ - "core:app:default" - ] + "const": "core:default" }, { - "description": "core:app:allow-app-hide -> Enables the app_hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:app:allow-app-hide" - ] + "const": "core:app:default" }, { - "description": "core:app:allow-app-show -> Enables the app_show command without any pre-configured scope.", + "description": "Enables the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-app-show" - ] + "const": "core:app:allow-app-hide" }, { - "description": "core:app:allow-default-window-icon -> Enables the default_window_icon command without any pre-configured scope.", + "description": "Enables the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-default-window-icon" - ] + "const": "core:app:allow-app-show" }, { - "description": "core:app:allow-name -> Enables the name command without any pre-configured scope.", + "description": "Enables the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-name" - ] + "const": "core:app:allow-default-window-icon" }, { - "description": "core:app:allow-tauri-version -> Enables the tauri_version command without any pre-configured scope.", + "description": "Enables the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-tauri-version" - ] + "const": "core:app:allow-name" }, { - "description": "core:app:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Enables the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-version" - ] + "const": "core:app:allow-set-app-theme" }, { - "description": "core:app:deny-app-hide -> Denies the app_hide command without any pre-configured scope.", + "description": "Enables the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-hide" - ] + "const": "core:app:allow-tauri-version" }, { - "description": "core:app:deny-app-show -> Denies the app_show command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-show" - ] + "const": "core:app:allow-version" }, { - "description": "core:app:deny-default-window-icon -> Denies the default_window_icon command without any pre-configured scope.", + "description": "Denies the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-default-window-icon" - ] + "const": "core:app:deny-app-hide" }, { - "description": "core:app:deny-name -> Denies the name command without any pre-configured scope.", + "description": "Denies the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-name" - ] + "const": "core:app:deny-app-show" }, { - "description": "core:app:deny-tauri-version -> Denies the tauri_version command without any pre-configured scope.", + "description": "Denies the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-tauri-version" - ] + "const": "core:app:deny-default-window-icon" }, { - "description": "core:app:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Denies the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-version" - ] + "const": "core:app:deny-name" }, { - "description": "core:event:default -> Default permissions for the plugin.", + "description": "Denies the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:default" - ] + "const": "core:app:deny-set-app-theme" }, { - "description": "core:event:allow-emit -> Enables the emit command without any pre-configured scope.", + "description": "Denies the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit" - ] + "const": "core:app:deny-tauri-version" }, { - "description": "core:event:allow-emit-to -> Enables the emit_to command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit-to" - ] + "const": "core:app:deny-version" }, { - "description": "core:event:allow-listen -> Enables the listen command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:event:allow-listen" - ] + "const": "core:event:default" }, { - "description": "core:event:allow-unlisten -> Enables the unlisten command without any pre-configured scope.", + "description": "Enables the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-unlisten" - ] + "const": "core:event:allow-emit" }, { - "description": "core:event:deny-emit -> Denies the emit command without any pre-configured scope.", + "description": "Enables the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit" - ] + "const": "core:event:allow-emit-to" }, { - "description": "core:event:deny-emit-to -> Denies the emit_to command without any pre-configured scope.", + "description": "Enables the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit-to" - ] + "const": "core:event:allow-listen" }, { - "description": "core:event:deny-listen -> Denies the listen command without any pre-configured scope.", + "description": "Enables the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-listen" - ] + "const": "core:event:allow-unlisten" }, { - "description": "core:event:deny-unlisten -> Denies the unlisten command without any pre-configured scope.", + "description": "Denies the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-unlisten" - ] + "const": "core:event:deny-emit" }, { - "description": "core:image:default -> Default permissions for the plugin.", + "description": "Denies the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:default" - ] + "const": "core:event:deny-emit-to" }, { - "description": "core:image:allow-from-bytes -> Enables the from_bytes command without any pre-configured scope.", + "description": "Denies the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-bytes" - ] + "const": "core:event:deny-listen" }, { - "description": "core:image:allow-from-path -> Enables the from_path command without any pre-configured scope.", + "description": "Denies the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-path" - ] + "const": "core:event:deny-unlisten" }, { - "description": "core:image:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:image:allow-new" - ] + "const": "core:image:default" }, { - "description": "core:image:allow-rgba -> Enables the rgba command without any pre-configured scope.", + "description": "Enables the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-rgba" - ] + "const": "core:image:allow-from-bytes" }, { - "description": "core:image:allow-size -> Enables the size command without any pre-configured scope.", + "description": "Enables the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-size" - ] + "const": "core:image:allow-from-path" }, { - "description": "core:image:deny-from-bytes -> Denies the from_bytes command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-bytes" - ] + "const": "core:image:allow-new" }, { - "description": "core:image:deny-from-path -> Denies the from_path command without any pre-configured scope.", + "description": "Enables the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-path" - ] + "const": "core:image:allow-rgba" }, { - "description": "core:image:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-new" - ] + "const": "core:image:allow-size" }, { - "description": "core:image:deny-rgba -> Denies the rgba command without any pre-configured scope.", + "description": "Denies the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-rgba" - ] + "const": "core:image:deny-from-bytes" }, { - "description": "core:image:deny-size -> Denies the size command without any pre-configured scope.", + "description": "Denies the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-size" - ] + "const": "core:image:deny-from-path" }, { - "description": "core:menu:default -> Default permissions for the plugin.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:default" - ] + "const": "core:image:deny-new" }, { - "description": "core:menu:allow-append -> Enables the append command without any pre-configured scope.", + "description": "Denies the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-append" - ] + "const": "core:image:deny-rgba" }, { - "description": "core:menu:allow-create-default -> Enables the create_default command without any pre-configured scope.", + "description": "Denies the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-create-default" - ] + "const": "core:image:deny-size" }, { - "description": "core:menu:allow-get -> Enables the get command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:menu:allow-get" - ] + "const": "core:menu:default" }, { - "description": "core:menu:allow-insert -> Enables the insert command without any pre-configured scope.", + "description": "Enables the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-insert" - ] + "const": "core:menu:allow-append" }, { - "description": "core:menu:allow-is-checked -> Enables the is_checked command without any pre-configured scope.", + "description": "Enables the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-checked" - ] + "const": "core:menu:allow-create-default" }, { - "description": "core:menu:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "description": "Enables the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-enabled" - ] + "const": "core:menu:allow-get" }, { - "description": "core:menu:allow-items -> Enables the items command without any pre-configured scope.", + "description": "Enables the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-items" - ] + "const": "core:menu:allow-insert" }, { - "description": "core:menu:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Enables the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-new" - ] + "const": "core:menu:allow-is-checked" }, { - "description": "core:menu:allow-popup -> Enables the popup command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-popup" - ] + "const": "core:menu:allow-is-enabled" }, { - "description": "core:menu:allow-prepend -> Enables the prepend command without any pre-configured scope.", + "description": "Enables the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-prepend" - ] + "const": "core:menu:allow-items" }, { - "description": "core:menu:allow-remove -> Enables the remove command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove" - ] + "const": "core:menu:allow-new" }, { - "description": "core:menu:allow-remove-at -> Enables the remove_at command without any pre-configured scope.", + "description": "Enables the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove-at" - ] + "const": "core:menu:allow-popup" }, { - "description": "core:menu:allow-set-accelerator -> Enables the set_accelerator command without any pre-configured scope.", + "description": "Enables the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-accelerator" - ] + "const": "core:menu:allow-prepend" }, { - "description": "core:menu:allow-set-as-app-menu -> Enables the set_as_app_menu command without any pre-configured scope.", + "description": "Enables the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-app-menu" - ] + "const": "core:menu:allow-remove" }, { - "description": "core:menu:allow-set-as-help-menu-for-nsapp -> Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:allow-remove-at" }, { - "description": "core:menu:allow-set-as-window-menu -> Enables the set_as_window_menu command without any pre-configured scope.", + "description": "Enables the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-window-menu" - ] + "const": "core:menu:allow-set-accelerator" }, { - "description": "core:menu:allow-set-as-windows-menu-for-nsapp -> Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:allow-set-as-app-menu" }, { - "description": "core:menu:allow-set-checked -> Enables the set_checked command without any pre-configured scope.", + "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-checked" - ] + "const": "core:menu:allow-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:allow-set-enabled -> Enables the set_enabled command without any pre-configured scope.", + "description": "Enables the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-enabled" - ] + "const": "core:menu:allow-set-as-window-menu" }, { - "description": "core:menu:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-icon" - ] + "const": "core:menu:allow-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:allow-set-text -> Enables the set_text command without any pre-configured scope.", + "description": "Enables the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-text" - ] + "const": "core:menu:allow-set-checked" }, { - "description": "core:menu:allow-text -> Enables the text command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-text" - ] + "const": "core:menu:allow-set-enabled" }, { - "description": "core:menu:deny-append -> Denies the append command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-append" - ] + "const": "core:menu:allow-set-icon" }, { - "description": "core:menu:deny-create-default -> Denies the create_default command without any pre-configured scope.", + "description": "Enables the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-create-default" - ] + "const": "core:menu:allow-set-text" }, { - "description": "core:menu:deny-get -> Denies the get command without any pre-configured scope.", + "description": "Enables the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-get" - ] + "const": "core:menu:allow-text" }, { - "description": "core:menu:deny-insert -> Denies the insert command without any pre-configured scope.", + "description": "Denies the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-insert" - ] + "const": "core:menu:deny-append" }, { - "description": "core:menu:deny-is-checked -> Denies the is_checked command without any pre-configured scope.", + "description": "Denies the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-checked" - ] + "const": "core:menu:deny-create-default" }, { - "description": "core:menu:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "description": "Denies the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-enabled" - ] + "const": "core:menu:deny-get" }, { - "description": "core:menu:deny-items -> Denies the items command without any pre-configured scope.", + "description": "Denies the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-items" - ] + "const": "core:menu:deny-insert" }, { - "description": "core:menu:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Denies the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-new" - ] + "const": "core:menu:deny-is-checked" }, { - "description": "core:menu:deny-popup -> Denies the popup command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-popup" - ] + "const": "core:menu:deny-is-enabled" }, { - "description": "core:menu:deny-prepend -> Denies the prepend command without any pre-configured scope.", + "description": "Denies the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-prepend" - ] + "const": "core:menu:deny-items" }, { - "description": "core:menu:deny-remove -> Denies the remove command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove" - ] + "const": "core:menu:deny-new" }, { - "description": "core:menu:deny-remove-at -> Denies the remove_at command without any pre-configured scope.", + "description": "Denies the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove-at" - ] + "const": "core:menu:deny-popup" }, { - "description": "core:menu:deny-set-accelerator -> Denies the set_accelerator command without any pre-configured scope.", + "description": "Denies the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-accelerator" - ] + "const": "core:menu:deny-prepend" }, { - "description": "core:menu:deny-set-as-app-menu -> Denies the set_as_app_menu command without any pre-configured scope.", + "description": "Denies the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-app-menu" - ] + "const": "core:menu:deny-remove" }, { - "description": "core:menu:deny-set-as-help-menu-for-nsapp -> Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:deny-remove-at" }, { - "description": "core:menu:deny-set-as-window-menu -> Denies the set_as_window_menu command without any pre-configured scope.", + "description": "Denies the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-window-menu" - ] + "const": "core:menu:deny-set-accelerator" }, { - "description": "core:menu:deny-set-as-windows-menu-for-nsapp -> Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:deny-set-as-app-menu" }, { - "description": "core:menu:deny-set-checked -> Denies the set_checked command without any pre-configured scope.", + "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-checked" - ] + "const": "core:menu:deny-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:deny-set-enabled -> Denies the set_enabled command without any pre-configured scope.", + "description": "Denies the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-enabled" - ] + "const": "core:menu:deny-set-as-window-menu" }, { - "description": "core:menu:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-icon" - ] + "const": "core:menu:deny-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:deny-set-text -> Denies the set_text command without any pre-configured scope.", + "description": "Denies the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-text" - ] + "const": "core:menu:deny-set-checked" }, { - "description": "core:menu:deny-text -> Denies the text command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-text" - ] + "const": "core:menu:deny-set-enabled" }, { - "description": "core:path:default -> Default permissions for the plugin.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:default" - ] + "const": "core:menu:deny-set-icon" }, { - "description": "core:path:allow-basename -> Enables the basename command without any pre-configured scope.", + "description": "Denies the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-basename" - ] + "const": "core:menu:deny-set-text" }, { - "description": "core:path:allow-dirname -> Enables the dirname command without any pre-configured scope.", + "description": "Denies the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-dirname" - ] + "const": "core:menu:deny-text" }, { - "description": "core:path:allow-extname -> Enables the extname command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:path:allow-extname" - ] + "const": "core:path:default" }, { - "description": "core:path:allow-is-absolute -> Enables the is_absolute command without any pre-configured scope.", + "description": "Enables the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-is-absolute" - ] + "const": "core:path:allow-basename" }, { - "description": "core:path:allow-join -> Enables the join command without any pre-configured scope.", + "description": "Enables the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-join" - ] + "const": "core:path:allow-dirname" }, { - "description": "core:path:allow-normalize -> Enables the normalize command without any pre-configured scope.", + "description": "Enables the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-normalize" - ] + "const": "core:path:allow-extname" }, { - "description": "core:path:allow-resolve -> Enables the resolve command without any pre-configured scope.", + "description": "Enables the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve" - ] + "const": "core:path:allow-is-absolute" }, { - "description": "core:path:allow-resolve-directory -> Enables the resolve_directory command without any pre-configured scope.", + "description": "Enables the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve-directory" - ] + "const": "core:path:allow-join" }, { - "description": "core:path:deny-basename -> Denies the basename command without any pre-configured scope.", + "description": "Enables the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-basename" - ] + "const": "core:path:allow-normalize" }, { - "description": "core:path:deny-dirname -> Denies the dirname command without any pre-configured scope.", + "description": "Enables the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-dirname" - ] + "const": "core:path:allow-resolve" }, { - "description": "core:path:deny-extname -> Denies the extname command without any pre-configured scope.", + "description": "Enables the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-extname" - ] + "const": "core:path:allow-resolve-directory" }, { - "description": "core:path:deny-is-absolute -> Denies the is_absolute command without any pre-configured scope.", + "description": "Denies the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-is-absolute" - ] + "const": "core:path:deny-basename" }, { - "description": "core:path:deny-join -> Denies the join command without any pre-configured scope.", + "description": "Denies the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-join" - ] + "const": "core:path:deny-dirname" }, { - "description": "core:path:deny-normalize -> Denies the normalize command without any pre-configured scope.", + "description": "Denies the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-normalize" - ] + "const": "core:path:deny-extname" }, { - "description": "core:path:deny-resolve -> Denies the resolve command without any pre-configured scope.", + "description": "Denies the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve" - ] + "const": "core:path:deny-is-absolute" }, { - "description": "core:path:deny-resolve-directory -> Denies the resolve_directory command without any pre-configured scope.", + "description": "Denies the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve-directory" - ] + "const": "core:path:deny-join" }, { - "description": "core:resources:default -> Default permissions for the plugin.", + "description": "Denies the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:default" - ] + "const": "core:path:deny-normalize" }, { - "description": "core:resources:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:allow-close" - ] + "const": "core:path:deny-resolve" }, { - "description": "core:resources:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Denies the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:deny-close" - ] + "const": "core:path:deny-resolve-directory" }, { - "description": "core:tray:default -> Default permissions for the plugin.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:default" - ] + "const": "core:resources:default" }, { - "description": "core:tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-get-by-id" - ] + "const": "core:resources:allow-close" }, { - "description": "core:tray:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-new" - ] + "const": "core:resources:deny-close" }, { - "description": "core:tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:allow-remove-by-id" - ] + "const": "core:tray:default" }, { - "description": "core:tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon" - ] + "const": "core:tray:allow-get-by-id" }, { - "description": "core:tray:allow-set-icon-as-template -> Enables the set_icon_as_template command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon-as-template" - ] + "const": "core:tray:allow-new" }, { - "description": "core:tray:allow-set-menu -> Enables the set_menu command without any pre-configured scope.", + "description": "Enables the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-menu" - ] + "const": "core:tray:allow-remove-by-id" }, { - "description": "core:tray:allow-set-show-menu-on-left-click -> Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-show-menu-on-left-click" - ] + "const": "core:tray:allow-set-icon" }, { - "description": "core:tray:allow-set-temp-dir-path -> Enables the set_temp_dir_path command without any pre-configured scope.", + "description": "Enables the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-temp-dir-path" - ] + "const": "core:tray:allow-set-icon-as-template" }, { - "description": "core:tray:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-title" - ] + "const": "core:tray:allow-set-menu" }, { - "description": "core:tray:allow-set-tooltip -> Enables the set_tooltip command without any pre-configured scope.", + "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-tooltip" - ] + "const": "core:tray:allow-set-show-menu-on-left-click" }, { - "description": "core:tray:allow-set-visible -> Enables the set_visible command without any pre-configured scope.", + "description": "Enables the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-visible" - ] + "const": "core:tray:allow-set-temp-dir-path" }, { - "description": "core:tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-get-by-id" - ] + "const": "core:tray:allow-set-title" }, { - "description": "core:tray:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-new" - ] + "const": "core:tray:allow-set-tooltip" }, { - "description": "core:tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.", + "description": "Enables the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-remove-by-id" - ] + "const": "core:tray:allow-set-visible" }, { - "description": "core:tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon" - ] + "const": "core:tray:deny-get-by-id" }, { - "description": "core:tray:deny-set-icon-as-template -> Denies the set_icon_as_template command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon-as-template" - ] + "const": "core:tray:deny-new" }, { - "description": "core:tray:deny-set-menu -> Denies the set_menu command without any pre-configured scope.", + "description": "Denies the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-menu" - ] + "const": "core:tray:deny-remove-by-id" }, { - "description": "core:tray:deny-set-show-menu-on-left-click -> Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-show-menu-on-left-click" - ] + "const": "core:tray:deny-set-icon" }, { - "description": "core:tray:deny-set-temp-dir-path -> Denies the set_temp_dir_path command without any pre-configured scope.", + "description": "Denies the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-temp-dir-path" - ] + "const": "core:tray:deny-set-icon-as-template" }, { - "description": "core:tray:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-title" - ] + "const": "core:tray:deny-set-menu" }, { - "description": "core:tray:deny-set-tooltip -> Denies the set_tooltip command without any pre-configured scope.", + "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-tooltip" - ] + "const": "core:tray:deny-set-show-menu-on-left-click" }, { - "description": "core:tray:deny-set-visible -> Denies the set_visible command without any pre-configured scope.", + "description": "Denies the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-visible" - ] + "const": "core:tray:deny-set-temp-dir-path" }, { - "description": "core:webview:default -> Default permissions for the plugin.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:default" - ] + "const": "core:tray:deny-set-title" }, { - "description": "core:webview:allow-create-webview -> Enables the create_webview command without any pre-configured scope.", + "description": "Denies the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview" - ] + "const": "core:tray:deny-set-tooltip" }, { - "description": "core:webview:allow-create-webview-window -> Enables the create_webview_window command without any pre-configured scope.", + "description": "Denies the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview-window" - ] + "const": "core:tray:deny-set-visible" }, { - "description": "core:webview:allow-get-all-webviews -> Enables the get_all_webviews command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:webview:allow-get-all-webviews" - ] + "const": "core:webview:default" }, { - "description": "core:webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-internal-toggle-devtools" - ] + "const": "core:webview:allow-clear-all-browsing-data" }, { - "description": "core:webview:allow-print -> Enables the print command without any pre-configured scope.", + "description": "Enables the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-print" - ] + "const": "core:webview:allow-create-webview" }, { - "description": "core:webview:allow-reparent -> Enables the reparent command without any pre-configured scope.", + "description": "Enables the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-reparent" - ] + "const": "core:webview:allow-create-webview-window" }, { - "description": "core:webview:allow-set-webview-focus -> Enables the set_webview_focus command without any pre-configured scope.", + "description": "Enables the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-focus" - ] + "const": "core:webview:allow-get-all-webviews" }, { - "description": "core:webview:allow-set-webview-position -> Enables the set_webview_position command without any pre-configured scope.", + "description": "Enables the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-position" - ] + "const": "core:webview:allow-internal-toggle-devtools" }, { - "description": "core:webview:allow-set-webview-size -> Enables the set_webview_size command without any pre-configured scope.", + "description": "Enables the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-size" - ] + "const": "core:webview:allow-print" }, { - "description": "core:webview:allow-set-webview-zoom -> Enables the set_webview_zoom command without any pre-configured scope.", + "description": "Enables the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-zoom" - ] + "const": "core:webview:allow-reparent" }, { - "description": "core:webview:allow-webview-close -> Enables the webview_close command without any pre-configured scope.", + "description": "Enables the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-close" - ] + "const": "core:webview:allow-set-webview-focus" }, { - "description": "core:webview:allow-webview-position -> Enables the webview_position command without any pre-configured scope.", + "description": "Enables the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-position" - ] + "const": "core:webview:allow-set-webview-position" }, { - "description": "core:webview:allow-webview-size -> Enables the webview_size command without any pre-configured scope.", + "description": "Enables the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-size" - ] + "const": "core:webview:allow-set-webview-size" }, { - "description": "core:webview:deny-create-webview -> Denies the create_webview command without any pre-configured scope.", + "description": "Enables the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview" - ] + "const": "core:webview:allow-set-webview-zoom" }, { - "description": "core:webview:deny-create-webview-window -> Denies the create_webview_window command without any pre-configured scope.", + "description": "Enables the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview-window" - ] + "const": "core:webview:allow-webview-close" }, { - "description": "core:webview:deny-get-all-webviews -> Denies the get_all_webviews command without any pre-configured scope.", + "description": "Enables the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-get-all-webviews" - ] + "const": "core:webview:allow-webview-hide" }, { - "description": "core:webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-internal-toggle-devtools" - ] + "const": "core:webview:allow-webview-position" }, { - "description": "core:webview:deny-print -> Denies the print command without any pre-configured scope.", + "description": "Enables the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-print" - ] + "const": "core:webview:allow-webview-show" }, { - "description": "core:webview:deny-reparent -> Denies the reparent command without any pre-configured scope.", + "description": "Enables the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-reparent" - ] + "const": "core:webview:allow-webview-size" }, { - "description": "core:webview:deny-set-webview-focus -> Denies the set_webview_focus command without any pre-configured scope.", + "description": "Denies the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-focus" - ] + "const": "core:webview:deny-clear-all-browsing-data" }, { - "description": "core:webview:deny-set-webview-position -> Denies the set_webview_position command without any pre-configured scope.", + "description": "Denies the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-position" - ] + "const": "core:webview:deny-create-webview" }, { - "description": "core:webview:deny-set-webview-size -> Denies the set_webview_size command without any pre-configured scope.", + "description": "Denies the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-size" - ] + "const": "core:webview:deny-create-webview-window" }, { - "description": "core:webview:deny-set-webview-zoom -> Denies the set_webview_zoom command without any pre-configured scope.", + "description": "Denies the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-zoom" - ] + "const": "core:webview:deny-get-all-webviews" }, { - "description": "core:webview:deny-webview-close -> Denies the webview_close command without any pre-configured scope.", + "description": "Denies the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-close" - ] + "const": "core:webview:deny-internal-toggle-devtools" }, { - "description": "core:webview:deny-webview-position -> Denies the webview_position command without any pre-configured scope.", + "description": "Denies the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-position" - ] + "const": "core:webview:deny-print" }, { - "description": "core:webview:deny-webview-size -> Denies the webview_size command without any pre-configured scope.", + "description": "Denies the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-size" - ] + "const": "core:webview:deny-reparent" }, { - "description": "core:window:default -> Default permissions for the plugin.", + "description": "Denies the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:default" - ] + "const": "core:webview:deny-set-webview-focus" }, { - "description": "core:window:allow-available-monitors -> Enables the available_monitors command without any pre-configured scope.", + "description": "Denies the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-available-monitors" - ] + "const": "core:webview:deny-set-webview-position" }, { - "description": "core:window:allow-center -> Enables the center command without any pre-configured scope.", + "description": "Denies the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-center" - ] + "const": "core:webview:deny-set-webview-size" }, { - "description": "core:window:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-close" - ] + "const": "core:webview:deny-set-webview-zoom" }, { - "description": "core:window:allow-create -> Enables the create command without any pre-configured scope.", + "description": "Denies the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-create" - ] + "const": "core:webview:deny-webview-close" }, { - "description": "core:window:allow-current-monitor -> Enables the current_monitor command without any pre-configured scope.", + "description": "Denies the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-current-monitor" - ] + "const": "core:webview:deny-webview-hide" }, { - "description": "core:window:allow-cursor-position -> Enables the cursor_position command without any pre-configured scope.", + "description": "Denies the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-cursor-position" - ] + "const": "core:webview:deny-webview-position" }, { - "description": "core:window:allow-destroy -> Enables the destroy command without any pre-configured scope.", + "description": "Denies the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-destroy" - ] + "const": "core:webview:deny-webview-show" }, { - "description": "core:window:allow-get-all-windows -> Enables the get_all_windows command without any pre-configured scope.", + "description": "Denies the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-get-all-windows" - ] + "const": "core:webview:deny-webview-size" }, { - "description": "core:window:allow-hide -> Enables the hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:window:allow-hide" - ] + "const": "core:window:default" }, { - "description": "core:window:allow-inner-position -> Enables the inner_position command without any pre-configured scope.", + "description": "Enables the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-position" - ] + "const": "core:window:allow-available-monitors" }, { - "description": "core:window:allow-inner-size -> Enables the inner_size command without any pre-configured scope.", + "description": "Enables the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-size" - ] + "const": "core:window:allow-center" }, { - "description": "core:window:allow-internal-toggle-maximize -> Enables the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-internal-toggle-maximize" - ] + "const": "core:window:allow-close" }, { - "description": "core:window:allow-is-closable -> Enables the is_closable command without any pre-configured scope.", + "description": "Enables the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-closable" - ] + "const": "core:window:allow-create" }, { - "description": "core:window:allow-is-decorated -> Enables the is_decorated command without any pre-configured scope.", + "description": "Enables the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-decorated" - ] + "const": "core:window:allow-current-monitor" }, { - "description": "core:window:allow-is-focused -> Enables the is_focused command without any pre-configured scope.", + "description": "Enables the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-focused" - ] + "const": "core:window:allow-cursor-position" }, { - "description": "core:window:allow-is-fullscreen -> Enables the is_fullscreen command without any pre-configured scope.", + "description": "Enables the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-fullscreen" - ] + "const": "core:window:allow-destroy" }, { - "description": "core:window:allow-is-maximizable -> Enables the is_maximizable command without any pre-configured scope.", + "description": "Enables the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximizable" - ] + "const": "core:window:allow-get-all-windows" }, { - "description": "core:window:allow-is-maximized -> Enables the is_maximized command without any pre-configured scope.", + "description": "Enables the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximized" - ] + "const": "core:window:allow-hide" }, { - "description": "core:window:allow-is-minimizable -> Enables the is_minimizable command without any pre-configured scope.", + "description": "Enables the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimizable" - ] + "const": "core:window:allow-inner-position" }, { - "description": "core:window:allow-is-minimized -> Enables the is_minimized command without any pre-configured scope.", + "description": "Enables the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimized" - ] + "const": "core:window:allow-inner-size" }, { - "description": "core:window:allow-is-resizable -> Enables the is_resizable command without any pre-configured scope.", + "description": "Enables the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-resizable" - ] + "const": "core:window:allow-internal-toggle-maximize" }, { - "description": "core:window:allow-is-visible -> Enables the is_visible command without any pre-configured scope.", + "description": "Enables the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-visible" - ] + "const": "core:window:allow-is-closable" }, { - "description": "core:window:allow-maximize -> Enables the maximize command without any pre-configured scope.", + "description": "Enables the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-maximize" - ] + "const": "core:window:allow-is-decorated" }, { - "description": "core:window:allow-minimize -> Enables the minimize command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-minimize" - ] + "const": "core:window:allow-is-enabled" }, { - "description": "core:window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.", + "description": "Enables the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-monitor-from-point" - ] + "const": "core:window:allow-is-focused" }, { - "description": "core:window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.", + "description": "Enables the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-position" - ] + "const": "core:window:allow-is-fullscreen" }, { - "description": "core:window:allow-outer-size -> Enables the outer_size command without any pre-configured scope.", + "description": "Enables the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-size" - ] + "const": "core:window:allow-is-maximizable" }, { - "description": "core:window:allow-primary-monitor -> Enables the primary_monitor command without any pre-configured scope.", + "description": "Enables the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-primary-monitor" - ] + "const": "core:window:allow-is-maximized" }, { - "description": "core:window:allow-request-user-attention -> Enables the request_user_attention command without any pre-configured scope.", + "description": "Enables the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-request-user-attention" - ] + "const": "core:window:allow-is-minimizable" }, { - "description": "core:window:allow-scale-factor -> Enables the scale_factor command without any pre-configured scope.", + "description": "Enables the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-scale-factor" - ] + "const": "core:window:allow-is-minimized" }, { - "description": "core:window:allow-set-always-on-bottom -> Enables the set_always_on_bottom command without any pre-configured scope.", + "description": "Enables the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-bottom" - ] + "const": "core:window:allow-is-resizable" }, { - "description": "core:window:allow-set-always-on-top -> Enables the set_always_on_top command without any pre-configured scope.", + "description": "Enables the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-top" - ] + "const": "core:window:allow-is-visible" }, { - "description": "core:window:allow-set-closable -> Enables the set_closable command without any pre-configured scope.", + "description": "Enables the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-closable" - ] + "const": "core:window:allow-maximize" }, { - "description": "core:window:allow-set-content-protected -> Enables the set_content_protected command without any pre-configured scope.", + "description": "Enables the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-content-protected" - ] + "const": "core:window:allow-minimize" }, { - "description": "core:window:allow-set-cursor-grab -> Enables the set_cursor_grab command without any pre-configured scope.", + "description": "Enables the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-grab" - ] + "const": "core:window:allow-monitor-from-point" }, { - "description": "core:window:allow-set-cursor-icon -> Enables the set_cursor_icon command without any pre-configured scope.", + "description": "Enables the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-icon" - ] + "const": "core:window:allow-outer-position" }, { - "description": "core:window:allow-set-cursor-position -> Enables the set_cursor_position command without any pre-configured scope.", + "description": "Enables the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-position" - ] + "const": "core:window:allow-outer-size" }, { - "description": "core:window:allow-set-cursor-visible -> Enables the set_cursor_visible command without any pre-configured scope.", + "description": "Enables the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-visible" - ] + "const": "core:window:allow-primary-monitor" }, { - "description": "core:window:allow-set-decorations -> Enables the set_decorations command without any pre-configured scope.", + "description": "Enables the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-decorations" - ] + "const": "core:window:allow-request-user-attention" }, { - "description": "core:window:allow-set-effects -> Enables the set_effects command without any pre-configured scope.", + "description": "Enables the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-effects" - ] + "const": "core:window:allow-scale-factor" }, { - "description": "core:window:allow-set-focus -> Enables the set_focus command without any pre-configured scope.", + "description": "Enables the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-focus" - ] + "const": "core:window:allow-set-always-on-bottom" }, { - "description": "core:window:allow-set-fullscreen -> Enables the set_fullscreen command without any pre-configured scope.", + "description": "Enables the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-fullscreen" - ] + "const": "core:window:allow-set-always-on-top" }, { - "description": "core:window:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-icon" - ] + "const": "core:window:allow-set-closable" }, { - "description": "core:window:allow-set-ignore-cursor-events -> Enables the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Enables the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-ignore-cursor-events" - ] + "const": "core:window:allow-set-content-protected" }, { - "description": "core:window:allow-set-max-size -> Enables the set_max_size command without any pre-configured scope.", + "description": "Enables the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-max-size" - ] + "const": "core:window:allow-set-cursor-grab" }, { - "description": "core:window:allow-set-maximizable -> Enables the set_maximizable command without any pre-configured scope.", + "description": "Enables the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-maximizable" - ] + "const": "core:window:allow-set-cursor-icon" }, { - "description": "core:window:allow-set-min-size -> Enables the set_min_size command without any pre-configured scope.", + "description": "Enables the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-min-size" - ] + "const": "core:window:allow-set-cursor-position" }, { - "description": "core:window:allow-set-minimizable -> Enables the set_minimizable command without any pre-configured scope.", + "description": "Enables the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-minimizable" - ] + "const": "core:window:allow-set-cursor-visible" }, { - "description": "core:window:allow-set-position -> Enables the set_position command without any pre-configured scope.", + "description": "Enables the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-position" - ] + "const": "core:window:allow-set-decorations" }, { - "description": "core:window:allow-set-progress-bar -> Enables the set_progress_bar command without any pre-configured scope.", + "description": "Enables the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-progress-bar" - ] + "const": "core:window:allow-set-effects" }, { - "description": "core:window:allow-set-resizable -> Enables the set_resizable command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-resizable" - ] + "const": "core:window:allow-set-enabled" }, { - "description": "core:window:allow-set-shadow -> Enables the set_shadow command without any pre-configured scope.", + "description": "Enables the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-shadow" - ] + "const": "core:window:allow-set-focus" }, { - "description": "core:window:allow-set-size -> Enables the set_size command without any pre-configured scope.", + "description": "Enables the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size" - ] + "const": "core:window:allow-set-fullscreen" }, { - "description": "core:window:allow-set-size-constraints -> Enables the set_size_constraints command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size-constraints" - ] + "const": "core:window:allow-set-icon" }, { - "description": "core:window:allow-set-skip-taskbar -> Enables the set_skip_taskbar command without any pre-configured scope.", + "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-skip-taskbar" - ] + "const": "core:window:allow-set-ignore-cursor-events" }, { - "description": "core:window:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title" - ] + "const": "core:window:allow-set-max-size" }, { - "description": "core:window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.", + "description": "Enables the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title-bar-style" - ] + "const": "core:window:allow-set-maximizable" }, { - "description": "core:window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Enables the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-visible-on-all-workspaces" - ] + "const": "core:window:allow-set-min-size" }, { - "description": "core:window:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-show" - ] + "const": "core:window:allow-set-minimizable" }, { - "description": "core:window:allow-start-dragging -> Enables the start_dragging command without any pre-configured scope.", + "description": "Enables the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-dragging" - ] + "const": "core:window:allow-set-position" }, { - "description": "core:window:allow-start-resize-dragging -> Enables the start_resize_dragging command without any pre-configured scope.", + "description": "Enables the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-resize-dragging" - ] + "const": "core:window:allow-set-progress-bar" }, { - "description": "core:window:allow-theme -> Enables the theme command without any pre-configured scope.", + "description": "Enables the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-theme" - ] + "const": "core:window:allow-set-resizable" }, { - "description": "core:window:allow-title -> Enables the title command without any pre-configured scope.", + "description": "Enables the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-title" - ] + "const": "core:window:allow-set-shadow" }, { - "description": "core:window:allow-toggle-maximize -> Enables the toggle_maximize command without any pre-configured scope.", + "description": "Enables the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-toggle-maximize" - ] + "const": "core:window:allow-set-size" }, { - "description": "core:window:allow-unmaximize -> Enables the unmaximize command without any pre-configured scope.", + "description": "Enables the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unmaximize" - ] + "const": "core:window:allow-set-size-constraints" }, { - "description": "core:window:allow-unminimize -> Enables the unminimize command without any pre-configured scope.", + "description": "Enables the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unminimize" - ] + "const": "core:window:allow-set-skip-taskbar" }, { - "description": "core:window:deny-available-monitors -> Denies the available_monitors command without any pre-configured scope.", + "description": "Enables the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-available-monitors" - ] + "const": "core:window:allow-set-theme" }, { - "description": "core:window:deny-center -> Denies the center command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-center" - ] + "const": "core:window:allow-set-title" }, { - "description": "core:window:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Enables the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-close" - ] + "const": "core:window:allow-set-title-bar-style" }, { - "description": "core:window:deny-create -> Denies the create command without any pre-configured scope.", + "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-create" - ] + "const": "core:window:allow-set-visible-on-all-workspaces" }, { - "description": "core:window:deny-current-monitor -> Denies the current_monitor command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-current-monitor" - ] + "const": "core:window:allow-show" }, { - "description": "core:window:deny-cursor-position -> Denies the cursor_position command without any pre-configured scope.", + "description": "Enables the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-cursor-position" - ] + "const": "core:window:allow-start-dragging" }, { - "description": "core:window:deny-destroy -> Denies the destroy command without any pre-configured scope.", + "description": "Enables the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-destroy" - ] + "const": "core:window:allow-start-resize-dragging" }, { - "description": "core:window:deny-get-all-windows -> Denies the get_all_windows command without any pre-configured scope.", + "description": "Enables the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-get-all-windows" - ] + "const": "core:window:allow-theme" }, { - "description": "core:window:deny-hide -> Denies the hide command without any pre-configured scope.", + "description": "Enables the title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-hide" - ] + "const": "core:window:allow-title" }, { - "description": "core:window:deny-inner-position -> Denies the inner_position command without any pre-configured scope.", + "description": "Enables the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-position" - ] + "const": "core:window:allow-toggle-maximize" }, { - "description": "core:window:deny-inner-size -> Denies the inner_size command without any pre-configured scope.", + "description": "Enables the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-size" - ] + "const": "core:window:allow-unmaximize" }, { - "description": "core:window:deny-internal-toggle-maximize -> Denies the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-internal-toggle-maximize" - ] + "const": "core:window:allow-unminimize" }, { - "description": "core:window:deny-is-closable -> Denies the is_closable command without any pre-configured scope.", + "description": "Denies the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-closable" - ] + "const": "core:window:deny-available-monitors" }, { - "description": "core:window:deny-is-decorated -> Denies the is_decorated command without any pre-configured scope.", + "description": "Denies the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-decorated" - ] + "const": "core:window:deny-center" }, { - "description": "core:window:deny-is-focused -> Denies the is_focused command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-focused" - ] + "const": "core:window:deny-close" }, { - "description": "core:window:deny-is-fullscreen -> Denies the is_fullscreen command without any pre-configured scope.", + "description": "Denies the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-fullscreen" - ] + "const": "core:window:deny-create" }, { - "description": "core:window:deny-is-maximizable -> Denies the is_maximizable command without any pre-configured scope.", + "description": "Denies the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximizable" - ] + "const": "core:window:deny-current-monitor" }, { - "description": "core:window:deny-is-maximized -> Denies the is_maximized command without any pre-configured scope.", + "description": "Denies the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximized" - ] + "const": "core:window:deny-cursor-position" }, { - "description": "core:window:deny-is-minimizable -> Denies the is_minimizable command without any pre-configured scope.", + "description": "Denies the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimizable" - ] + "const": "core:window:deny-destroy" }, { - "description": "core:window:deny-is-minimized -> Denies the is_minimized command without any pre-configured scope.", + "description": "Denies the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimized" - ] + "const": "core:window:deny-get-all-windows" }, { - "description": "core:window:deny-is-resizable -> Denies the is_resizable command without any pre-configured scope.", + "description": "Denies the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-resizable" - ] + "const": "core:window:deny-hide" }, { - "description": "core:window:deny-is-visible -> Denies the is_visible command without any pre-configured scope.", + "description": "Denies the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-visible" - ] + "const": "core:window:deny-inner-position" }, { - "description": "core:window:deny-maximize -> Denies the maximize command without any pre-configured scope.", + "description": "Denies the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-maximize" - ] + "const": "core:window:deny-inner-size" }, { - "description": "core:window:deny-minimize -> Denies the minimize command without any pre-configured scope.", + "description": "Denies the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-minimize" - ] + "const": "core:window:deny-internal-toggle-maximize" }, { - "description": "core:window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.", + "description": "Denies the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-monitor-from-point" - ] + "const": "core:window:deny-is-closable" }, { - "description": "core:window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.", + "description": "Denies the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-position" - ] + "const": "core:window:deny-is-decorated" }, { - "description": "core:window:deny-outer-size -> Denies the outer_size command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-size" - ] + "const": "core:window:deny-is-enabled" }, { - "description": "core:window:deny-primary-monitor -> Denies the primary_monitor command without any pre-configured scope.", + "description": "Denies the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-primary-monitor" - ] + "const": "core:window:deny-is-focused" }, { - "description": "core:window:deny-request-user-attention -> Denies the request_user_attention command without any pre-configured scope.", + "description": "Denies the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-request-user-attention" - ] + "const": "core:window:deny-is-fullscreen" }, { - "description": "core:window:deny-scale-factor -> Denies the scale_factor command without any pre-configured scope.", + "description": "Denies the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-scale-factor" - ] + "const": "core:window:deny-is-maximizable" }, { - "description": "core:window:deny-set-always-on-bottom -> Denies the set_always_on_bottom command without any pre-configured scope.", + "description": "Denies the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-bottom" - ] + "const": "core:window:deny-is-maximized" }, { - "description": "core:window:deny-set-always-on-top -> Denies the set_always_on_top command without any pre-configured scope.", + "description": "Denies the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-top" - ] + "const": "core:window:deny-is-minimizable" }, { - "description": "core:window:deny-set-closable -> Denies the set_closable command without any pre-configured scope.", + "description": "Denies the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-closable" - ] + "const": "core:window:deny-is-minimized" }, { - "description": "core:window:deny-set-content-protected -> Denies the set_content_protected command without any pre-configured scope.", + "description": "Denies the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-content-protected" - ] + "const": "core:window:deny-is-resizable" }, { - "description": "core:window:deny-set-cursor-grab -> Denies the set_cursor_grab command without any pre-configured scope.", + "description": "Denies the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-grab" - ] + "const": "core:window:deny-is-visible" }, { - "description": "core:window:deny-set-cursor-icon -> Denies the set_cursor_icon command without any pre-configured scope.", + "description": "Denies the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-icon" - ] + "const": "core:window:deny-maximize" }, { - "description": "core:window:deny-set-cursor-position -> Denies the set_cursor_position command without any pre-configured scope.", + "description": "Denies the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-position" - ] + "const": "core:window:deny-minimize" }, { - "description": "core:window:deny-set-cursor-visible -> Denies the set_cursor_visible command without any pre-configured scope.", + "description": "Denies the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-visible" - ] + "const": "core:window:deny-monitor-from-point" }, { - "description": "core:window:deny-set-decorations -> Denies the set_decorations command without any pre-configured scope.", + "description": "Denies the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-decorations" - ] + "const": "core:window:deny-outer-position" }, { - "description": "core:window:deny-set-effects -> Denies the set_effects command without any pre-configured scope.", + "description": "Denies the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-effects" - ] + "const": "core:window:deny-outer-size" }, { - "description": "core:window:deny-set-focus -> Denies the set_focus command without any pre-configured scope.", + "description": "Denies the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-focus" - ] + "const": "core:window:deny-primary-monitor" }, { - "description": "core:window:deny-set-fullscreen -> Denies the set_fullscreen command without any pre-configured scope.", + "description": "Denies the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-fullscreen" - ] + "const": "core:window:deny-request-user-attention" }, { - "description": "core:window:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-icon" - ] + "const": "core:window:deny-scale-factor" }, { - "description": "core:window:deny-set-ignore-cursor-events -> Denies the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Denies the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-ignore-cursor-events" - ] + "const": "core:window:deny-set-always-on-bottom" }, { - "description": "core:window:deny-set-max-size -> Denies the set_max_size command without any pre-configured scope.", + "description": "Denies the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-max-size" - ] + "const": "core:window:deny-set-always-on-top" }, { - "description": "core:window:deny-set-maximizable -> Denies the set_maximizable command without any pre-configured scope.", + "description": "Denies the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-maximizable" - ] + "const": "core:window:deny-set-closable" }, { - "description": "core:window:deny-set-min-size -> Denies the set_min_size command without any pre-configured scope.", + "description": "Denies the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-min-size" - ] + "const": "core:window:deny-set-content-protected" }, { - "description": "core:window:deny-set-minimizable -> Denies the set_minimizable command without any pre-configured scope.", + "description": "Denies the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-minimizable" - ] + "const": "core:window:deny-set-cursor-grab" }, { - "description": "core:window:deny-set-position -> Denies the set_position command without any pre-configured scope.", + "description": "Denies the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-position" - ] + "const": "core:window:deny-set-cursor-icon" }, { - "description": "core:window:deny-set-progress-bar -> Denies the set_progress_bar command without any pre-configured scope.", + "description": "Denies the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-progress-bar" - ] + "const": "core:window:deny-set-cursor-position" }, { - "description": "core:window:deny-set-resizable -> Denies the set_resizable command without any pre-configured scope.", + "description": "Denies the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-resizable" - ] + "const": "core:window:deny-set-cursor-visible" }, { - "description": "core:window:deny-set-shadow -> Denies the set_shadow command without any pre-configured scope.", + "description": "Denies the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-shadow" - ] + "const": "core:window:deny-set-decorations" }, { - "description": "core:window:deny-set-size -> Denies the set_size command without any pre-configured scope.", + "description": "Denies the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size" - ] + "const": "core:window:deny-set-effects" }, { - "description": "core:window:deny-set-size-constraints -> Denies the set_size_constraints command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size-constraints" - ] + "const": "core:window:deny-set-enabled" }, { - "description": "core:window:deny-set-skip-taskbar -> Denies the set_skip_taskbar command without any pre-configured scope.", + "description": "Denies the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-skip-taskbar" - ] + "const": "core:window:deny-set-focus" }, { - "description": "core:window:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title" - ] + "const": "core:window:deny-set-fullscreen" }, { - "description": "core:window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title-bar-style" - ] + "const": "core:window:deny-set-icon" }, { - "description": "core:window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-visible-on-all-workspaces" - ] + "const": "core:window:deny-set-ignore-cursor-events" }, { - "description": "core:window:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-show" - ] + "const": "core:window:deny-set-max-size" }, { - "description": "core:window:deny-start-dragging -> Denies the start_dragging command without any pre-configured scope.", + "description": "Denies the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-dragging" - ] + "const": "core:window:deny-set-maximizable" }, { - "description": "core:window:deny-start-resize-dragging -> Denies the start_resize_dragging command without any pre-configured scope.", + "description": "Denies the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-resize-dragging" - ] + "const": "core:window:deny-set-min-size" }, { - "description": "core:window:deny-theme -> Denies the theme command without any pre-configured scope.", + "description": "Denies the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-theme" - ] + "const": "core:window:deny-set-minimizable" }, { - "description": "core:window:deny-title -> Denies the title command without any pre-configured scope.", + "description": "Denies the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-title" - ] + "const": "core:window:deny-set-position" }, { - "description": "core:window:deny-toggle-maximize -> Denies the toggle_maximize command without any pre-configured scope.", + "description": "Denies the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-toggle-maximize" - ] + "const": "core:window:deny-set-progress-bar" }, { - "description": "core:window:deny-unmaximize -> Denies the unmaximize command without any pre-configured scope.", + "description": "Denies the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unmaximize" - ] + "const": "core:window:deny-set-resizable" }, { - "description": "core:window:deny-unminimize -> Denies the unminimize command without any pre-configured scope.", + "description": "Denies the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unminimize" - ] + "const": "core:window:deny-set-shadow" }, { - "description": "dialog:default -> This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", + "description": "Denies the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:default" - ] + "const": "core:window:deny-set-size" }, { - "description": "dialog:allow-ask -> Enables the ask command without any pre-configured scope.", + "description": "Denies the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-ask" - ] + "const": "core:window:deny-set-size-constraints" }, { - "description": "dialog:allow-confirm -> Enables the confirm command without any pre-configured scope.", + "description": "Denies the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-confirm" - ] + "const": "core:window:deny-set-skip-taskbar" }, { - "description": "dialog:allow-message -> Enables the message command without any pre-configured scope.", + "description": "Denies the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-message" - ] + "const": "core:window:deny-set-theme" }, { - "description": "dialog:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-open" - ] + "const": "core:window:deny-set-title" }, { - "description": "dialog:allow-save -> Enables the save command without any pre-configured scope.", + "description": "Denies the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-save" - ] + "const": "core:window:deny-set-title-bar-style" }, { - "description": "dialog:deny-ask -> Denies the ask command without any pre-configured scope.", + "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-ask" - ] + "const": "core:window:deny-set-visible-on-all-workspaces" }, { - "description": "dialog:deny-confirm -> Denies the confirm command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-confirm" - ] + "const": "core:window:deny-show" }, { - "description": "dialog:deny-message -> Denies the message command without any pre-configured scope.", + "description": "Denies the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-message" - ] + "const": "core:window:deny-start-dragging" }, { - "description": "dialog:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-open" - ] + "const": "core:window:deny-start-resize-dragging" }, { - "description": "dialog:deny-save -> Denies the save command without any pre-configured scope.", + "description": "Denies the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-save" - ] + "const": "core:window:deny-theme" }, { - "description": "log:default -> Allows the log command", + "description": "Denies the title command without any pre-configured scope.", "type": "string", - "enum": [ - "log:default" - ] + "const": "core:window:deny-title" }, { - "description": "log:allow-log -> Enables the log command without any pre-configured scope.", + "description": "Denies the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:allow-log" - ] + "const": "core:window:deny-toggle-maximize" }, { - "description": "log:deny-log -> Denies the log command without any pre-configured scope.", + "description": "Denies the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:deny-log" - ] + "const": "core:window:deny-unmaximize" }, { - "description": "notification:default -> This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", + "description": "Denies the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:default" - ] + "const": "core:window:deny-unminimize" }, { - "description": "notification:allow-batch -> Enables the batch command without any pre-configured scope.", + "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", "type": "string", - "enum": [ - "notification:allow-batch" - ] + "const": "dialog:default" }, { - "description": "notification:allow-cancel -> Enables the cancel command without any pre-configured scope.", + "description": "Enables the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-cancel" - ] + "const": "dialog:allow-ask" }, { - "description": "notification:allow-check-permissions -> Enables the check_permissions command without any pre-configured scope.", + "description": "Enables the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-check-permissions" - ] + "const": "dialog:allow-confirm" }, { - "description": "notification:allow-create-channel -> Enables the create_channel command without any pre-configured scope.", + "description": "Enables the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-create-channel" - ] + "const": "dialog:allow-message" }, { - "description": "notification:allow-delete-channel -> Enables the delete_channel command without any pre-configured scope.", + "description": "Enables the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-delete-channel" - ] + "const": "dialog:allow-open" }, { - "description": "notification:allow-get-active -> Enables the get_active command without any pre-configured scope.", + "description": "Enables the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-active" - ] + "const": "dialog:allow-save" }, { - "description": "notification:allow-get-pending -> Enables the get_pending command without any pre-configured scope.", + "description": "Denies the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-pending" - ] + "const": "dialog:deny-ask" }, { - "description": "notification:allow-is-permission-granted -> Enables the is_permission_granted command without any pre-configured scope.", + "description": "Denies the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-is-permission-granted" - ] + "const": "dialog:deny-confirm" }, { - "description": "notification:allow-list-channels -> Enables the list_channels command without any pre-configured scope.", + "description": "Denies the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-list-channels" - ] + "const": "dialog:deny-message" }, { - "description": "notification:allow-notify -> Enables the notify command without any pre-configured scope.", + "description": "Denies the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-notify" - ] + "const": "dialog:deny-open" }, { - "description": "notification:allow-permission-state -> Enables the permission_state command without any pre-configured scope.", + "description": "Denies the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-permission-state" - ] + "const": "dialog:deny-save" }, { - "description": "notification:allow-register-action-types -> Enables the register_action_types command without any pre-configured scope.", + "description": "Allows the log command", "type": "string", - "enum": [ - "notification:allow-register-action-types" - ] + "const": "log:default" }, { - "description": "notification:allow-register-listener -> Enables the register_listener command without any pre-configured scope.", + "description": "Enables the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-register-listener" - ] + "const": "log:allow-log" }, { - "description": "notification:allow-remove-active -> Enables the remove_active command without any pre-configured scope.", + "description": "Denies the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-remove-active" - ] + "const": "log:deny-log" }, { - "description": "notification:allow-request-permission -> Enables the request_permission command without any pre-configured scope.", + "description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", "type": "string", - "enum": [ - "notification:allow-request-permission" - ] + "const": "notification:default" }, { - "description": "notification:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-show" - ] + "const": "notification:allow-batch" }, { - "description": "notification:deny-batch -> Denies the batch command without any pre-configured scope.", + "description": "Enables the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-batch" - ] + "const": "notification:allow-cancel" }, { - "description": "notification:deny-cancel -> Denies the cancel command without any pre-configured scope.", + "description": "Enables the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-cancel" - ] + "const": "notification:allow-check-permissions" }, { - "description": "notification:deny-check-permissions -> Denies the check_permissions command without any pre-configured scope.", + "description": "Enables the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-check-permissions" - ] + "const": "notification:allow-create-channel" }, { - "description": "notification:deny-create-channel -> Denies the create_channel command without any pre-configured scope.", + "description": "Enables the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-create-channel" - ] + "const": "notification:allow-delete-channel" }, { - "description": "notification:deny-delete-channel -> Denies the delete_channel command without any pre-configured scope.", + "description": "Enables the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-delete-channel" - ] + "const": "notification:allow-get-active" }, { - "description": "notification:deny-get-active -> Denies the get_active command without any pre-configured scope.", + "description": "Enables the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-active" - ] + "const": "notification:allow-get-pending" }, { - "description": "notification:deny-get-pending -> Denies the get_pending command without any pre-configured scope.", + "description": "Enables the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-pending" - ] + "const": "notification:allow-is-permission-granted" }, { - "description": "notification:deny-is-permission-granted -> Denies the is_permission_granted command without any pre-configured scope.", + "description": "Enables the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-is-permission-granted" - ] + "const": "notification:allow-list-channels" }, { - "description": "notification:deny-list-channels -> Denies the list_channels command without any pre-configured scope.", + "description": "Enables the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-list-channels" - ] + "const": "notification:allow-notify" }, { - "description": "notification:deny-notify -> Denies the notify command without any pre-configured scope.", + "description": "Enables the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-notify" - ] + "const": "notification:allow-permission-state" }, { - "description": "notification:deny-permission-state -> Denies the permission_state command without any pre-configured scope.", + "description": "Enables the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-permission-state" - ] + "const": "notification:allow-register-action-types" }, { - "description": "notification:deny-register-action-types -> Denies the register_action_types command without any pre-configured scope.", + "description": "Enables the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-action-types" - ] + "const": "notification:allow-register-listener" }, { - "description": "notification:deny-register-listener -> Denies the register_listener command without any pre-configured scope.", + "description": "Enables the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-listener" - ] + "const": "notification:allow-remove-active" }, { - "description": "notification:deny-remove-active -> Denies the remove_active command without any pre-configured scope.", + "description": "Enables the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-remove-active" - ] + "const": "notification:allow-request-permission" }, { - "description": "notification:deny-request-permission -> Denies the request_permission command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-request-permission" - ] + "const": "notification:allow-show" }, { - "description": "notification:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-show" - ] + "const": "notification:deny-batch" }, { - "description": "os:default -> This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", + "description": "Denies the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:default" - ] + "const": "notification:deny-cancel" }, { - "description": "os:allow-arch -> Enables the arch command without any pre-configured scope.", + "description": "Denies the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-arch" - ] + "const": "notification:deny-check-permissions" }, { - "description": "os:allow-exe-extension -> Enables the exe_extension command without any pre-configured scope.", + "description": "Denies the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-exe-extension" - ] + "const": "notification:deny-create-channel" }, { - "description": "os:allow-family -> Enables the family command without any pre-configured scope.", + "description": "Denies the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-family" - ] + "const": "notification:deny-delete-channel" }, { - "description": "os:allow-hostname -> Enables the hostname command without any pre-configured scope.", + "description": "Denies the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-hostname" - ] + "const": "notification:deny-get-active" }, { - "description": "os:allow-locale -> Enables the locale command without any pre-configured scope.", + "description": "Denies the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-locale" - ] + "const": "notification:deny-get-pending" }, { - "description": "os:allow-os-type -> Enables the os_type command without any pre-configured scope.", + "description": "Denies the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-os-type" - ] + "const": "notification:deny-is-permission-granted" }, { - "description": "os:allow-platform -> Enables the platform command without any pre-configured scope.", + "description": "Denies the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-platform" - ] + "const": "notification:deny-list-channels" }, { - "description": "os:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Denies the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-version" - ] + "const": "notification:deny-notify" }, { - "description": "os:deny-arch -> Denies the arch command without any pre-configured scope.", + "description": "Denies the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-arch" - ] + "const": "notification:deny-permission-state" }, { - "description": "os:deny-exe-extension -> Denies the exe_extension command without any pre-configured scope.", + "description": "Denies the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-exe-extension" - ] + "const": "notification:deny-register-action-types" }, { - "description": "os:deny-family -> Denies the family command without any pre-configured scope.", + "description": "Denies the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-family" - ] + "const": "notification:deny-register-listener" }, { - "description": "os:deny-hostname -> Denies the hostname command without any pre-configured scope.", + "description": "Denies the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-hostname" - ] + "const": "notification:deny-remove-active" }, { - "description": "os:deny-locale -> Denies the locale command without any pre-configured scope.", + "description": "Denies the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-locale" - ] + "const": "notification:deny-request-permission" }, { - "description": "os:deny-os-type -> Denies the os_type command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-os-type" - ] + "const": "notification:deny-show" }, { - "description": "os:deny-platform -> Denies the platform command without any pre-configured scope.", + "description": "This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", "type": "string", - "enum": [ - "os:deny-platform" - ] + "const": "os:default" }, { - "description": "os:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Enables the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-version" - ] + "const": "os:allow-arch" }, { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "description": "Enables the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:default" - ] + "const": "os:allow-exe-extension" }, { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "description": "Enables the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-execute" - ] + "const": "os:allow-family" }, { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "description": "Enables the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-kill" - ] + "const": "os:allow-hostname" }, { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Enables the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-open" - ] + "const": "os:allow-locale" }, { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "description": "Enables the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-spawn" - ] + "const": "os:allow-os-type" }, { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "description": "Enables the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] + "const": "os:allow-platform" }, { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-execute" - ] + "const": "os:allow-version" }, { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "description": "Denies the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-kill" - ] + "const": "os:deny-arch" }, { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-open" - ] + "const": "os:deny-exe-extension" }, { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "description": "Denies the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-spawn" - ] + "const": "os:deny-family" }, { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "description": "Denies the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "const": "os:deny-hostname" }, { - "description": "window-state:default -> This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "description": "Denies the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:default" - ] + "const": "os:deny-locale" }, { - "description": "window-state:allow-filename -> Enables the filename command without any pre-configured scope.", + "description": "Denies the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-filename" - ] + "const": "os:deny-os-type" }, { - "description": "window-state:allow-restore-state -> Enables the restore_state command without any pre-configured scope.", + "description": "Denies the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-restore-state" - ] + "const": "os:deny-platform" }, { - "description": "window-state:allow-save-window-state -> Enables the save_window_state command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-save-window-state" - ] + "const": "os:deny-version" }, { - "description": "window-state:deny-filename -> Denies the filename command without any pre-configured scope.", + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", "type": "string", - "enum": [ - "window-state:deny-filename" - ] + "const": "shell:default" }, { - "description": "window-state:deny-restore-state -> Denies the restore_state command without any pre-configured scope.", + "description": "Enables the execute command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-restore-state" - ] + "const": "shell:allow-execute" }, { - "description": "window-state:deny-save-window-state -> Denies the save_window_state command without any pre-configured scope.", + "description": "Enables the kill command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-save-window-state" - ] + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + }, + { + "description": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "type": "string", + "const": "window-state:default" + }, + { + "description": "Enables the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-filename" + }, + { + "description": "Enables the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-restore-state" + }, + { + "description": "Enables the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-save-window-state" + }, + { + "description": "Denies the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-filename" + }, + { + "description": "Denies the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-restore-state" + }, + { + "description": "Denies the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-save-window-state" } ] }, @@ -3027,7 +2426,7 @@ } ] }, - "ShellAllowedArg": { + "ShellScopeEntryAllowedArg": { "description": "A command argument allowed to be executed by the webview API.", "anyOf": [ { @@ -3055,18 +2454,18 @@ } ] }, - "ShellAllowedArgs": { - "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "ShellScopeEntryAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", "anyOf": [ { "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", "type": "boolean" }, { - "description": "A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.", + "description": "A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.", "type": "array", "items": { - "$ref": "#/definitions/ShellAllowedArg" + "$ref": "#/definitions/ShellScopeEntryAllowedArg" } } ] diff --git a/desktop/tauri/src-tauri/src/traymenu.rs b/desktop/tauri/src-tauri/src/traymenu.rs index 9d775475..0aef6fe7 100644 --- a/desktop/tauri/src-tauri/src/traymenu.rs +++ b/desktop/tauri/src-tauri/src/traymenu.rs @@ -29,7 +29,7 @@ use crate::{ portmaster::PortmasterExt, window::{create_main_window, may_navigate_to_ui, open_window}, }; -use tauri_plugin_dialog::DialogExt; +use tauri_plugin_dialog::{DialogExt, MessageDialogButtons}; pub type AppIcon = TrayIcon; @@ -199,8 +199,10 @@ pub fn setup_tray_menu( app.dialog() .message("This does not stop the Portmaster system service") .title("Do you really want to quit the user interface?") - .ok_button_label("Yes, exit") - .cancel_button_label("No") + .buttons(MessageDialogButtons::OkCancelCustom( + "Yes, exit".to_owned(), + "No".to_owned(), + )) .show(move |answer| { if answer { // let _ = handle.emit("exit-requested", ""); diff --git a/desktop/tauri/src-tauri/templates/main.wxs b/desktop/tauri/src-tauri/templates/main.wxs index 249eccf0..d1894ace 100644 --- a/desktop/tauri/src-tauri/templates/main.wxs +++ b/desktop/tauri/src-tauri/templates/main.wxs @@ -139,7 +139,7 @@ {{/each~}} - + {{#each file_associations as |association| ~}} {{#each association.ext as |ext| ~}} diff --git a/desktop/tauri/src-tauri/templates/main_original.wxs b/desktop/tauri/src-tauri/templates/main_original.wxs index 1b8116ed..b1d2672a 100644 --- a/desktop/tauri/src-tauri/templates/main_original.wxs +++ b/desktop/tauri/src-tauri/templates/main_original.wxs @@ -139,7 +139,7 @@ {{/each~}} - + {{#each file_associations as |association| ~}} {{#each association.ext as |ext| ~}} From 943b9b78591baa6c0b33f0453474030e2335d65c Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 26 Nov 2024 17:00:01 +0200 Subject: [PATCH 12/63] Fix file permissions on windows (#1758) * [service] Set file permissions on windows * [service] Fix minor windows permission bugs * [service] Fix permission bugs * [service] Fix windows non admin user start --- base/database/storage/fstree/fstree.go | 12 ++++++++---- base/updater/fetch.go | 8 +++++++- base/utils/fs.go | 15 ++++++++++++--- base/utils/renameio/writefile.go | 14 ++++++++++++-- cmds/portmaster-start/run.go | 2 +- go.mod | 1 + go.sum | 3 +++ service/updates/helper/electron.go | 2 +- service/updates/upgrader.go | 8 +++++++- 9 files changed, 52 insertions(+), 13 deletions(-) diff --git a/base/database/storage/fstree/fstree.go b/base/database/storage/fstree/fstree.go index 44cf384f..7965439a 100644 --- a/base/database/storage/fstree/fstree.go +++ b/base/database/storage/fstree/fstree.go @@ -15,6 +15,7 @@ import ( "strings" "time" + "github.com/hectane/go-acl" "github.com/safing/portmaster/base/database/iterator" "github.com/safing/portmaster/base/database/query" "github.com/safing/portmaster/base/database/record" @@ -288,10 +289,13 @@ func writeFile(filename string, data []byte, perm os.FileMode) error { defer t.Cleanup() //nolint:errcheck // Set permissions before writing data, in case the data is sensitive. - if !onWindows { - if err := t.Chmod(perm); err != nil { - return err - } + if onWindows { + err = acl.Chmod(filename, perm) + } else { + err = t.Chmod(perm) + } + if err != nil { + return err } if _, err := t.Write(data); err != nil { diff --git a/base/updater/fetch.go b/base/updater/fetch.go index f324709d..150037ed 100644 --- a/base/updater/fetch.go +++ b/base/updater/fetch.go @@ -14,6 +14,7 @@ import ( "path/filepath" "time" + "github.com/hectane/go-acl" "github.com/safing/jess/filesig" "github.com/safing/jess/lhash" "github.com/safing/portmaster/base/log" @@ -136,7 +137,12 @@ func (reg *ResourceRegistry) fetchFile(ctx context.Context, client *http.Client, return fmt.Errorf("%s: failed to finalize file %s: %w", reg.Name, rv.storagePath(), err) } // set permissions - if !onWindows { + if onWindows { + err = acl.Chmod(rv.storagePath(), 0o0755) + if err != nil { + log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err) + } + } else { // TODO: only set executable files to 0755, set other to 0644 err = os.Chmod(rv.storagePath(), 0o0755) //nolint:gosec // See TODO above. if err != nil { diff --git a/base/utils/fs.go b/base/utils/fs.go index b612a069..bb59960f 100644 --- a/base/utils/fs.go +++ b/base/utils/fs.go @@ -6,6 +6,8 @@ import ( "io/fs" "os" "runtime" + + "github.com/hectane/go-acl" ) const isWindows = runtime.GOOS == "windows" @@ -20,8 +22,9 @@ func EnsureDirectory(path string, perm os.FileMode) error { if f.IsDir() { // directory exists, check permissions if isWindows { - // TODO: set correct permission on windows - // acl.Chmod(path, perm) + // Ignore windows permission error. For none admin users it will always fail. + acl.Chmod(path, perm) + return nil } else if f.Mode().Perm() != perm { return os.Chmod(path, perm) } @@ -38,7 +41,13 @@ func EnsureDirectory(path string, perm os.FileMode) error { if err != nil { return fmt.Errorf("could not create dir %s: %w", path, err) } - return os.Chmod(path, perm) + if isWindows { + // Ignore windows permission error. For none admin users it will always fail. + acl.Chmod(path, perm) + return nil + } else { + return os.Chmod(path, perm) + } } // other error opening path return fmt.Errorf("failed to access %s: %w", path, err) diff --git a/base/utils/renameio/writefile.go b/base/utils/renameio/writefile.go index 21153025..073a1e1b 100644 --- a/base/utils/renameio/writefile.go +++ b/base/utils/renameio/writefile.go @@ -1,6 +1,11 @@ package renameio -import "os" +import ( + "os" + "runtime" + + "github.com/hectane/go-acl" +) // WriteFile mirrors os.WriteFile, replacing an existing file with the same // name atomically. @@ -14,7 +19,12 @@ func WriteFile(filename string, data []byte, perm os.FileMode) error { }() // Set permissions before writing data, in case the data is sensitive. - if err := t.Chmod(perm); err != nil { + if runtime.GOOS == "windows" { + err = acl.Chmod(t.path, perm) + } else { + err = t.Chmod(perm) + } + if err != nil { return err } diff --git a/cmds/portmaster-start/run.go b/cmds/portmaster-start/run.go index f807fd69..48ad36cb 100644 --- a/cmds/portmaster-start/run.go +++ b/cmds/portmaster-start/run.go @@ -272,7 +272,7 @@ func fixExecPerm(path string) error { return nil } - if err := os.Chmod(path, 0o0755); err != nil { //nolint:gosec // Set execution rights. + if err := os.Chmod(path, 0o0755); err != nil { //nolint:gosec return fmt.Errorf("failed to chmod %s: %w", path, err) } diff --git a/go.mod b/go.mod index 80685cce..d40c1410 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.7.0 + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb github.com/jackc/puddle/v2 v2.2.2 github.com/lmittmann/tint v1.0.5 github.com/maruel/panicparse/v2 v2.3.1 diff --git a/go.sum b/go.sum index 4a0cac3f..c2bfeae6 100644 --- a/go.sum +++ b/go.sum @@ -137,6 +137,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -388,6 +390,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/service/updates/helper/electron.go b/service/updates/helper/electron.go index 4c8c4a07..2fa6810b 100644 --- a/service/updates/helper/electron.go +++ b/service/updates/helper/electron.go @@ -48,9 +48,9 @@ func EnsureChromeSandboxPermissions(reg *updater.ResourceRegistry) error { sandboxFile := filepath.Join(unpackedPath, "chrome-sandbox") if err := os.Chmod(sandboxFile, 0o0755|os.ModeSetuid); err != nil { log.Errorf(suidBitWarning, 0o0755|os.ModeSetuid, sandboxFile) - return fmt.Errorf("failed to chmod: %w", err) } + log.Debugf("updates: fixed SUID permission for chrome-sandbox") return nil diff --git a/service/updates/upgrader.go b/service/updates/upgrader.go index 622b3909..4963bced 100644 --- a/service/updates/upgrader.go +++ b/service/updates/upgrader.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/hectane/go-acl" processInfo "github.com/shirou/gopsutil/process" "github.com/tevino/abool" @@ -349,7 +350,12 @@ func upgradeBinary(fileToUpgrade string, file *updater.File) error { } // check permissions - if !onWindows { + if onWindows { + err = acl.Chmod(fileToUpgrade, 0o0755) + if err != nil { + return fmt.Errorf("failed to set permissions on %s: %w", fileToUpgrade, err) + } + } else { info, err := os.Stat(fileToUpgrade) if err != nil { return fmt.Errorf("failed to get file info on %s: %w", fileToUpgrade, err) From 1a1bc14804491546c9d3375bf49c6869382b50b6 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Wed, 27 Nov 2024 17:10:47 +0200 Subject: [PATCH 13/63] Feature/systemd query events (#1728) * [service] Subscribe to systemd-resolver events * [service] Add disabled state to the resolver * [service] Add ETW DNS event listener * [service] DNS listener refactoring * [service] Add windows core dll project * [service] DNSListener refactoring, small bugfixes * [service] Change dns bypass rule * [service] Update gitignore * [service] Remove shim from integration module * [service] Add DNS packet analyzer * [service] Add self-check in dns monitor * [service] Fix go linter errors * [CI] Add github workflow for the windows core dll * [service] Minor fixes to the dns monitor --- .github/workflows/windows-dll.yml | 41 ++++ .gitignore | 1 + go.mod | 2 + go.sum | 2 + service/compat/module.go | 1 + service/compat/selfcheck.go | 6 + service/firewall/bypassing.go | 30 +++ service/firewall/dns.go | 54 +++-- .../dnsmonitor/etwlink_windows.go | 99 +++++++++ .../interception/dnsmonitor/eventlistener.go | 19 ++ .../dnsmonitor/eventlistener_linux.go | 144 +++++++++++++ .../dnsmonitor/eventlistener_windows.go | 103 +++++++++ .../interception/dnsmonitor/module.go | 138 ++++++++++++ .../interception/dnsmonitor/varlinktypes.go | 83 ++++++++ service/firewall/interception/nfq/nfq.go | 2 +- .../interception/windowskext/packet.go | 2 +- .../interception/windowskext2/handler.go | 1 + .../interception/windowskext2/packet.go | 12 +- service/firewall/module.go | 5 +- service/firewall/packet_handler.go | 104 ++++++++- service/instance.go | 25 ++- service/integration/etw_windows.go | 114 ++++++++++ service/integration/integration.go | 16 ++ service/integration/integration_windows.go | 52 +++++ service/integration/module.go | 49 +++++ service/network/connection.go | 33 +++ service/network/module.go | 4 + service/network/packet/parse.go | 61 +++++- service/resolver/ipinfo.go | 21 ++ service/resolver/main.go | 6 + service/resolver/resolver.go | 21 +- service/resolver/resolvers.go | 11 +- windows_core_dll/build.ps1 | 2 + windows_core_dll/dllmain.cpp | 197 ++++++++++++++++++ windows_core_dll/framework.h | 5 + windows_core_dll/pch.cpp | 5 + windows_core_dll/pch.h | 22 ++ windows_core_dll/windows_core_dll.sln | 31 +++ windows_core_dll/windows_core_dll.vcxproj | 158 ++++++++++++++ .../windows_core_dll.vcxproj.filters | 33 +++ .../windows_core_dll.vcxproj.user | 4 + 41 files changed, 1668 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/windows-dll.yml create mode 100644 service/firewall/interception/dnsmonitor/etwlink_windows.go create mode 100644 service/firewall/interception/dnsmonitor/eventlistener.go create mode 100644 service/firewall/interception/dnsmonitor/eventlistener_linux.go create mode 100644 service/firewall/interception/dnsmonitor/eventlistener_windows.go create mode 100644 service/firewall/interception/dnsmonitor/module.go create mode 100644 service/firewall/interception/dnsmonitor/varlinktypes.go create mode 100644 service/integration/etw_windows.go create mode 100644 service/integration/integration.go create mode 100644 service/integration/integration_windows.go create mode 100644 service/integration/module.go create mode 100644 windows_core_dll/build.ps1 create mode 100644 windows_core_dll/dllmain.cpp create mode 100644 windows_core_dll/framework.h create mode 100644 windows_core_dll/pch.cpp create mode 100644 windows_core_dll/pch.h create mode 100644 windows_core_dll/windows_core_dll.sln create mode 100644 windows_core_dll/windows_core_dll.vcxproj create mode 100644 windows_core_dll/windows_core_dll.vcxproj.filters create mode 100644 windows_core_dll/windows_core_dll.vcxproj.user diff --git a/.github/workflows/windows-dll.yml b/.github/workflows/windows-dll.yml new file mode 100644 index 00000000..9b2fd723 --- /dev/null +++ b/.github/workflows/windows-dll.yml @@ -0,0 +1,41 @@ +name: Windows Portmaster Core DLL + +on: + push: + paths: + - 'windows_core_dll/**' + branches: + - master + - develop + + pull_request: + paths: + - 'windows_core_dll/**' + branches: + - master + - develop + workflow_dispatch: + +jobs: + build: + name: Build + runs-on: windows-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v2 + - name: Build DLL + run: msbuild windows_core_dll\windows_core_dll.sln -t:rebuild -property:Configuration=Release + - name: Verify DLL + shell: powershell + run: | + if (!(Test-Path "windows_core_dll/x64/Release/portmaster-core.dll")) { + Write-Error "DLL build failed: portmaster-core.dll not found" + exit 1 + } + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: portmaster-core-dll + path: windows_core_dll/x64/Release/portmaster-core.dll \ No newline at end of file diff --git a/.gitignore b/.gitignore index e0a6550a..03d8b25f 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ go.work.sum # Kext releases windows_kext/release/kext_release_*.zip +windows_core_dll/.vs/windows_core_dll diff --git a/go.mod b/go.mod index d40c1410..5f609ef6 100644 --- a/go.mod +++ b/go.mod @@ -59,6 +59,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 + github.com/varlink/go v0.4.0 github.com/vincent-petithory/dataurl v1.0.0 go.etcd.io/bbolt v1.3.11 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f @@ -92,6 +93,7 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/maruel/panicparse/v2 v2.3.1 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect diff --git a/go.sum b/go.sum index c2bfeae6..13ec98f8 100644 --- a/go.sum +++ b/go.sum @@ -313,6 +313,8 @@ github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= +github.com/varlink/go v0.4.0 h1:+/BQoUO9eJK/+MTSHwFcJch7TMsb6N6Dqp6g0qaXXRo= +github.com/varlink/go v0.4.0/go.mod h1:DKg9Y2ctoNkesREGAEak58l+jOC6JU2aqZvUYs5DynU= github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= diff --git a/service/compat/module.go b/service/compat/module.go index 5ac97b51..e6781c9b 100644 --- a/service/compat/module.go +++ b/service/compat/module.go @@ -181,4 +181,5 @@ func New(instance instance) (*Compat, error) { type instance interface { NetEnv() *netenv.NetEnv + Resolver() *resolver.ResolverModule } diff --git a/service/compat/selfcheck.go b/service/compat/selfcheck.go index 27efd488..0bbef4e4 100644 --- a/service/compat/selfcheck.go +++ b/service/compat/selfcheck.go @@ -158,6 +158,12 @@ func selfcheck(ctx context.Context) (issue *systemIssue, err error) { // Step 3: Have the nameserver respond with random data in the answer section. + // Check if the resolver is enabled + if module.instance.Resolver().IsDisabled() { + // There is no control over the response, there is nothing more that can be checked. + return nil, nil + } + // Wait for the reply from the resolver. select { case err := <-dnsCheckLookupError: diff --git a/service/firewall/bypassing.go b/service/firewall/bypassing.go index 415fc6c8..4fe9a119 100644 --- a/service/firewall/bypassing.go +++ b/service/firewall/bypassing.go @@ -43,8 +43,24 @@ func PreventBypassing(ctx context.Context, conn *network.Connection) (endpoints. return endpoints.NoMatch, "", nil } + // If Portmaster resolver is disabled allow requests going to system dns resolver. + // And allow all connections out of the System Resolver. + if module.instance.Resolver().IsDisabled() { + // TODO(vladimir): Is there a more specific check that can be done? + if conn.Process().IsSystemResolver() { + return endpoints.NoMatch, "", nil + } + if conn.Entity.Port == 53 && conn.Entity.IPScope.IsLocalhost() { + return endpoints.NoMatch, "", nil + } + } + // Block bypass attempts using an (encrypted) DNS server. switch { + case looksLikeOutgoingDNSRequest(conn) && module.instance.Resolver().IsDisabled(): + // Allow. Packet will be analyzed and blocked if its not a dns request, before sent. + conn.Inspecting = true + return endpoints.NoMatch, "", nil case conn.Entity.Port == 53: return endpoints.Denied, "blocked DNS query, manual dns setup required", @@ -62,3 +78,17 @@ func PreventBypassing(ctx context.Context, conn *network.Connection) (endpoints. return endpoints.NoMatch, "", nil } + +func looksLikeOutgoingDNSRequest(conn *network.Connection) bool { + // Outbound on remote port 53, UDP. + if conn.Inbound { + return false + } + if conn.Entity.Port != 53 { + return false + } + if conn.IPProtocol != packet.UDP { + return false + } + return true +} diff --git a/service/firewall/dns.go b/service/firewall/dns.go index 9b1a55e5..e3434708 100644 --- a/service/firewall/dns.go +++ b/service/firewall/dns.go @@ -287,6 +287,30 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw } } + // Create new record for this IP. + record := resolver.ResolvedDomain{ + Domain: q.FQDN, + Resolver: rrCache.Resolver, + DNSRequestContext: rrCache.ToDNSRequestContext(), + Expires: rrCache.Expires, + } + // Process CNAMEs + record.AddCNAMEs(cnames) + // Link connection with cnames. + if conn.Type == network.DNSRequest { + conn.Entity.CNAME = record.CNAMEs + } + + SaveIPsInCache(ips, profileID, record) +} + +// formatRR is a friendlier alternative to miekg/dns.RR.String(). +func formatRR(rr dns.RR) string { + return strings.ReplaceAll(rr.String(), "\t", " ") +} + +// SaveIPsInCache saves the provided ips in the dns cashe assoseted with the record Domain and CNAMEs. +func SaveIPsInCache(ips []net.IP, profileID string, record resolver.ResolvedDomain) { // Package IPs and CNAMEs into IPInfo structs. for _, ip := range ips { // Never save domain attributions for localhost IPs. @@ -294,31 +318,6 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw continue } - // Create new record for this IP. - record := resolver.ResolvedDomain{ - Domain: q.FQDN, - Resolver: rrCache.Resolver, - DNSRequestContext: rrCache.ToDNSRequestContext(), - Expires: rrCache.Expires, - } - - // Resolve all CNAMEs in the correct order and add the to the record - up to max 50 layers. - domain := q.FQDN - for range 50 { - nextDomain, isCNAME := cnames[domain] - if !isCNAME || nextDomain == domain { - break - } - - record.CNAMEs = append(record.CNAMEs, nextDomain) - domain = nextDomain - } - - // Update the entity to include the CNAMEs of the query response. - conn.Entity.CNAME = record.CNAMEs - - // Check if there is an existing record for this DNS response. - // Else create a new one. ipString := ip.String() info, err := resolver.GetIPInfo(profileID, ipString) if err != nil { @@ -341,8 +340,3 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw } } } - -// formatRR is a friendlier alternative to miekg/dns.RR.String(). -func formatRR(rr dns.RR) string { - return strings.ReplaceAll(rr.String(), "\t", " ") -} diff --git a/service/firewall/interception/dnsmonitor/etwlink_windows.go b/service/firewall/interception/dnsmonitor/etwlink_windows.go new file mode 100644 index 00000000..d014bbab --- /dev/null +++ b/service/firewall/interception/dnsmonitor/etwlink_windows.go @@ -0,0 +1,99 @@ +//go:build windows +// +build windows + +package dnsmonitor + +import ( + "fmt" + "runtime" + "sync" + "sync/atomic" + + "github.com/safing/portmaster/service/integration" + "golang.org/x/sys/windows" +) + +type ETWSession struct { + i integration.ETWFunctions + + shutdownGuard atomic.Bool + shutdownMutex sync.Mutex + + state uintptr +} + +// NewSession creates new ETW event listener and initilizes it. This is a low level interface, make sure to call DestorySession when you are done using it. +func NewSession(etwInterface integration.ETWFunctions, callback func(domain string, result string)) (*ETWSession, error) { + etwSession := &ETWSession{ + i: etwInterface, + } + + // Make sure session from previous instances are not running. + _ = etwSession.i.StopOldSession() + + // Initialize notification activated callback + win32Callback := windows.NewCallback(func(domain *uint16, result *uint16) uintptr { + callback(windows.UTF16PtrToString(domain), windows.UTF16PtrToString(result)) + return 0 + }) + // The function only allocates memory it will not fail. + etwSession.state = etwSession.i.CreateState(win32Callback) + + // Make sure DestroySession is called even if caller forgets to call it. + runtime.SetFinalizer(etwSession, func(s *ETWSession) { + _ = s.i.DestroySession(s.state) + }) + + // Initialize session. + err := etwSession.i.InitializeSession(etwSession.state) + if err != nil { + return nil, fmt.Errorf("failed to initialzie session: %q", err) + } + + return etwSession, nil +} + +// StartTrace starts the tracing session of dns events. This is a blocking call. It will not return until the trace is stopped. +func (l *ETWSession) StartTrace() error { + return l.i.StartTrace(l.state) +} + +// IsRunning returns true if DestroySession has NOT been called. +func (l *ETWSession) IsRunning() bool { + return !l.shutdownGuard.Load() +} + +// FlushTrace flushes the trace buffer. +func (l *ETWSession) FlushTrace() error { + l.shutdownMutex.Lock() + defer l.shutdownMutex.Unlock() + + // Make sure session is still running. + if l.shutdownGuard.Load() { + return nil + } + + return l.i.FlushTrace(l.state) +} + +// StopTrace stopes the trace. This will cause StartTrace to return. +func (l *ETWSession) StopTrace() error { + return l.i.StopTrace(l.state) +} + +// DestroySession closes the session and frees the allocated memory. Listener cannot be used after this function is called. +func (l *ETWSession) DestroySession() error { + l.shutdownMutex.Lock() + defer l.shutdownMutex.Unlock() + + if l.shutdownGuard.Swap(true) { + return nil + } + + err := l.i.DestroySession(l.state) + if err != nil { + return err + } + l.state = 0 + return nil +} diff --git a/service/firewall/interception/dnsmonitor/eventlistener.go b/service/firewall/interception/dnsmonitor/eventlistener.go new file mode 100644 index 00000000..911130c9 --- /dev/null +++ b/service/firewall/interception/dnsmonitor/eventlistener.go @@ -0,0 +1,19 @@ +//go:build !linux && !windows +// +build !linux,!windows + +package dnsmonitor + +type Listener struct{} + +func newListener(_ *DNSMonitor) (*Listener, error) { + return &Listener{}, nil +} + +func (l *Listener) flush() error { + // Nothing to flush + return nil +} + +func (l *Listener) stop() error { + return nil +} diff --git a/service/firewall/interception/dnsmonitor/eventlistener_linux.go b/service/firewall/interception/dnsmonitor/eventlistener_linux.go new file mode 100644 index 00000000..d987a082 --- /dev/null +++ b/service/firewall/interception/dnsmonitor/eventlistener_linux.go @@ -0,0 +1,144 @@ +//go:build linux +// +build linux + +package dnsmonitor + +import ( + "errors" + "fmt" + "net" + "os" + + "github.com/miekg/dns" + "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/resolver" + "github.com/varlink/go/varlink" +) + +type Listener struct { + varlinkConn *varlink.Connection +} + +func newListener(module *DNSMonitor) (*Listener, error) { + // Set source of the resolver. + ResolverInfo.Source = resolver.ServerSourceSystemd + + // Check if the system has systemd-resolver. + _, err := os.Stat("/run/systemd/resolve/io.systemd.Resolve.Monitor") + if err != nil { + return nil, fmt.Errorf("system does not support systemd resolver monitor") + } + + listener := &Listener{} + + restartAttempts := 0 + + module.mgr.Go("systemd-resolver-event-listener", func(w *mgr.WorkerCtx) error { + // Abort initialization if the connection failed after too many tries. + if restartAttempts > 10 { + return nil + } + restartAttempts += 1 + + // Initialize varlink connection + varlinkConn, err := varlink.NewConnection(module.mgr.Ctx(), "unix:/run/systemd/resolve/io.systemd.Resolve.Monitor") + if err != nil { + return fmt.Errorf("failed to connect to systemd-resolver varlink service: %w", err) + } + defer func() { + if varlinkConn != nil { + err = varlinkConn.Close() + if err != nil { + log.Errorf("dnsmonitor: failed to close varlink connection: %s", err) + } + } + }() + + listener.varlinkConn = varlinkConn + // Subscribe to the dns query events + receive, err := listener.varlinkConn.Send(w.Ctx(), "io.systemd.Resolve.Monitor.SubscribeQueryResults", nil, varlink.More) + if err != nil { + var varlinkErr *varlink.Error + if errors.As(err, &varlinkErr) { + return fmt.Errorf("failed to issue Varlink call: %+v", varlinkErr.Parameters) + } else { + return fmt.Errorf("failed to issue Varlink call: %w", err) + } + } + + for { + queryResult := QueryResult{} + // Receive the next event from the resolver. + flags, err := receive(w.Ctx(), &queryResult) + if err != nil { + var varlinkErr *varlink.Error + if errors.As(err, &varlinkErr) { + return fmt.Errorf("failed to receive Varlink reply: %+v", varlinkErr.Parameters) + } else { + return fmt.Errorf("failed to receive Varlink reply: %w", err) + } + } + + // Check if the reply indicates the end of the stream + if flags&varlink.Continues == 0 { + break + } + + // Ignore if there is no question. + if queryResult.Question == nil || len(*queryResult.Question) == 0 { + continue + } + + // Protmaster self check + domain := (*queryResult.Question)[0].Name + if processIfSelfCheckDomain(dns.Fqdn(domain)) { + // Not need to process result. + continue + } + + if queryResult.Rcode != nil { + continue // Ignore DNS errors + } + + listener.processAnswer(domain, &queryResult) + } + return nil + }) + return listener, nil +} + +func (l *Listener) flush() error { + // Nothing to flush + return nil +} + +func (l *Listener) stop() error { + return nil +} + +func (l *Listener) processAnswer(domain string, queryResult *QueryResult) { + // Allocated data struct for the parsed result. + cnames := make(map[string]string) + ips := make([]net.IP, 0, 5) + + // Check if the query is valid + if queryResult.Answer == nil { + return + } + + // Go trough each answer entry. + for _, a := range *queryResult.Answer { + if a.RR.Address != nil { + ip := net.IP(*a.RR.Address) + // Answer contains ip address. + ips = append(ips, ip) + + } else if a.RR.Name != nil { + // Answer is a CNAME. + cnames[domain] = *a.RR.Name + } + } + + saveDomain(domain, ips, cnames) +} diff --git a/service/firewall/interception/dnsmonitor/eventlistener_windows.go b/service/firewall/interception/dnsmonitor/eventlistener_windows.go new file mode 100644 index 00000000..b6a39fd8 --- /dev/null +++ b/service/firewall/interception/dnsmonitor/eventlistener_windows.go @@ -0,0 +1,103 @@ +//go:build windows +// +build windows + +package dnsmonitor + +import ( + "fmt" + "net" + "strconv" + "strings" + + "github.com/miekg/dns" + "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/resolver" +) + +type Listener struct { + etw *ETWSession +} + +func newListener(module *DNSMonitor) (*Listener, error) { + // Set source of the resolver. + ResolverInfo.Source = resolver.ServerSourceETW + + listener := &Listener{} + var err error + // Initialize new dns event session. + listener.etw, err = NewSession(module.instance.OSIntegration().GetETWInterface(), listener.processEvent) + if err != nil { + return nil, err + } + + // Start listening for events. + module.mgr.Go("etw-dns-event-listener", func(w *mgr.WorkerCtx) error { + return listener.etw.StartTrace() + }) + + return listener, nil +} + +func (l *Listener) flush() error { + return l.etw.FlushTrace() +} + +func (l *Listener) stop() error { + if l == nil { + return fmt.Errorf("listener is nil") + } + if l.etw == nil { + return fmt.Errorf("invalid etw session") + } + // Stop and destroy trace. Destroy should be called even if stop fails for some reason. + err := l.etw.StopTrace() + err2 := l.etw.DestroySession() + + if err != nil { + return fmt.Errorf("StopTrace failed: %w", err) + } + + if err2 != nil { + return fmt.Errorf("DestroySession failed: %w", err2) + } + return nil +} + +func (l *Listener) processEvent(domain string, result string) { + if processIfSelfCheckDomain(dns.Fqdn(domain)) { + // Not need to process result. + return + } + + // Ignore empty results + if len(result) == 0 { + return + } + + cnames := make(map[string]string) + ips := []net.IP{} + + resultArray := strings.Split(result, ";") + for _, r := range resultArray { + // For results other than IP addresses, the string starts with "type:" + if strings.HasPrefix(r, "type:") { + dnsValueArray := strings.Split(r, " ") + if len(dnsValueArray) < 3 { + continue + } + + // Ignore everything except CNAME records + if value, err := strconv.ParseInt(dnsValueArray[1], 10, 16); err == nil && value == int64(dns.TypeCNAME) { + cnames[domain] = dnsValueArray[2] + } + + } else { + // If the event doesn't start with "type:", it's an IP address + ip := net.ParseIP(r) + if ip != nil { + ips = append(ips, ip) + } + } + } + saveDomain(domain, ips, cnames) +} diff --git a/service/firewall/interception/dnsmonitor/module.go b/service/firewall/interception/dnsmonitor/module.go new file mode 100644 index 00000000..eed8be11 --- /dev/null +++ b/service/firewall/interception/dnsmonitor/module.go @@ -0,0 +1,138 @@ +package dnsmonitor + +import ( + "errors" + "net" + "strings" + + "github.com/miekg/dns" + "github.com/safing/portmaster/base/database" + "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/service/compat" + "github.com/safing/portmaster/service/integration" + "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/network/netutils" + "github.com/safing/portmaster/service/resolver" +) + +var ResolverInfo = resolver.ResolverInfo{ + Name: "SystemResolver", + Type: resolver.ServerTypeMonitor, +} + +type DNSMonitor struct { + instance instance + mgr *mgr.Manager + + listener *Listener +} + +// Manager returns the module manager. +func (dl *DNSMonitor) Manager() *mgr.Manager { + return dl.mgr +} + +// Start starts the module. +func (dl *DNSMonitor) Start() error { + // Initialize dns event listener + var err error + dl.listener, err = newListener(dl) + if err != nil { + log.Errorf("dnsmonitor: failed to start dns listener: %s", err) + } + + return nil +} + +// Stop stops the module. +func (dl *DNSMonitor) Stop() error { + if dl.listener != nil { + err := dl.listener.stop() + if err != nil { + log.Errorf("dnsmonitor: failed to close listener: %s", err) + } + } + return nil +} + +// Flush flushes the buffer forcing all events to be processed. +func (dl *DNSMonitor) Flush() error { + return dl.listener.flush() +} + +func saveDomain(domain string, ips []net.IP, cnames map[string]string) { + fqdn := dns.Fqdn(domain) + // Create new record for this IP. + record := resolver.ResolvedDomain{ + Domain: fqdn, + Resolver: &ResolverInfo, + DNSRequestContext: &resolver.DNSRequestContext{}, + Expires: 0, + } + + // Process cnames + record.AddCNAMEs(cnames) + + // Add to cache + saveIPsInCache(ips, resolver.IPInfoProfileScopeGlobal, record) +} + +func New(instance instance) (*DNSMonitor, error) { + // Initialize module + m := mgr.New("DNSMonitor") + module := &DNSMonitor{ + mgr: m, + instance: instance, + } + + return module, nil +} + +type instance interface { + OSIntegration() *integration.OSIntegration +} + +func processIfSelfCheckDomain(fqdn string) bool { + // Check for compat check dns request. + if strings.HasSuffix(fqdn, compat.DNSCheckInternalDomainScope) { + subdomain := strings.TrimSuffix(fqdn, compat.DNSCheckInternalDomainScope) + _ = compat.SubmitDNSCheckDomain(subdomain) + log.Infof("dnsmonitor: self-check domain received") + // No need to parse the answer. + return true + } + + return false +} + +// saveIPsInCache saves the provided ips in the dns cashe assoseted with the record Domain and CNAMEs. +func saveIPsInCache(ips []net.IP, profileID string, record resolver.ResolvedDomain) { + // Package IPs and CNAMEs into IPInfo structs. + for _, ip := range ips { + // Never save domain attributions for localhost IPs. + if netutils.GetIPScope(ip) == netutils.HostLocal { + continue + } + + ipString := ip.String() + info, err := resolver.GetIPInfo(profileID, ipString) + if err != nil { + if !errors.Is(err, database.ErrNotFound) { + log.Errorf("dnsmonitor: failed to search for IP info record: %s", err) + } + + info = &resolver.IPInfo{ + IP: ipString, + ProfileID: profileID, + } + } + + // Add the new record to the resolved domains for this IP and scope. + info.AddDomain(record) + + // Save if the record is new or has been updated. + if err := info.Save(); err != nil { + log.Errorf("dnsmonitor: failed to save IP info record: %s", err) + } + } +} diff --git a/service/firewall/interception/dnsmonitor/varlinktypes.go b/service/firewall/interception/dnsmonitor/varlinktypes.go new file mode 100644 index 00000000..3021ac18 --- /dev/null +++ b/service/firewall/interception/dnsmonitor/varlinktypes.go @@ -0,0 +1,83 @@ +//go:build linux +// +build linux + +package dnsmonitor + +// List of struct that define the systemd-resolver varlink dns event protocol. +// Source: `sudo varlinkctl introspect /run/systemd/resolve/io.systemd.Resolve.Monitor io.systemd.Resolve.Monitor` + +type ResourceKey struct { + Class int `json:"class"` + Type int `json:"type"` + Name string `json:"name"` +} + +type ResourceRecord struct { + Key ResourceKey `json:"key"` + Name *string `json:"name,omitempty"` + Address *[]byte `json:"address,omitempty"` + // Rest of the fields are not used. + // Priority *int `json:"priority,omitempty"` + // Weight *int `json:"weight,omitempty"` + // Port *int `json:"port,omitempty"` + // CPU *string `json:"cpu,omitempty"` + // OS *string `json:"os,omitempty"` + // Items *[]string `json:"items,omitempty"` + // MName *string `json:"mname,omitempty"` + // RName *string `json:"rname,omitempty"` + // Serial *int `json:"serial,omitempty"` + // Refresh *int `json:"refresh,omitempty"` + // Expire *int `json:"expire,omitempty"` + // Minimum *int `json:"minimum,omitempty"` + // Exchange *string `json:"exchange,omitempty"` + // Version *int `json:"version,omitempty"` + // Size *int `json:"size,omitempty"` + // HorizPre *int `json:"horiz_pre,omitempty"` + // VertPre *int `json:"vert_pre,omitempty"` + // Latitude *int `json:"latitude,omitempty"` + // Longitude *int `json:"longitude,omitempty"` + // Altitude *int `json:"altitude,omitempty"` + // KeyTag *int `json:"key_tag,omitempty"` + // Algorithm *int `json:"algorithm,omitempty"` + // DigestType *int `json:"digest_type,omitempty"` + // Digest *string `json:"digest,omitempty"` + // FPType *int `json:"fptype,omitempty"` + // Fingerprint *string `json:"fingerprint,omitempty"` + // Flags *int `json:"flags,omitempty"` + // Protocol *int `json:"protocol,omitempty"` + // DNSKey *string `json:"dnskey,omitempty"` + // Signer *string `json:"signer,omitempty"` + // TypeCovered *int `json:"type_covered,omitempty"` + // Labels *int `json:"labels,omitempty"` + // OriginalTTL *int `json:"original_ttl,omitempty"` + // Expiration *int `json:"expiration,omitempty"` + // Inception *int `json:"inception,omitempty"` + // Signature *string `json:"signature,omitempty"` + // NextDomain *string `json:"next_domain,omitempty"` + // Types *[]int `json:"types,omitempty"` + // Iterations *int `json:"iterations,omitempty"` + // Salt *string `json:"salt,omitempty"` + // Hash *string `json:"hash,omitempty"` + // CertUsage *int `json:"cert_usage,omitempty"` + // Selector *int `json:"selector,omitempty"` + // MatchingType *int `json:"matching_type,omitempty"` + // Data *string `json:"data,omitempty"` + // Tag *string `json:"tag,omitempty"` + // Value *string `json:"value,omitempty"` +} + +type Answer struct { + RR *ResourceRecord `json:"rr,omitempty"` + Raw string `json:"raw"` + IfIndex *int `json:"ifindex,omitempty"` +} + +type QueryResult struct { + Ready *bool `json:"ready,omitempty"` + State *string `json:"state,omitempty"` + Rcode *int `json:"rcode,omitempty"` + Errno *int `json:"errno,omitempty"` + Question *[]ResourceKey `json:"question,omitempty"` + CollectedQuestions *[]ResourceKey `json:"collectedQuestions,omitempty"` + Answer *[]Answer `json:"answer,omitempty"` +} diff --git a/service/firewall/interception/nfq/nfq.go b/service/firewall/interception/nfq/nfq.go index 22a5b390..397d1857 100644 --- a/service/firewall/interception/nfq/nfq.go +++ b/service/firewall/interception/nfq/nfq.go @@ -188,7 +188,7 @@ func (q *Queue) packetHandler(ctx context.Context) func(nfqueue.Attribute) int { return 0 } - if err := pmpacket.Parse(*attrs.Payload, &pkt.Base); err != nil { + if err := pmpacket.ParseLayer3(*attrs.Payload, &pkt.Base); err != nil { log.Warningf("nfqueue: failed to parse payload: %s", err) _ = pkt.Drop() return 0 diff --git a/service/firewall/interception/windowskext/packet.go b/service/firewall/interception/windowskext/packet.go index 5942d7d9..9145926c 100644 --- a/service/firewall/interception/windowskext/packet.go +++ b/service/firewall/interception/windowskext/packet.go @@ -59,7 +59,7 @@ func (pkt *Packet) LoadPacketData() error { return packet.ErrFailedToLoadPayload } - err = packet.Parse(payload, &pkt.Base) + err = packet.ParseLayer3(payload, &pkt.Base) if err != nil { log.Tracer(pkt.Ctx()).Warningf("windowskext: failed to parse payload: %s", err) return packet.ErrFailedToLoadPayload diff --git a/service/firewall/interception/windowskext2/handler.go b/service/firewall/interception/windowskext2/handler.go index 57f74c71..d144fa63 100644 --- a/service/firewall/interception/windowskext2/handler.go +++ b/service/firewall/interception/windowskext2/handler.go @@ -55,6 +55,7 @@ func Handler(ctx context.Context, packets chan packet.Packet, bandwidthUpdate ch newPacket := &Packet{ verdictRequest: conn.ID, payload: conn.Payload, + payloadLayer: conn.PayloadLayer, verdictSet: abool.NewBool(false), } info := newPacket.Info() diff --git a/service/firewall/interception/windowskext2/packet.go b/service/firewall/interception/windowskext2/packet.go index 52a7a2a7..00d95036 100644 --- a/service/firewall/interception/windowskext2/packet.go +++ b/service/firewall/interception/windowskext2/packet.go @@ -4,6 +4,7 @@ package windowskext import ( + "fmt" "sync" "github.com/tevino/abool" @@ -19,6 +20,7 @@ type Packet struct { verdictRequest uint64 payload []byte + payloadLayer uint8 verdictSet *abool.AtomicBool payloadLoaded bool @@ -51,7 +53,15 @@ func (pkt *Packet) LoadPacketData() error { pkt.payloadLoaded = true if len(pkt.payload) > 0 { - err := packet.Parse(pkt.payload, &pkt.Base) + var err error + switch pkt.payloadLayer { + case 3: + err = packet.ParseLayer3(pkt.payload, &pkt.Base) + case 4: + err = packet.ParseLayer4(pkt.payload, &pkt.Base) + default: + err = fmt.Errorf("unsupported payload layer: %d", pkt.payloadLayer) + } if err != nil { log.Tracef("payload: %#v", pkt.payload) log.Tracer(pkt.Ctx()).Warningf("windowskext: failed to parse payload: %s", err) diff --git a/service/firewall/module.go b/service/firewall/module.go index 131d4cac..2ac87de2 100644 --- a/service/firewall/module.go +++ b/service/firewall/module.go @@ -16,6 +16,7 @@ import ( "github.com/safing/portmaster/service/netquery" "github.com/safing/portmaster/service/network" "github.com/safing/portmaster/service/profile" + "github.com/safing/portmaster/service/resolver" "github.com/safing/portmaster/spn/access" "github.com/safing/portmaster/spn/captain" ) @@ -34,8 +35,7 @@ func (ss *stringSliceFlag) Set(value string) error { var allowedClients stringSliceFlag type Firewall struct { - mgr *mgr.Manager - + mgr *mgr.Manager instance instance } @@ -165,4 +165,5 @@ type instance interface { Access() *access.Access Network() *network.Network NetQuery() *netquery.NetQuery + Resolver() *resolver.ResolverModule } diff --git a/service/firewall/packet_handler.go b/service/firewall/packet_handler.go index a290182f..c0e59cb7 100644 --- a/service/firewall/packet_handler.go +++ b/service/firewall/packet_handler.go @@ -6,10 +6,12 @@ import ( "fmt" "net" "os" + "strings" "sync/atomic" "time" "github.com/google/gopacket/layers" + "github.com/miekg/dns" "github.com/tevino/abool" "github.com/safing/portmaster/base/log" @@ -23,6 +25,7 @@ import ( "github.com/safing/portmaster/service/network/netutils" "github.com/safing/portmaster/service/network/packet" "github.com/safing/portmaster/service/process" + "github.com/safing/portmaster/service/resolver" "github.com/safing/portmaster/spn/access" ) @@ -444,8 +447,9 @@ func filterHandler(conn *network.Connection, pkt packet.Packet) { filterConnection = false log.Tracer(pkt.Ctx()).Infof("filter: granting own pre-authenticated connection %s", conn) - // Redirect outbound DNS packets if enabled, + // Redirect outbound DNS packets if enabled, case dnsQueryInterception() && + !module.instance.Resolver().IsDisabled() && pkt.IsOutbound() && pkt.Info().DstPort == 53 && // that don't match the address of our nameserver, @@ -478,11 +482,13 @@ func filterHandler(conn *network.Connection, pkt packet.Packet) { // Decide how to continue handling connection. switch { + case conn.Inspecting && looksLikeOutgoingDNSRequest(conn): + inspectDNSPacket(conn, pkt) + conn.UpdateFirewallHandler(inspectDNSPacket) case conn.Inspecting: log.Tracer(pkt.Ctx()).Trace("filter: start inspecting") conn.UpdateFirewallHandler(inspectAndVerdictHandler) inspectAndVerdictHandler(conn, pkt) - default: conn.StopFirewallHandler() verdictHandler(conn, pkt) @@ -506,7 +512,7 @@ func FilterConnection(ctx context.Context, conn *network.Connection, pkt packet. } // TODO: Enable inspection framework again. - conn.Inspecting = false + // conn.Inspecting = false // TODO: Quick fix for the SPN. // Use inspection framework for proper encryption detection. @@ -580,6 +586,98 @@ func inspectAndVerdictHandler(conn *network.Connection, pkt packet.Packet) { issueVerdict(conn, pkt, 0, true) } +func inspectDNSPacket(conn *network.Connection, pkt packet.Packet) { + // Ignore info-only packets in this handler. + if pkt.InfoOnly() { + return + } + + dnsPacket := new(dns.Msg) + err := pkt.LoadPacketData() + if err != nil { + _ = pkt.Block() + log.Errorf("filter: failed to load packet payload: %s", err) + return + } + + // Parse and block invalid packets. + err = dnsPacket.Unpack(pkt.Payload()) + if err != nil { + err = pkt.PermanentBlock() + if err != nil { + log.Errorf("filter: failed to block packet: %s", err) + } + _ = conn.SetVerdict(network.VerdictBlock, "none DNS data on DNS port", "", nil) + conn.VerdictPermanent = true + conn.Save() + return + } + + // Packet was parsed. + // Allow it but only after the answer was added to the cache. + defer func() { + err = pkt.Accept() + if err != nil { + log.Errorf("filter: failed to accept dns packet: %s", err) + } + }() + + // Check if packet has a question. + if len(dnsPacket.Question) == 0 { + return + } + + // Read create structs with the needed data. + question := dnsPacket.Question[0] + fqdn := dns.Fqdn(question.Name) + + // Check for compat check dns request. + if strings.HasSuffix(fqdn, compat.DNSCheckInternalDomainScope) { + subdomain := strings.TrimSuffix(fqdn, compat.DNSCheckInternalDomainScope) + _ = compat.SubmitDNSCheckDomain(subdomain) + log.Infof("packet_handler: self-check domain received") + // No need to parse the answer. + return + } + + // Check if there is an answer. + if len(dnsPacket.Answer) == 0 { + return + } + + resolverInfo := &resolver.ResolverInfo{ + Name: "DNSRequestObserver", + Type: resolver.ServerTypeFirewall, + Source: resolver.ServerSourceFirewall, + IP: conn.Entity.IP, + Domain: conn.Entity.Domain, + IPScope: conn.Entity.IPScope, + } + + rrCache := &resolver.RRCache{ + Domain: fqdn, + Question: dns.Type(question.Qtype), + RCode: dnsPacket.Rcode, + Answer: dnsPacket.Answer, + Ns: dnsPacket.Ns, + Extra: dnsPacket.Extra, + Resolver: resolverInfo, + } + + query := &resolver.Query{ + FQDN: fqdn, + QType: dns.Type(question.Qtype), + NoCaching: false, + IgnoreFailing: false, + LocalResolversOnly: false, + ICANNSpace: false, + DomainRoot: "", + } + + // Save to cache + UpdateIPsAndCNAMEs(query, rrCache, conn) +} + func icmpFilterHandler(conn *network.Connection, pkt packet.Packet) { // Load packet data. err := pkt.LoadPacketData() diff --git a/service/instance.go b/service/instance.go index ad6e9dab..ee482605 100644 --- a/service/instance.go +++ b/service/instance.go @@ -19,6 +19,8 @@ import ( "github.com/safing/portmaster/service/core/base" "github.com/safing/portmaster/service/firewall" "github.com/safing/portmaster/service/firewall/interception" + "github.com/safing/portmaster/service/firewall/interception/dnsmonitor" + "github.com/safing/portmaster/service/integration" "github.com/safing/portmaster/service/intel/customlists" "github.com/safing/portmaster/service/intel/filterlists" "github.com/safing/portmaster/service/intel/geoip" @@ -65,6 +67,7 @@ type Instance struct { core *core.Core updates *updates.Updates + integration *integration.OSIntegration geoip *geoip.GeoIP netenv *netenv.NetEnv ui *ui.UI @@ -74,6 +77,7 @@ type Instance struct { firewall *firewall.Firewall filterLists *filterlists.FilterLists interception *interception.Interception + dnsmonitor *dnsmonitor.DNSMonitor customlist *customlists.CustomList status *status.Status broadcasts *broadcasts.Broadcasts @@ -107,7 +111,6 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx instance.ctx, instance.cancelCtx = context.WithCancel(context.Background()) var err error - // Base modules instance.base, err = base.New(instance) if err != nil { @@ -151,6 +154,10 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx if err != nil { return instance, fmt.Errorf("create updates module: %w", err) } + instance.integration, err = integration.New(instance) + if err != nil { + return instance, fmt.Errorf("create integration module: %w", err) + } instance.geoip, err = geoip.New(instance) if err != nil { return instance, fmt.Errorf("create customlist module: %w", err) @@ -187,6 +194,10 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx if err != nil { return instance, fmt.Errorf("create interception module: %w", err) } + instance.dnsmonitor, err = dnsmonitor.New(instance) + if err != nil { + return instance, fmt.Errorf("create dns-listener module: %w", err) + } instance.customlist, err = customlists.New(instance) if err != nil { return instance, fmt.Errorf("create customlist module: %w", err) @@ -275,6 +286,7 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx instance.core, instance.updates, + instance.integration, instance.geoip, instance.netenv, @@ -288,6 +300,7 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx instance.filterLists, instance.customlist, instance.interception, + instance.dnsmonitor, instance.compat, instance.status, @@ -378,6 +391,11 @@ func (i *Instance) Updates() *updates.Updates { return i.updates } +// OSIntegration returns the integration module. +func (i *Instance) OSIntegration() *integration.OSIntegration { + return i.integration +} + // GeoIP returns the geoip module. func (i *Instance) GeoIP() *geoip.GeoIP { return i.geoip @@ -463,6 +481,11 @@ func (i *Instance) Interception() *interception.Interception { return i.interception } +// DNSMonitor returns the dns-listener module. +func (i *Instance) DNSMonitor() *dnsmonitor.DNSMonitor { + return i.dnsmonitor +} + // CustomList returns the customlist module. func (i *Instance) CustomList() *customlists.CustomList { return i.customlist diff --git a/service/integration/etw_windows.go b/service/integration/etw_windows.go new file mode 100644 index 00000000..eac3ad8f --- /dev/null +++ b/service/integration/etw_windows.go @@ -0,0 +1,114 @@ +//go:build windows +// +build windows + +package integration + +import ( + "fmt" + + "golang.org/x/sys/windows" +) + +type ETWFunctions struct { + createState *windows.Proc + initializeSession *windows.Proc + startTrace *windows.Proc + flushTrace *windows.Proc + stopTrace *windows.Proc + destroySession *windows.Proc + stopOldSession *windows.Proc +} + +func initializeETW(dll *windows.DLL) (ETWFunctions, error) { + var functions ETWFunctions + var err error + functions.createState, err = dll.FindProc("PM_ETWCreateState") + if err != nil { + return functions, fmt.Errorf("failed to load function PM_ETWCreateState: %q", err) + } + functions.initializeSession, err = dll.FindProc("PM_ETWInitializeSession") + if err != nil { + return functions, fmt.Errorf("failed to load function PM_ETWInitializeSession: %q", err) + } + functions.startTrace, err = dll.FindProc("PM_ETWStartTrace") + if err != nil { + return functions, fmt.Errorf("failed to load function PM_ETWStartTrace: %q", err) + } + functions.flushTrace, err = dll.FindProc("PM_ETWFlushTrace") + if err != nil { + return functions, fmt.Errorf("failed to load function PM_ETWFlushTrace: %q", err) + } + functions.stopTrace, err = dll.FindProc("PM_ETWStopTrace") + if err != nil { + return functions, fmt.Errorf("failed to load function PM_ETWStopTrace: %q", err) + } + functions.destroySession, err = dll.FindProc("PM_ETWDestroySession") + if err != nil { + return functions, fmt.Errorf("failed to load function PM_ETWDestroySession: %q", err) + } + functions.stopOldSession, err = dll.FindProc("PM_ETWStopOldSession") + if err != nil { + return functions, fmt.Errorf("failed to load function PM_ETWDestroySession: %q", err) + } + return functions, nil +} + +// CreateState calls the dll createState C function. +func (etw ETWFunctions) CreateState(callback uintptr) uintptr { + state, _, _ := etw.createState.Call(callback) + return state +} + +// InitializeSession calls the dll initializeSession C function. +func (etw ETWFunctions) InitializeSession(state uintptr) error { + rc, _, _ := etw.initializeSession.Call(state) + if rc != 0 { + return fmt.Errorf("failed with status code: %d", rc) + } + return nil +} + +// StartTrace calls the dll startTrace C function. +func (etw ETWFunctions) StartTrace(state uintptr) error { + rc, _, _ := etw.startTrace.Call(state) + if rc != 0 { + return fmt.Errorf("failed with status code: %d", rc) + } + return nil +} + +// FlushTrace calls the dll flushTrace C function. +func (etw ETWFunctions) FlushTrace(state uintptr) error { + rc, _, _ := etw.flushTrace.Call(state) + if rc != 0 { + return fmt.Errorf("failed with status code: %d", rc) + } + return nil +} + +// StopTrace calls the dll stopTrace C function. +func (etw ETWFunctions) StopTrace(state uintptr) error { + rc, _, _ := etw.stopTrace.Call(state) + if rc != 0 { + return fmt.Errorf("failed with status code: %d", rc) + } + return nil +} + +// DestroySession calls the dll destroySession C function. +func (etw ETWFunctions) DestroySession(state uintptr) error { + rc, _, _ := etw.destroySession.Call(state) + if rc != 0 { + return fmt.Errorf("failed with status code: %d", rc) + } + return nil +} + +// StopOldSession calls the dll stopOldSession C function. +func (etw ETWFunctions) StopOldSession() error { + rc, _, _ := etw.stopOldSession.Call() + if rc != 0 { + return fmt.Errorf("failed with status code: %d", rc) + } + return nil +} diff --git a/service/integration/integration.go b/service/integration/integration.go new file mode 100644 index 00000000..2189b152 --- /dev/null +++ b/service/integration/integration.go @@ -0,0 +1,16 @@ +//go:build !windows +// +build !windows + +package integration + +type OSSpecific struct{} + +// Initialize is empty on any OS different then Windows. +func (i *OSIntegration) Initialize() error { + return nil +} + +// CleanUp releases any resourses allocated during initializaion. +func (i *OSIntegration) CleanUp() error { + return nil +} diff --git a/service/integration/integration_windows.go b/service/integration/integration_windows.go new file mode 100644 index 00000000..786d6da6 --- /dev/null +++ b/service/integration/integration_windows.go @@ -0,0 +1,52 @@ +//go:build windows +// +build windows + +package integration + +import ( + "fmt" + + "github.com/safing/portmaster/service/updates" + "golang.org/x/sys/windows" +) + +type OSSpecific struct { + dll *windows.DLL + etwFunctions ETWFunctions +} + +// Initialize loads the dll and finds all the needed functions from it. +func (i *OSIntegration) Initialize() error { + // Find path to the dll. + file, err := updates.GetFile("portmaster-core.dll") + if err != nil { + return err + } + + // Load the DLL. + i.os.dll, err = windows.LoadDLL(file.Path()) + if err != nil { + return fmt.Errorf("failed to load dll: %q", err) + } + + // Enumerate all needed dll functions. + i.os.etwFunctions, err = initializeETW(i.os.dll) + if err != nil { + return err + } + + return nil +} + +// CleanUp releases any resourses allocated during initializaion. +func (i *OSIntegration) CleanUp() error { + if i.os.dll != nil { + return i.os.dll.Release() + } + return nil +} + +// GetETWInterface return struct containing all the ETW related functions. +func (i *OSIntegration) GetETWInterface() ETWFunctions { + return i.os.etwFunctions +} diff --git a/service/integration/module.go b/service/integration/module.go new file mode 100644 index 00000000..0e43798a --- /dev/null +++ b/service/integration/module.go @@ -0,0 +1,49 @@ +package integration + +import ( + "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/updates" +) + +// OSIntegration module provides special integration with the OS. +type OSIntegration struct { + m *mgr.Manager + states *mgr.StateMgr + + //nolint:unused + os OSSpecific + + instance instance +} + +// New returns a new OSIntegration module. +func New(instance instance) (*OSIntegration, error) { + m := mgr.New("OSIntegration") + module := &OSIntegration{ + m: m, + states: m.NewStateMgr(), + + instance: instance, + } + + return module, nil +} + +// Manager returns the module manager. +func (i *OSIntegration) Manager() *mgr.Manager { + return i.m +} + +// Start starts the module. +func (i *OSIntegration) Start() error { + return i.Initialize() +} + +// Stop stops the module. +func (i *OSIntegration) Stop() error { + return i.CleanUp() +} + +type instance interface { + Updates() *updates.Updates +} diff --git a/service/network/connection.go b/service/network/connection.go index 7ea96400..b3dd70fc 100644 --- a/service/network/connection.go +++ b/service/network/connection.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "net" + "runtime" "sync" "sync/atomic" "time" @@ -18,6 +19,7 @@ import ( "github.com/safing/portmaster/service/netenv" "github.com/safing/portmaster/service/network/netutils" "github.com/safing/portmaster/service/network/packet" + "github.com/safing/portmaster/service/network/reference" "github.com/safing/portmaster/service/process" _ "github.com/safing/portmaster/service/process/tags" "github.com/safing/portmaster/service/resolver" @@ -542,6 +544,23 @@ func (conn *Connection) GatherConnectionInfo(pkt packet.Packet) (err error) { // Try again with the global scope, in case DNS went through the system resolver. ipinfo, err = resolver.GetIPInfo(resolver.IPInfoProfileScopeGlobal, pkt.Info().RemoteIP().String()) } + + if runtime.GOOS == "windows" && err != nil { + // On windows domains may come with delay. + if module.instance.Resolver().IsDisabled() && conn.shouldWaitForDomain() { + // Flush the dns listener buffer and try again. + for i := range 4 { + _ = module.instance.DNSMonitor().Flush() + ipinfo, err = resolver.GetIPInfo(resolver.IPInfoProfileScopeGlobal, pkt.Info().RemoteIP().String()) + if err == nil { + log.Tracer(pkt.Ctx()).Debugf("network: found domain from dnsmonitor after %d tries", i+1) + break + } + time.Sleep(5 * time.Millisecond) + } + } + } + if err == nil { lastResolvedDomain := ipinfo.MostRecentDomain() if lastResolvedDomain != nil { @@ -869,3 +888,17 @@ func (conn *Connection) String() string { return fmt.Sprintf("%s -> %s", conn.process, conn.Entity.IP) } } + +func (conn *Connection) shouldWaitForDomain() bool { + // Should wait for Global Unicast, outgoing and not ICMP connections + switch { + case conn.Entity.IPScope != netutils.Global: + return false + case conn.Inbound: + return false + case reference.IsICMP(conn.Entity.Protocol): + return false + } + + return true +} diff --git a/service/network/module.go b/service/network/module.go index 4cab1cb1..eb9b452d 100644 --- a/service/network/module.go +++ b/service/network/module.go @@ -9,10 +9,12 @@ import ( "sync/atomic" "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/service/firewall/interception/dnsmonitor" "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/netenv" "github.com/safing/portmaster/service/network/state" "github.com/safing/portmaster/service/profile" + "github.com/safing/portmaster/service/resolver" ) // Events. @@ -188,4 +190,6 @@ func New(instance instance) (*Network, error) { type instance interface { Profile() *profile.ProfileModule + Resolver() *resolver.ResolverModule + DNSMonitor() *dnsmonitor.DNSMonitor } diff --git a/service/network/packet/parse.go b/service/network/packet/parse.go index 562546af..adfc69d9 100644 --- a/service/network/packet/parse.go +++ b/service/network/packet/parse.go @@ -106,11 +106,12 @@ func checkError(packet gopacket.Packet, info *Info) error { return nil } -// Parse parses an IP packet and saves the information in the given packet object. -func Parse(packetData []byte, pktBase *Base) (err error) { +// ParseLayer3 parses an IP packet and saves the information in the given packet object. +func ParseLayer3(packetData []byte, pktBase *Base) (err error) { if len(packetData) == 0 { return errors.New("empty packet") } + pktBase.layer3Data = packetData ipVersion := packetData[0] >> 4 @@ -155,6 +156,62 @@ func Parse(packetData []byte, pktBase *Base) (err error) { return nil } +// ParseLayer4 parses an layer 4 packet and saves the information in the given packet object. +func ParseLayer4(packetData []byte, pktBase *Base) (err error) { + if len(packetData) == 0 { + return errors.New("empty packet") + } + + var layer gopacket.LayerType + switch pktBase.info.Protocol { + case ICMP: + layer = layers.LayerTypeICMPv4 + case IGMP: + layer = layers.LayerTypeIGMP + case TCP: + layer = layers.LayerTypeTCP + case UDP: + layer = layers.LayerTypeUDP + case ICMPv6: + layer = layers.LayerTypeICMPv6 + case UDPLite: + return fmt.Errorf("UDPLite not supported") + case RAW: + return fmt.Errorf("RAW protocol not supported") + case AnyHostInternalProtocol61: + return fmt.Errorf("AnyHostInternalProtocol61 protocol not supported") + default: + return fmt.Errorf("protocol not supported") + } + + packet := gopacket.NewPacket(packetData, layer, gopacket.DecodeOptions{ + Lazy: true, + NoCopy: true, + }) + + availableDecoders := []func(gopacket.Packet, *Info) error{ + parseTCP, + parseUDP, + // parseUDPLite, // We don't yet support udplite. + parseICMPv4, + parseICMPv6, + parseIGMP, + checkError, + } + + for _, dec := range availableDecoders { + if err := dec(packet, pktBase.Info()); err != nil { + return err + } + } + + pktBase.layers = packet + if transport := packet.TransportLayer(); transport != nil { + pktBase.layer5Data = transport.LayerPayload() + } + return nil +} + func init() { genIPProtocolFromLayerType() } diff --git a/service/resolver/ipinfo.go b/service/resolver/ipinfo.go index 89cf9297..32cc0cc3 100644 --- a/service/resolver/ipinfo.go +++ b/service/resolver/ipinfo.go @@ -52,6 +52,27 @@ type ResolvedDomain struct { Expires int64 } +// AddCNAMEs adds all cnames from the map related to its set Domain. +func (resolved *ResolvedDomain) AddCNAMEs(cnames map[string]string) { + // Resolve all CNAMEs in the correct order and add the to the record - up to max 50 layers. + domain := resolved.Domain +domainLoop: + for range 50 { + nextDomain, isCNAME := cnames[domain] + switch { + case !isCNAME: + break domainLoop + case nextDomain == resolved.Domain: + break domainLoop + case nextDomain == domain: + break domainLoop + } + + resolved.CNAMEs = append(resolved.CNAMEs, nextDomain) + domain = nextDomain + } +} + // String returns a string representation of ResolvedDomain including // the CNAME chain. It implements fmt.Stringer. func (resolved *ResolvedDomain) String() string { diff --git a/service/resolver/main.go b/service/resolver/main.go index 8a43d12b..107d5fc8 100644 --- a/service/resolver/main.go +++ b/service/resolver/main.go @@ -29,6 +29,8 @@ type ResolverModule struct { //nolint failingResolverWorkerMgr *mgr.WorkerMgr suggestUsingStaleCacheTask *mgr.WorkerMgr + isDisabled atomic.Bool + states *mgr.StateMgr } @@ -52,6 +54,10 @@ func (rm *ResolverModule) Stop() error { return nil } +func (rm *ResolverModule) IsDisabled() bool { + return rm.isDisabled.Load() +} + func prep() error { // Set DNS test connectivity function for the online status check netenv.DNSTestQueryFunc = func(ctx context.Context, fdqn string) (ips []net.IP, ok bool, err error) { diff --git a/service/resolver/resolver.go b/service/resolver/resolver.go index 1a1a12f4..35d71329 100644 --- a/service/resolver/resolver.go +++ b/service/resolver/resolver.go @@ -17,17 +17,22 @@ import ( // DNS Resolver Attributes. const ( - ServerTypeDNS = "dns" - ServerTypeTCP = "tcp" - ServerTypeDoT = "dot" - ServerTypeDoH = "doh" - ServerTypeMDNS = "mdns" - ServerTypeEnv = "env" + ServerTypeDNS = "dns" + ServerTypeTCP = "tcp" + ServerTypeDoT = "dot" + ServerTypeDoH = "doh" + ServerTypeMDNS = "mdns" + ServerTypeEnv = "env" + ServerTypeMonitor = "monitor" + ServerTypeFirewall = "firewall" ServerSourceConfigured = "config" ServerSourceOperatingSystem = "system" ServerSourceMDNS = "mdns" ServerSourceEnv = "env" + ServerSourceETW = "etw" + ServerSourceSystemd = "systemd" + ServerSourceFirewall = "firewall" ) // DNS resolver scheme aliases. @@ -82,11 +87,11 @@ type ResolverInfo struct { //nolint:golint,maligned // TODO Name string // Type describes the type of the resolver. - // Possible values include dns, tcp, dot, doh, mdns, env. + // Possible values include dns, tcp, dot, doh, mdns, env, monitor, firewall. Type string // Source describes where the resolver configuration came from. - // Possible values include config, system, mdns, env. + // Possible values include config, system, mdns, env, etw, systemd, firewall. Source string // IP is the IP address of the resolver diff --git a/service/resolver/resolvers.go b/service/resolver/resolvers.go index c5609a01..45876b4e 100644 --- a/service/resolver/resolvers.go +++ b/service/resolver/resolvers.go @@ -388,7 +388,6 @@ func loadResolvers() { // Resolve module error about missing resolvers. module.states.Remove(missingResolversErrorID) - // Check if settings were changed and clear name cache when they did. newResolverConfig := configuredNameServers() if len(currentResolverConfig) > 0 && @@ -399,6 +398,14 @@ func loadResolvers() { return err }) } + + // If no resolvers are configure set the disabled state. So other modules knows that the users does not want to use Portmaster resolver. + if len(newResolverConfig) == 0 { + module.isDisabled.Store(true) + } else { + module.isDisabled.Store(false) + } + currentResolverConfig = newResolverConfig newResolvers := append( @@ -431,7 +438,7 @@ func loadResolvers() { // save resolvers globalResolvers = newResolvers - // assing resolvers to scopes + // assign resolvers to scopes setScopedResolvers(globalResolvers) // set active resolvers (for cache validation) diff --git a/windows_core_dll/build.ps1 b/windows_core_dll/build.ps1 new file mode 100644 index 00000000..d58f45ed --- /dev/null +++ b/windows_core_dll/build.ps1 @@ -0,0 +1,2 @@ +msbuild .\windows_core_dll.sln /p:Configuration=Release +ls .\x64\Release\portmaster-core.dll \ No newline at end of file diff --git a/windows_core_dll/dllmain.cpp b/windows_core_dll/dllmain.cpp new file mode 100644 index 00000000..cc0efaac --- /dev/null +++ b/windows_core_dll/dllmain.cpp @@ -0,0 +1,197 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "pch.h" + +#pragma comment(lib, "tdh.lib") + +// GUID of the DNS log provider +static const GUID DNS_CLIENT_PROVIDER_GUID = { + 0x1C95126E, + 0x7EEA, + 0x49A9, + {0xA3, 0xFE, 0xA3, 0x78, 0xB0, 0x3D, 0xDB, 0x4D} }; + +// GUID of the event session. This should be unique for the application. +static const GUID PORTMASTER_ETW_SESSION_GUID = { + 0x0211d070, + 0xc3b2, + 0x4609, + {0x92, 0xf5, 0x28, 0xe7, 0x18, 0xb2, 0x3b, 0x18} }; + +// Name of the session. This is visble when user queries all ETW sessions. +// (example `logman query -ets`) +#define LOGSESSION_NAME L"PortmasterDNSEventListener" + +// Fuction type of the callback that will be called on each event. +typedef uint64_t(*GoEventRecordCallback)(wchar_t* domain, wchar_t* result); + +// Holds the state of the ETW Session. +struct ETWSessionState { + TRACEHANDLE SessionTraceHandle; + EVENT_TRACE_PROPERTIES* SessionProperties; + TRACEHANDLE sessionHandle; + GoEventRecordCallback callback; +}; + +// getPropertyValue reads a property from the event. +static bool getPropertyValue(PEVENT_RECORD evt, LPWSTR prop, PBYTE* pData) { + // Describe the data that needs to be retrieved from the event. + PROPERTY_DATA_DESCRIPTOR DataDescriptor; + ZeroMemory(&DataDescriptor, sizeof(DataDescriptor)); + DataDescriptor.PropertyName = (ULONGLONG)(prop); + DataDescriptor.ArrayIndex = 0; + + DWORD PropertySize = 0; + // Check if the data is avaliable and what is the size of it. + DWORD status = + TdhGetPropertySize(evt, 0, NULL, 1, &DataDescriptor, &PropertySize); + if (ERROR_SUCCESS != status) { + return false; + } + + // Allocate memory for the data. + *pData = (PBYTE)malloc(PropertySize); + if (NULL == *pData) { + return false; + } + + // Get the data. + status = + TdhGetProperty(evt, 0, NULL, 1, &DataDescriptor, PropertySize, *pData); + if (ERROR_SUCCESS != status) { + if (*pData) { + free(*pData); + *pData = NULL; + } + return false; + } + + return true; +} + +// EventRecordCallback is a callback called on each event. +static void WINAPI EventRecordCallback(PEVENT_RECORD eventRecord) { + PBYTE resultValue = NULL; + PBYTE domainValue = NULL; + + getPropertyValue(eventRecord, (LPWSTR)L"QueryResults", &resultValue); + getPropertyValue(eventRecord, (LPWSTR)L"QueryName", &domainValue); + + ETWSessionState* state = (ETWSessionState*)eventRecord->UserContext; + + if (resultValue != NULL && domainValue != NULL) { + state->callback((wchar_t*)domainValue, (wchar_t*)resultValue); + } + + free(resultValue); + free(domainValue); +} + +extern "C" { + // PM_ETWCreateState allocates memory for the state and initializes the config for the session. PM_ETWDestroySession must be called to avoid leaks. + // callback must be set to a valid function pointer. + __declspec(dllexport) ETWSessionState* PM_ETWCreateState(GoEventRecordCallback callback) { + // Create trace session properties. + ULONG BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME); + EVENT_TRACE_PROPERTIES* SessionProperties = + (EVENT_TRACE_PROPERTIES*)calloc(1, BufferSize); + SessionProperties->Wnode.BufferSize = BufferSize; + SessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID; + SessionProperties->Wnode.ClientContext = 1; // QPC clock resolution + SessionProperties->Wnode.Guid = PORTMASTER_ETW_SESSION_GUID; + SessionProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE; + SessionProperties->MaximumFileSize = 1; // MB + SessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); + + // Create state + ETWSessionState* state = (ETWSessionState*)calloc(1, sizeof(ETWSessionState)); + state->SessionProperties = SessionProperties; + state->callback = callback; + return state; + } + + // PM_ETWInitializeSession initializes the session. + __declspec(dllexport) uint32_t PM_ETWInitializeSession(ETWSessionState* state) { + return StartTrace(&state->SessionTraceHandle, LOGSESSION_NAME, + state->SessionProperties); + } + + // PM_ETWStartTrace subscribes to the dns events and start listening. The function blocks while the listener is running. + // Call PM_ETWStopTrace to stop the listener. + __declspec(dllexport) uint32_t PM_ETWStartTrace(ETWSessionState* state) { + ULONG status = + EnableTraceEx2(state->SessionTraceHandle, (LPCGUID)&DNS_CLIENT_PROVIDER_GUID, + EVENT_CONTROL_CODE_ENABLE_PROVIDER, + TRACE_LEVEL_INFORMATION, 0, 0, 0, NULL); + + if (status != ERROR_SUCCESS) { + return status; + } + + EVENT_TRACE_LOGFILE trace = { 0 }; + + trace.LoggerName = (LPWSTR)(LOGSESSION_NAME); + trace.ProcessTraceMode = + PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD; + trace.EventRecordCallback = EventRecordCallback; + trace.Context = state; + + state->sessionHandle = OpenTrace(&trace); + if (state->sessionHandle == INVALID_PROCESSTRACE_HANDLE) { + return 1; + } + + status = ProcessTrace(&state->sessionHandle, 1, NULL, NULL); + if (status != ERROR_SUCCESS) { + return 1; + } + + return ERROR_SUCCESS; + } + + // PM_ETWFlushTrace flushes the event buffer. + __declspec(dllexport) uint32_t PM_ETWFlushTrace(ETWSessionState* state) { + return ControlTrace(state->SessionTraceHandle, LOGSESSION_NAME, + state->SessionProperties, EVENT_TRACE_CONTROL_FLUSH); + } + + // PM_ETWFlushTrace stops the listener. + __declspec(dllexport) uint32_t PM_ETWStopTrace(ETWSessionState* state) { + return ControlTrace(state->SessionTraceHandle, LOGSESSION_NAME, state->SessionProperties, + EVENT_TRACE_CONTROL_STOP); + } + + // PM_ETWFlushTrace Closes the session and frees resourses. + __declspec(dllexport) uint32_t PM_ETWDestroySession(ETWSessionState* state) { + if (state == NULL) { + return 1; + } + uint32_t status = CloseTrace(state->sessionHandle); + + // Free memory. + free(state->SessionProperties); + free(state); + return status; + } + + // PM_ETWStopOldSession removes old session with the same name if they exist. + // It returns success(0) only if its able to delete the old session. + __declspec(dllexport) ULONG PM_ETWStopOldSession() { + ULONG status = ERROR_SUCCESS; + TRACEHANDLE sessionHandle = 0; + + // Create trace session properties + size_t bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME); + EVENT_TRACE_PROPERTIES* sessionProperties = (EVENT_TRACE_PROPERTIES*)calloc(1, bufferSize); + sessionProperties->Wnode.BufferSize = (ULONG)bufferSize; + sessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID; + sessionProperties->Wnode.ClientContext = 1; // QPC clock resolution + sessionProperties->Wnode.Guid = PORTMASTER_ETW_SESSION_GUID; + sessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); + + // Use Control trace will stop the session which will trigger a delete. + status = ControlTrace(NULL, LOGSESSION_NAME, sessionProperties, EVENT_TRACE_CONTROL_STOP); + + free(sessionProperties); + return status; + } +} \ No newline at end of file diff --git a/windows_core_dll/framework.h b/windows_core_dll/framework.h new file mode 100644 index 00000000..a9744f82 --- /dev/null +++ b/windows_core_dll/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include diff --git a/windows_core_dll/pch.cpp b/windows_core_dll/pch.cpp new file mode 100644 index 00000000..91c22df2 --- /dev/null +++ b/windows_core_dll/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/windows_core_dll/pch.h b/windows_core_dll/pch.h new file mode 100644 index 00000000..e5658cac --- /dev/null +++ b/windows_core_dll/pch.h @@ -0,0 +1,22 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +// add headers that you want to pre-compile here +#include "framework.h" + +#include +#include +#include +#include +#include +#include +#include + + +#endif //PCH_H diff --git a/windows_core_dll/windows_core_dll.sln b/windows_core_dll/windows_core_dll.sln new file mode 100644 index 00000000..73d46ca7 --- /dev/null +++ b/windows_core_dll/windows_core_dll.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35222.181 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows_core_dll", "windows_core_dll.vcxproj", "{6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Debug|x64.ActiveCfg = Debug|x64 + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Debug|x64.Build.0 = Debug|x64 + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Debug|x86.ActiveCfg = Debug|Win32 + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Debug|x86.Build.0 = Debug|Win32 + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Release|x64.ActiveCfg = Release|x64 + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Release|x64.Build.0 = Release|x64 + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Release|x86.ActiveCfg = Release|Win32 + {6F3C7EAF-8511-4822-AAF0-1086D27E4DA9}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8E60106D-49DF-49C7-AC08-02775342FEAE} + EndGlobalSection +EndGlobal diff --git a/windows_core_dll/windows_core_dll.vcxproj b/windows_core_dll/windows_core_dll.vcxproj new file mode 100644 index 00000000..cf6d65f1 --- /dev/null +++ b/windows_core_dll/windows_core_dll.vcxproj @@ -0,0 +1,158 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {6f3c7eaf-8511-4822-aaf0-1086d27e4da9} + windowscoredll + 10.0 + portmaster-core + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;WINDOWSCOREDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;WINDOWSCOREDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;WINDOWSCOREDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;WINDOWSCOREDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/windows_core_dll/windows_core_dll.vcxproj.filters b/windows_core_dll/windows_core_dll.vcxproj.filters new file mode 100644 index 00000000..f99bb483 --- /dev/null +++ b/windows_core_dll/windows_core_dll.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/windows_core_dll/windows_core_dll.vcxproj.user b/windows_core_dll/windows_core_dll.vcxproj.user new file mode 100644 index 00000000..0f14913f --- /dev/null +++ b/windows_core_dll/windows_core_dll.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 706ce222d02a4f8a1062dfa64ae77eec58c6656d Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 27 Nov 2024 16:16:15 +0100 Subject: [PATCH 14/63] WIP --- base/info/version.go | 6 +- base/log/slog.go | 22 +- .../run.go => cmdbase/service.go} | 111 +++++++--- .../run_linux.go => cmdbase/service_linux.go} | 27 +-- .../service_windows.go} | 16 +- cmds/{portmaster-core => cmdbase}/update.go | 16 +- cmds/cmdbase/version.go | 20 ++ cmds/hub/main.go | 184 ++++++---------- cmds/observation-hub/main.go | 198 +++++++----------- cmds/portmaster-core/main.go | 52 +++-- cmds/portmaster-core/main_linux.go | 21 ++ cmds/portmaster-core/main_windows.go | 13 ++ cmds/portmaster-core/recover_linux.go | 19 +- cmds/testsuite/db.go | 2 +- cmds/trafficgen/main.go | 3 +- .../edit-profile-dialog.ts | 6 +- .../shared/netquery/line-chart/line-chart.ts | 2 +- .../shared/netquery/searchbar/searchbar.ts | 2 +- service/broadcasts/notify.go | 4 +- service/config.go | 75 ++++++- service/configure/updates.go | 65 ++++++ service/core/api.go | 128 ++++++++++- service/core/base/global.go | 46 ---- service/core/base/module.go | 10 +- service/core/core.go | 18 +- service/core/update_config.go | 134 ++++++++++++ service/core/update_versions.go | 176 ++++++++++++++++ service/instance.go | 28 ++- service/updates.go | 120 ----------- service/updates/downloader.go | 2 +- service/updates/index.go | 11 +- service/updates/index_scan.go | 11 +- service/updates/module.go | 132 +++++++++++- service/updates/upgrade.go | 2 - spn/instance.go | 57 ++--- 35 files changed, 1138 insertions(+), 601 deletions(-) rename cmds/{portmaster-core/run.go => cmdbase/service.go} (53%) rename cmds/{portmaster-core/run_linux.go => cmdbase/service_linux.go} (81%) rename cmds/{portmaster-core/run_windows.go => cmdbase/service_windows.go} (93%) rename cmds/{portmaster-core => cmdbase}/update.go (88%) create mode 100644 cmds/cmdbase/version.go create mode 100644 cmds/portmaster-core/main_linux.go create mode 100644 cmds/portmaster-core/main_windows.go create mode 100644 service/configure/updates.go delete mode 100644 service/core/base/global.go create mode 100644 service/core/update_config.go create mode 100644 service/core/update_versions.go delete mode 100644 service/updates.go diff --git a/base/info/version.go b/base/info/version.go index 2c6c3058..24247b0d 100644 --- a/base/info/version.go +++ b/base/info/version.go @@ -10,8 +10,6 @@ import ( "sync" ) -// FIXME: version does not show in portmaster - var ( name string license string @@ -167,9 +165,9 @@ func CondensedVersion() string { } return fmt.Sprintf( - "%s %s (%s; built with %s [%s %s] from %s [%s] at %s)", + "%s %s (%s/%s; built with %s [%s %s] from %s [%s] at %s)", info.Name, version, - runtime.GOOS, + runtime.GOOS, runtime.GOARCH, runtime.Version(), runtime.Compiler, cgoInfo, info.Commit, dirtyInfo, info.CommitTime, ) diff --git a/base/log/slog.go b/base/log/slog.go index 5901c146..65dec5ab 100644 --- a/base/log/slog.go +++ b/base/log/slog.go @@ -1,14 +1,19 @@ package log import ( + "io" "log/slog" "os" "runtime" "github.com/lmittmann/tint" + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" ) func setupSLog(level Severity) { + // TODO: Changes in the log level are not yet reflected onto the slog handlers in the modules. + // Set highest possible level, so it can be changed in runtime. handlerLogLevel := level.toSLogLevel() @@ -17,21 +22,23 @@ func setupSLog(level Severity) { switch runtime.GOOS { case "windows": logHandler = tint.NewHandler( - GlobalWriter, + windowsColoring(GlobalWriter), // Enable coloring on Windows. &tint.Options{ AddSource: true, Level: handlerLogLevel, TimeFormat: timeFormat, - NoColor: !GlobalWriter.IsStdout(), // FIXME: also check for tty. + NoColor: !( /* Color: */ GlobalWriter.IsStdout() && isatty.IsTerminal(GlobalWriter.file.Fd())), }, ) + case "linux": logHandler = tint.NewHandler(GlobalWriter, &tint.Options{ AddSource: true, Level: handlerLogLevel, TimeFormat: timeFormat, - NoColor: !GlobalWriter.IsStdout(), // FIXME: also check for tty. + NoColor: !( /* Color: */ GlobalWriter.IsStdout() && isatty.IsTerminal(GlobalWriter.file.Fd())), }) + default: logHandler = tint.NewHandler(os.Stdout, &tint.Options{ AddSource: true, @@ -43,6 +50,11 @@ func setupSLog(level Severity) { // Set as default logger. slog.SetDefault(slog.New(logHandler)) - // Set actual log level. - slog.SetLogLoggerLevel(handlerLogLevel) +} + +func windowsColoring(lw *LogWriter) io.Writer { + if lw.IsStdout() { + return colorable.NewColorable(lw.file) + } + return lw } diff --git a/cmds/portmaster-core/run.go b/cmds/cmdbase/service.go similarity index 53% rename from cmds/portmaster-core/run.go rename to cmds/cmdbase/service.go index 6c41bd56..28bc5e60 100644 --- a/cmds/portmaster-core/run.go +++ b/cmds/cmdbase/service.go @@ -1,12 +1,14 @@ -package main +package cmdbase import ( + "context" "errors" - "flag" "fmt" "io" "log/slog" "os" + "os/exec" + "runtime" "runtime/pprof" "time" @@ -15,14 +17,12 @@ import ( "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/service" "github.com/safing/portmaster/service/mgr" - "github.com/safing/portmaster/spn/conf" ) -var printStackOnExit bool - -func init() { - flag.BoolVar(&printStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down") -} +var ( + RebootOnRestart bool + PrintStackOnExit bool +) type SystemService interface { Run() @@ -30,21 +30,47 @@ type SystemService interface { RestartService() error } -func cmdRun(cmd *cobra.Command, args []string) { - // Run platform specific setup or switches. - runPlatformSpecifics(cmd, args) +type ServiceInstance interface { + Ready() bool + Start() error + Stop() error + Restart() + Shutdown() + Ctx() context.Context + IsShuttingDown() bool + ShuttingDown() <-chan struct{} + ShutdownCtx() context.Context + IsShutDown() bool + ShutdownComplete() <-chan struct{} + ExitCode() int + ShouldRestartIsSet() bool + CommandLineOperationIsSet() bool + CommandLineOperationExecute() error +} - // SETUP +var ( + SvcFactory func(*service.ServiceConfig) (ServiceInstance, error) + SvcConfig *service.ServiceConfig +) - // Enable SPN client mode. - // TODO: Move this to service config. - conf.EnableClient(true) - conf.EnableIntegration(true) +func RunService(cmd *cobra.Command, args []string) { + if SvcFactory == nil || SvcConfig == nil { + fmt.Fprintln(os.Stderr, "internal error: service not set up in cmdbase") + os.Exit(1) + } + + // Start logging. + // Note: Must be created before the service instance, so that they use the right logger. + err := log.Start(SvcConfig.LogLevel, SvcConfig.LogToStdout, SvcConfig.LogDir) + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(4) + } // Create instance. // Instance modules might request a cmdline execution of a function. var execCmdLine bool - instance, err := service.New(svcCfg) + instance, err := SvcFactory(SvcConfig) switch { case err == nil: // Continue @@ -59,13 +85,13 @@ func cmdRun(cmd *cobra.Command, args []string) { switch { case !execCmdLine: // Run service. - case instance.CommandLineOperation == nil: + case !instance.CommandLineOperationIsSet(): fmt.Println("command line operation execution requested, but not set") os.Exit(3) default: // Run the function and exit. fmt.Println("executing cmdline op") - err = instance.CommandLineOperation() + err = instance.CommandLineOperationExecute() if err != nil { fmt.Fprintf(os.Stderr, "command line operation failed: %s\n", err) os.Exit(3) @@ -75,16 +101,6 @@ func cmdRun(cmd *cobra.Command, args []string) { // START - // FIXME: fix color and duplicate level when logging with slog - // FIXME: check for tty for color enabling - - // Start logging. - err = log.Start(svcCfg.LogLevel, svcCfg.LogToStdout, svcCfg.LogDir) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - os.Exit(4) - } - // Create system service. service := NewSystemService(instance) @@ -102,7 +118,7 @@ func cmdRun(cmd *cobra.Command, args []string) { select { case <-instance.ShutdownComplete(): // Print stack on shutdown, if enabled. - if printStackOnExit { + if PrintStackOnExit { printStackTo(log.GlobalWriter, "PRINTING STACK ON EXIT") } case <-time.After(3 * time.Minute): @@ -110,9 +126,22 @@ func cmdRun(cmd *cobra.Command, args []string) { } // Check if restart was triggered and send start service command if true. - if instance.ShouldRestart && service.IsService() { - if err := service.RestartService(); err != nil { - slog.Error("failed to restart service", "err", err) + if instance.ShouldRestartIsSet() && service.IsService() { + // Check if we should reboot instead. + var rebooting bool + if RebootOnRestart { + // Trigger system reboot and record success. + rebooting = triggerSystemReboot() + if !rebooting { + log.Warningf("updates: rebooting failed, only restarting service instead") + } + } + + // Restart service if not rebooting. + if !rebooting { + if err := service.RestartService(); err != nil { + slog.Error("failed to restart service", "err", err) + } } } @@ -138,3 +167,19 @@ func printStackTo(writer io.Writer, msg string) { slog.Error("failed to write stack trace", "err", err) } } + +func triggerSystemReboot() (success bool) { + switch runtime.GOOS { + case "linux": + err := exec.Command("systemctl", "reboot").Run() + if err != nil { + log.Errorf("updates: triggering reboot with systemctl failed: %s", err) + return false + } + default: + log.Warningf("updates: rebooting is not support on %s", runtime.GOOS) + return false + } + + return true +} diff --git a/cmds/portmaster-core/run_linux.go b/cmds/cmdbase/service_linux.go similarity index 81% rename from cmds/portmaster-core/run_linux.go rename to cmds/cmdbase/service_linux.go index 858ed022..085b8649 100644 --- a/cmds/portmaster-core/run_linux.go +++ b/cmds/cmdbase/service_linux.go @@ -1,4 +1,4 @@ -package main +package cmdbase import ( "fmt" @@ -9,17 +9,15 @@ import ( "syscall" processInfo "github.com/shirou/gopsutil/process" - "github.com/spf13/cobra" "github.com/safing/portmaster/base/log" - "github.com/safing/portmaster/service" ) type LinuxSystemService struct { - instance *service.Instance + instance ServiceInstance } -func NewSystemService(instance *service.Instance) *LinuxSystemService { +func NewSystemService(instance ServiceInstance) *LinuxSystemService { return &LinuxSystemService{instance: instance} } @@ -30,7 +28,7 @@ func (s *LinuxSystemService) Run() { slog.Error("failed to start", "err", err) // Print stack on start failure, if enabled. - if printStackOnExit { + if PrintStackOnExit { printStackTo(log.GlobalWriter, "PRINTING STACK ON START FAILURE") } @@ -62,7 +60,7 @@ wait: continue wait } else { // Trigger shutdown. - fmt.Printf(" ", sig) // CLI output. + fmt.Printf(" \n", sig) // CLI output. slog.Warn("received stop signal", "signal", sig) s.instance.Shutdown() break wait @@ -128,18 +126,3 @@ func (s *LinuxSystemService) IsService() bool { // Check if the parent process ID is 1 == init system return ppid == 1 } - -func runPlatformSpecifics(cmd *cobra.Command, args []string) { - // If recover-iptables flag is set, run the recover-iptables command. - // This is for backwards compatibility - if recoverIPTables { - exitCode := 0 - err := recover(cmd, args) - if err != nil { - fmt.Printf("failed: %s", err) - exitCode = 1 - } - - os.Exit(exitCode) - } -} diff --git a/cmds/portmaster-core/run_windows.go b/cmds/cmdbase/service_windows.go similarity index 93% rename from cmds/portmaster-core/run_windows.go rename to cmds/cmdbase/service_windows.go index 09593630..fdb6df74 100644 --- a/cmds/portmaster-core/run_windows.go +++ b/cmds/cmdbase/service_windows.go @@ -1,4 +1,4 @@ -package main +package cmdbase // Based on the official Go examples from // https://github.com/golang/sys/blob/master/windows/svc/example @@ -13,21 +13,19 @@ import ( "os/signal" "syscall" - "github.com/spf13/cobra" "golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc/debug" "github.com/safing/portmaster/base/log" - "github.com/safing/portmaster/service" ) const serviceName = "PortmasterCore" type WindowsSystemService struct { - instance *service.Instance + instance ServiceInstance } -func NewSystemService(instance *service.Instance) *WindowsSystemService { +func NewSystemService(instance ServiceInstance) *WindowsSystemService { return &WindowsSystemService{instance: instance} } @@ -67,7 +65,7 @@ func (s *WindowsSystemService) Execute(args []string, changeRequests <-chan svc. fmt.Printf("failed to start: %s\n", err) // Print stack on start failure, if enabled. - if printStackOnExit { + if PrintStackOnExit { printStackTo(log.GlobalWriter, "PRINTING STACK ON START FAILURE") } @@ -102,7 +100,7 @@ waitSignal: select { case sig := <-signalCh: // Trigger shutdown. - fmt.Printf(" ", sig) // CLI output. + fmt.Printf(" \n", sig) // CLI output. slog.Warn("received stop signal", "signal", sig) break waitSignal @@ -112,7 +110,7 @@ waitSignal: changes <- c.CurrentStatus case svc.Stop, svc.Shutdown: - fmt.Printf(" ", serviceCmdName(c.Cmd)) // CLI output. + fmt.Printf(" \n", serviceCmdName(c.Cmd)) // CLI output. slog.Warn("received service shutdown command", "cmd", c.Cmd) break waitSignal @@ -201,8 +199,6 @@ sc.exe start $serviceName` return nil } -func runPlatformSpecifics(cmd *cobra.Command, args []string) - func serviceCmdName(cmd svc.Cmd) string { switch cmd { case svc.Stop: diff --git a/cmds/portmaster-core/update.go b/cmds/cmdbase/update.go similarity index 88% rename from cmds/portmaster-core/update.go rename to cmds/cmdbase/update.go index 866aab61..65c20a83 100644 --- a/cmds/portmaster-core/update.go +++ b/cmds/cmdbase/update.go @@ -1,4 +1,4 @@ -package main +package cmdbase import ( "fmt" @@ -12,32 +12,28 @@ import ( "github.com/safing/portmaster/service/updates" ) -var updateCmd = &cobra.Command{ +var UpdateCmd = &cobra.Command{ Use: "update", Short: "Force an update of all components.", RunE: update, } -func init() { - rootCmd.AddCommand(updateCmd) -} - func update(cmd *cobra.Command, args []string) error { // Finalize config. - err := svcCfg.Init() + err := SvcConfig.Init() if err != nil { return fmt.Errorf("internal configuration error: %w", err) } // Force logging to stdout. - svcCfg.LogToStdout = true + SvcConfig.LogToStdout = true // Start logging. - _ = log.Start(svcCfg.LogLevel, svcCfg.LogToStdout, svcCfg.LogDir) + _ = log.Start(SvcConfig.LogLevel, SvcConfig.LogToStdout, SvcConfig.LogDir) defer log.Shutdown() // Create updaters. instance := &updateDummyInstance{} - binaryUpdateConfig, intelUpdateConfig, err := service.MakeUpdateConfigs(svcCfg) + binaryUpdateConfig, intelUpdateConfig, err := service.MakeUpdateConfigs(SvcConfig) if err != nil { return fmt.Errorf("init updater config: %w", err) } diff --git a/cmds/cmdbase/version.go b/cmds/cmdbase/version.go new file mode 100644 index 00000000..86244dac --- /dev/null +++ b/cmds/cmdbase/version.go @@ -0,0 +1,20 @@ +package cmdbase + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/safing/portmaster/base/info" +) + +var VersionCmd = &cobra.Command{ + Use: "version", + Short: "Show version and related metadata.", + RunE: Version, +} + +func Version(cmd *cobra.Command, args []string) error { + fmt.Println(info.FullVersion()) + return nil +} diff --git a/cmds/hub/main.go b/cmds/hub/main.go index 1fdc8809..1e4e5116 100644 --- a/cmds/hub/main.go +++ b/cmds/hub/main.go @@ -1,158 +1,94 @@ package main import ( - "errors" "flag" "fmt" - "io" - "log/slog" "os" - "os/signal" "runtime" - "runtime/pprof" - "syscall" - "time" + + "github.com/spf13/cobra" "github.com/safing/portmaster/base/info" - "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/metrics" - "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/cmds/cmdbase" + "github.com/safing/portmaster/service" + "github.com/safing/portmaster/service/configure" "github.com/safing/portmaster/service/updates" - "github.com/safing/portmaster/spn" "github.com/safing/portmaster/spn/conf" ) +var ( + rootCmd = &cobra.Command{ + Use: "spn-hub", + PersistentPreRun: initializeGlobals, + Run: cmdbase.RunService, + } + + binDir string + dataDir string + + logToStdout bool + logDir string + logLevel string +) + func init() { - // flag.BoolVar(&updates.RebootOnRestart, "reboot-on-restart", false, "reboot server on auto-upgrade") - // FIXME + // Add persisent flags for all commands. + rootCmd.PersistentFlags().StringVar(&binDir, "bin-dir", "", "set directory for executable binaries (rw/ro)") + rootCmd.PersistentFlags().StringVar(&dataDir, "data-dir", "", "set directory for variable data (rw)") + + // Add flags for service only. + rootCmd.Flags().BoolVar(&logToStdout, "log-stdout", false, "log to stdout instead of file") + rootCmd.Flags().StringVar(&logDir, "log-dir", "", "set directory for logs") + rootCmd.Flags().StringVar(&logLevel, "log", "", "set log level to [trace|debug|info|warning|error|critical]") + rootCmd.Flags().BoolVar(&cmdbase.PrintStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down") + rootCmd.Flags().BoolVar(&cmdbase.RebootOnRestart, "reboot-on-restart", false, "reboot server instead of service restart") + + // Add other commands. + rootCmd.AddCommand(cmdbase.VersionCmd) + rootCmd.AddCommand(cmdbase.UpdateCmd) } -var sigUSR1 = syscall.Signal(0xa) - func main() { - flag.Parse() + // Add Go's default flag set. + // TODO: Move flags throughout Portmaster to here and add their values to the service config. + rootCmd.Flags().AddGoFlagSet(flag.CommandLine) - // Set name and license. + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func initializeGlobals(cmd *cobra.Command, args []string) { + // Set version info. info.Set("SPN Hub", "", "GPLv3") // Configure metrics. _ = metrics.SetNamespace("hub") - // Configure user agent and updates. + // Configure user agent. updates.UserAgent = fmt.Sprintf("SPN Hub (%s %s)", runtime.GOOS, runtime.GOARCH) - // helper.IntelOnly() // Set SPN public hub mode. conf.EnablePublicHub(true) - // Start logger with default log level. - _ = log.Start(log.WarningLevel) - - // FIXME: Use service? - - // Create instance. - var execCmdLine bool - instance, err := spn.New() - switch { - case err == nil: - // Continue - case errors.Is(err, mgr.ErrExecuteCmdLineOp): - execCmdLine = true - default: - fmt.Printf("error creating an instance: %s\n", err) - os.Exit(2) + // Configure service. + cmdbase.SvcFactory = func(svcCfg *service.ServiceConfig) (cmdbase.ServiceInstance, error) { + svc, err := service.New(svcCfg) + return svc, err } + cmdbase.SvcConfig = &service.ServiceConfig{ + BinDir: binDir, + DataDir: dataDir, - // Execute command line operation, if requested or available. - switch { - case !execCmdLine: - // Run service. - case instance.CommandLineOperation == nil: - fmt.Println("command line operation execution requested, but not set") - os.Exit(3) - default: - // Run the function and exit. - err = instance.CommandLineOperation() - if err != nil { - fmt.Fprintf(os.Stderr, "command line operation failed: %s\n", err) - os.Exit(3) - } - os.Exit(0) - } + LogToStdout: logToStdout, + LogDir: logDir, + LogLevel: logLevel, - // Start - go func() { - err = instance.Start() - if err != nil { - fmt.Printf("instance start failed: %s\n", err) - os.Exit(1) - } - }() - - // Wait for signal. - signalCh := make(chan os.Signal, 1) - signal.Notify( - signalCh, - os.Interrupt, - syscall.SIGHUP, - syscall.SIGINT, - syscall.SIGTERM, - syscall.SIGQUIT, - sigUSR1, - ) - - select { - case sig := <-signalCh: - // Only print and continue to wait if SIGUSR1 - if sig == sigUSR1 { - printStackTo(os.Stderr, "PRINTING STACK ON REQUEST") - } else { - fmt.Println(" ") // CLI output. - slog.Warn("program was interrupted, stopping") - } - - case <-instance.ShutdownComplete(): - log.Shutdown() - os.Exit(instance.ExitCode()) - } - - // Catch signals during shutdown. - // Rapid unplanned disassembly after 5 interrupts. - go func() { - forceCnt := 5 - for { - <-signalCh - forceCnt-- - if forceCnt > 0 { - fmt.Printf(" again, but already shutting down - %d more to force\n", forceCnt) - } else { - printStackTo(os.Stderr, "PRINTING STACK ON FORCED EXIT") - os.Exit(1) - } - } - }() - - // Rapid unplanned disassembly after 3 minutes. - go func() { - time.Sleep(3 * time.Minute) - printStackTo(os.Stderr, "PRINTING STACK - TAKING TOO LONG FOR SHUTDOWN") - os.Exit(1) - }() - - // Stop instance. - if err := instance.Stop(); err != nil { - slog.Error("failed to stop", "err", err) - } - log.Shutdown() - os.Exit(instance.ExitCode()) -} - -func printStackTo(writer io.Writer, msg string) { - _, err := fmt.Fprintf(writer, "===== %s =====\n", msg) - if err == nil { - err = pprof.Lookup("goroutine").WriteTo(writer, 1) - } - if err != nil { - slog.Error("failed to write stack trace", "err", err) + BinariesIndexURLs: configure.DefaultStableBinaryIndexURLs, + IntelIndexURLs: configure.DefaultIntelIndexURLs, + VerifyBinaryUpdates: configure.BinarySigningTrustStore, + VerifyIntelUpdates: configure.BinarySigningTrustStore, } } diff --git a/cmds/observation-hub/main.go b/cmds/observation-hub/main.go index 598680f0..ec34d53b 100644 --- a/cmds/observation-hub/main.go +++ b/cmds/observation-hub/main.go @@ -1,41 +1,75 @@ package main import ( - "errors" "flag" "fmt" - "io" - "log/slog" "os" - "os/signal" "runtime" - "runtime/pprof" - "syscall" - "time" "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/info" - "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/metrics" - "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/cmds/cmdbase" + "github.com/safing/portmaster/service" + "github.com/safing/portmaster/service/configure" "github.com/safing/portmaster/service/updates" - "github.com/safing/portmaster/spn" "github.com/safing/portmaster/spn/captain" "github.com/safing/portmaster/spn/conf" "github.com/safing/portmaster/spn/sluice" + "github.com/spf13/cobra" ) -var sigUSR1 = syscall.Signal(0xa) +var ( + rootCmd = &cobra.Command{ + Use: "observation-hub", + PersistentPreRun: initializeGlobals, + Run: cmdbase.RunService, + } + + binDir string + dataDir string + + logToStdout bool + logDir string + logLevel string +) + +func init() { + // Add persisent flags for all commands. + rootCmd.PersistentFlags().StringVar(&binDir, "bin-dir", "", "set directory for executable binaries (rw/ro)") + rootCmd.PersistentFlags().StringVar(&dataDir, "data-dir", "", "set directory for variable data (rw)") + + // Add flags for service only. + rootCmd.Flags().BoolVar(&logToStdout, "log-stdout", false, "log to stdout instead of file") + rootCmd.Flags().StringVar(&logDir, "log-dir", "", "set directory for logs") + rootCmd.Flags().StringVar(&logLevel, "log", "", "set log level to [trace|debug|info|warning|error|critical]") + rootCmd.Flags().BoolVar(&cmdbase.PrintStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down") + rootCmd.Flags().BoolVar(&cmdbase.RebootOnRestart, "reboot-on-restart", false, "reboot server instead of service restart") + + // Add other commands. + rootCmd.AddCommand(cmdbase.VersionCmd) + rootCmd.AddCommand(cmdbase.UpdateCmd) +} func main() { - flag.Parse() + // Add Go's default flag set. + // TODO: Move flags throughout Portmaster to here and add their values to the service config. + rootCmd.Flags().AddGoFlagSet(flag.CommandLine) + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func initializeGlobals(cmd *cobra.Command, args []string) { + // Set version info. info.Set("SPN Observation Hub", "", "GPLv3") // Configure metrics. _ = metrics.SetNamespace("observer") - // Configure user agent and updates. + // Configure user agent. updates.UserAgent = fmt.Sprintf("SPN Observation Hub (%s %s)", runtime.GOOS, runtime.GOARCH) // Configure SPN mode. @@ -46,129 +80,37 @@ func main() { sluice.EnableListener = false api.EnableServer = false - // Start logger with default log level. - _ = log.Start(log.WarningLevel) + // Configure service. + cmdbase.SvcFactory = func(svcCfg *service.ServiceConfig) (cmdbase.ServiceInstance, error) { + svc, err := service.New(svcCfg) - // Create instance. - var execCmdLine bool - instance, err := spn.New() - switch { - case err == nil: - // Continue - case errors.Is(err, mgr.ErrExecuteCmdLineOp): - execCmdLine = true - default: - fmt.Printf("error creating an instance: %s\n", err) - os.Exit(2) - } - - // Add additional modules. - observer, err := New(instance) - if err != nil { - fmt.Printf("error creating an instance: create observer module: %s\n", err) - os.Exit(2) - } - instance.AddModule(observer) - - _, err = NewApprise(instance) - if err != nil { - fmt.Printf("error creating an instance: create apprise module: %s\n", err) - os.Exit(2) - } - instance.AddModule(observer) - - // FIXME: Use service? - - // Execute command line operation, if requested or available. - switch { - case !execCmdLine: - // Run service. - case instance.CommandLineOperation == nil: - fmt.Println("command line operation execution requested, but not set") - os.Exit(3) - default: - // Run the function and exit. - err = instance.CommandLineOperation() + // Add additional modules. + observer, err := New(svc) if err != nil { - fmt.Fprintf(os.Stderr, "command line operation failed: %s\n", err) - os.Exit(3) + fmt.Printf("error creating an instance: create observer module: %s\n", err) + os.Exit(2) } - os.Exit(0) - } - - // Start - go func() { - err = instance.Start() + svc.AddModule(observer) + _, err = NewApprise(svc) if err != nil { - fmt.Printf("instance start failed: %s\n", err) - os.Exit(1) + fmt.Printf("error creating an instance: create apprise module: %s\n", err) + os.Exit(2) } - }() + svc.AddModule(observer) - // Wait for signal. - signalCh := make(chan os.Signal, 1) - signal.Notify( - signalCh, - os.Interrupt, - syscall.SIGHUP, - syscall.SIGINT, - syscall.SIGTERM, - syscall.SIGQUIT, - sigUSR1, - ) - - select { - case sig := <-signalCh: - // Only print and continue to wait if SIGUSR1 - if sig == sigUSR1 { - printStackTo(os.Stderr, "PRINTING STACK ON REQUEST") - } else { - fmt.Println(" ") // CLI output. - slog.Warn("program was interrupted, stopping") - } - - case <-instance.ShuttingDown(): - log.Shutdown() - os.Exit(instance.ExitCode()) + return svc, err } + cmdbase.SvcConfig = &service.ServiceConfig{ + BinDir: binDir, + DataDir: dataDir, - // Catch signals during shutdown. - // Rapid unplanned disassembly after 5 interrupts. - go func() { - forceCnt := 5 - for { - <-signalCh - forceCnt-- - if forceCnt > 0 { - fmt.Printf(" again, but already shutting down - %d more to force\n", forceCnt) - } else { - printStackTo(os.Stderr, "PRINTING STACK ON FORCED EXIT") - os.Exit(1) - } - } - }() + LogToStdout: logToStdout, + LogDir: logDir, + LogLevel: logLevel, - // Rapid unplanned disassembly after 3 minutes. - go func() { - time.Sleep(3 * time.Minute) - printStackTo(os.Stderr, "PRINTING STACK - TAKING TOO LONG FOR SHUTDOWN") - os.Exit(1) - }() - - // Stop instance. - if err := instance.Stop(); err != nil { - slog.Error("failed to stop", "err", err) - } - log.Shutdown() - os.Exit(instance.ExitCode()) -} - -func printStackTo(writer io.Writer, msg string) { - _, err := fmt.Fprintf(writer, "===== %s =====\n", msg) - if err == nil { - err = pprof.Lookup("goroutine").WriteTo(writer, 1) - } - if err != nil { - slog.Error("failed to write stack trace", "err", err) + BinariesIndexURLs: configure.DefaultStableBinaryIndexURLs, + IntelIndexURLs: configure.DefaultIntelIndexURLs, + VerifyBinaryUpdates: configure.BinarySigningTrustStore, + VerifyIntelUpdates: configure.BinarySigningTrustStore, } } diff --git a/cmds/portmaster-core/main.go b/cmds/portmaster-core/main.go index 8cd80864..12456f58 100644 --- a/cmds/portmaster-core/main.go +++ b/cmds/portmaster-core/main.go @@ -10,7 +10,9 @@ import ( "github.com/safing/portmaster/base/info" "github.com/safing/portmaster/base/metrics" + "github.com/safing/portmaster/cmds/cmdbase" "github.com/safing/portmaster/service" + "github.com/safing/portmaster/service/configure" "github.com/safing/portmaster/service/updates" ) @@ -18,7 +20,7 @@ var ( rootCmd = &cobra.Command{ Use: "portmaster-core", PersistentPreRun: initializeGlobals, - Run: cmdRun, + Run: mainRun, } binDir string @@ -28,14 +30,10 @@ var ( logDir string logLevel string - svcCfg *service.ServiceConfig + printVersion bool ) func init() { - // Add Go's default flag set. - // TODO: Move flags throughout Portmaster to here and add their values to the service config. - rootCmd.Flags().AddGoFlagSet(flag.CommandLine) - // Add persisent flags for all commands. rootCmd.PersistentFlags().StringVar(&binDir, "bin-dir", "", "set directory for executable binaries (rw/ro)") rootCmd.PersistentFlags().StringVar(&dataDir, "data-dir", "", "set directory for variable data (rw)") @@ -44,17 +42,32 @@ func init() { rootCmd.Flags().BoolVar(&logToStdout, "log-stdout", false, "log to stdout instead of file") rootCmd.Flags().StringVar(&logDir, "log-dir", "", "set directory for logs") rootCmd.Flags().StringVar(&logLevel, "log", "", "set log level to [trace|debug|info|warning|error|critical]") + rootCmd.Flags().BoolVar(&printVersion, "version", false, "print version (backward compatibility; use command instead)") + rootCmd.Flags().BoolVar(&cmdbase.PrintStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down") + + // Add other commands. + rootCmd.AddCommand(cmdbase.VersionCmd) + rootCmd.AddCommand(cmdbase.UpdateCmd) } func main() { + // Add Go's default flag set. + // TODO: Move flags throughout Portmaster to here and add their values to the service config. + rootCmd.Flags().AddGoFlagSet(flag.CommandLine) + if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } +func mainRun(cmd *cobra.Command, args []string) { + runPlatformSpecifics(cmd, args) + cmdbase.RunService(cmd, args) +} + func initializeGlobals(cmd *cobra.Command, args []string) { - // set information + // Set version info. info.Set("Portmaster", "", "GPLv3") // Configure metrics. @@ -63,8 +76,12 @@ func initializeGlobals(cmd *cobra.Command, args []string) { // Configure user agent. updates.UserAgent = fmt.Sprintf("Portmaster Core (%s %s)", runtime.GOOS, runtime.GOARCH) - // Create service config. - svcCfg = &service.ServiceConfig{ + // Configure service. + cmdbase.SvcFactory = func(svcCfg *service.ServiceConfig) (cmdbase.ServiceInstance, error) { + svc, err := service.New(svcCfg) + return svc, err + } + cmdbase.SvcConfig = &service.ServiceConfig{ BinDir: binDir, DataDir: dataDir, @@ -72,9 +89,18 @@ func initializeGlobals(cmd *cobra.Command, args []string) { LogDir: logDir, LogLevel: logLevel, - BinariesIndexURLs: service.DefaultStableBinaryIndexURLs, - IntelIndexURLs: service.DefaultIntelIndexURLs, - VerifyBinaryUpdates: service.BinarySigningTrustStore, - VerifyIntelUpdates: service.BinarySigningTrustStore, + BinariesIndexURLs: configure.DefaultStableBinaryIndexURLs, + IntelIndexURLs: configure.DefaultIntelIndexURLs, + VerifyBinaryUpdates: configure.BinarySigningTrustStore, + VerifyIntelUpdates: configure.BinarySigningTrustStore, } } + +func runFlagCmd(fn func(cmd *cobra.Command, args []string) error, cmd *cobra.Command, args []string) { + if err := fn(cmd, args); err != nil { + fmt.Printf("failed: %s\n", err) + os.Exit(1) + } + + os.Exit(0) +} diff --git a/cmds/portmaster-core/main_linux.go b/cmds/portmaster-core/main_linux.go new file mode 100644 index 00000000..e4d4783d --- /dev/null +++ b/cmds/portmaster-core/main_linux.go @@ -0,0 +1,21 @@ +package main + +import ( + "github.com/safing/portmaster/cmds/cmdbase" + "github.com/spf13/cobra" +) + +var recoverIPTablesFlag bool + +func init() { + rootCmd.Flags().BoolVar(&recoverIPTablesFlag, "recover-iptables", false, "recovers ip table rules (backward compatibility; use command instead)") +} + +func runPlatformSpecifics(cmd *cobra.Command, args []string) { + switch { + case printVersion: + runFlagCmd(cmdbase.Version, cmd, args) + case recoverIPTablesFlag: + runFlagCmd(recoverIPTables, cmd, args) + } +} diff --git a/cmds/portmaster-core/main_windows.go b/cmds/portmaster-core/main_windows.go new file mode 100644 index 00000000..5d2066f3 --- /dev/null +++ b/cmds/portmaster-core/main_windows.go @@ -0,0 +1,13 @@ +package main + +import ( + "github.com/safing/portmaster/cmds/cmdbase" + "github.com/spf13/cobra" +) + +func runPlatformSpecifics(cmd *cobra.Command, args []string) { + switch { + case printVersion: + runFlagCmd(cmdbase.Version, cmd, args) + } +} diff --git a/cmds/portmaster-core/recover_linux.go b/cmds/portmaster-core/recover_linux.go index 6f5532c2..61fecda7 100644 --- a/cmds/portmaster-core/recover_linux.go +++ b/cmds/portmaster-core/recover_linux.go @@ -2,7 +2,6 @@ package main import ( "errors" - "flag" "fmt" "os" "strings" @@ -13,23 +12,17 @@ import ( "github.com/safing/portmaster/service/firewall/interception" ) -var ( - recoverCmd = &cobra.Command{ - Use: "recover-iptables", - Short: "Force an update of all components.", - RunE: update, - } - - recoverIPTables bool -) +var recoverCmd = &cobra.Command{ + Use: "recover-iptables", + Short: "Clean up Portmaster rules in iptables", + RunE: recoverIPTables, +} func init() { rootCmd.AddCommand(recoverCmd) - - flag.BoolVar(&recoverIPTables, "recover-iptables", false, "recovers ip table rules (backward compatibility; use command instead)") } -func recover(cmd *cobra.Command, args []string) error { +func recoverIPTables(cmd *cobra.Command, args []string) error { // interception.DeactiveNfqueueFirewall uses coreos/go-iptables // which shells out to the /sbin/iptables binary. As a result, // we don't get the errno of the actual error and need to parse the diff --git a/cmds/testsuite/db.go b/cmds/testsuite/db.go index b23a6fd7..44286a8c 100644 --- a/cmds/testsuite/db.go +++ b/cmds/testsuite/db.go @@ -6,7 +6,7 @@ import ( ) func setupDatabases(path string) error { - err := database.InitializeWithPath(path) + err := database.Initialize(path) if err != nil { return err } diff --git a/cmds/trafficgen/main.go b/cmds/trafficgen/main.go index efcfd390..59f8aeca 100644 --- a/cmds/trafficgen/main.go +++ b/cmds/trafficgen/main.go @@ -37,13 +37,12 @@ func main() { } // Start logging. - err := log.Start() + err := log.Start("trace", true, "") if err != nil { fmt.Printf("failed to start logging: %s\n", err) os.Exit(1) } defer log.Shutdown() - log.SetLogLevel(log.TraceLevel) log.Info("starting traffic generator") // Execute requests diff --git a/desktop/angular/src/app/shared/edit-profile-dialog/edit-profile-dialog.ts b/desktop/angular/src/app/shared/edit-profile-dialog/edit-profile-dialog.ts index 60b5b514..2528d81a 100644 --- a/desktop/angular/src/app/shared/edit-profile-dialog/edit-profile-dialog.ts +++ b/desktop/angular/src/app/shared/edit-profile-dialog/edit-profile-dialog.ts @@ -238,13 +238,13 @@ export class EditProfileDialog implements OnInit, OnDestroy { this.portapi.delete(icon.Value).subscribe(); } - // FIXME(ppacher): we cannot yet delete API based icons ... + // TODO(ppacher): we cannot yet delete API based icons ... }); if (this.iconData !== '') { // save the new icon in the cache database - // FIXME(ppacher): we currently need to calls because the icon API in portmaster + // TODO(ppacher): we currently need to calls because the icon API in portmaster // does not update the profile but just saves the file and returns the filename. // So we still need to update the profile manually. updateIcon = this.profileService @@ -261,7 +261,7 @@ export class EditProfileDialog implements OnInit, OnDestroy { }) ); - // FIXME(ppacher): reset presentationpath + // TODO(ppacher): reset presentationpath } else { // just clear out that there was an icon this.profile.Icons = []; diff --git a/desktop/angular/src/app/shared/netquery/line-chart/line-chart.ts b/desktop/angular/src/app/shared/netquery/line-chart/line-chart.ts index 8d95a061..23a9007c 100644 --- a/desktop/angular/src/app/shared/netquery/line-chart/line-chart.ts +++ b/desktop/angular/src/app/shared/netquery/line-chart/line-chart.ts @@ -543,7 +543,7 @@ export class SfngNetqueryLineChartComponent implemen .append("title") .text(d => d.text) - // FIXME(ppacher): somehow d3 does not recognize which data points must be removed + // TODO(ppacher): somehow d3 does not recognize which data points must be removed // or re-placed. For now, just remove them all this.svgInner .select('.points') diff --git a/desktop/angular/src/app/shared/netquery/searchbar/searchbar.ts b/desktop/angular/src/app/shared/netquery/searchbar/searchbar.ts index 46a42f51..044f8618 100644 --- a/desktop/angular/src/app/shared/netquery/searchbar/searchbar.ts +++ b/desktop/angular/src/app/shared/netquery/searchbar/searchbar.ts @@ -184,7 +184,7 @@ export class SfngNetquerySearchbarComponent implements ControlValueAccessor, OnI const queries: Observable>[] = []; const queryKeys: (keyof Partial)[] = []; - // FIXME(ppacher): confirm .type is an actually allowed field + // TODO(ppacher): confirm .type is an actually allowed field if (!!parser.lastUnterminatedCondition) { fields = [parser.lastUnterminatedCondition.type as keyof NetqueryConnection]; limit = 0; diff --git a/service/broadcasts/notify.go b/service/broadcasts/notify.go index 235a1bf0..73c9f232 100644 --- a/service/broadcasts/notify.go +++ b/service/broadcasts/notify.go @@ -21,7 +21,7 @@ import ( ) const ( - broadcastsResourcePath = "intel/portmaster/notifications.yaml" + broadcastsResourceName = "notifications.yaml" broadcastNotificationIDPrefix = "broadcasts:" @@ -67,7 +67,7 @@ type BroadcastNotification struct { func broadcastNotify(ctx *mgr.WorkerCtx) error { // Get broadcast notifications file, load it from disk and parse it. - broadcastsResource, err := module.instance.IntelUpdates().GetFile(broadcastsResourcePath) + broadcastsResource, err := module.instance.IntelUpdates().GetFile(broadcastsResourceName) if err != nil { return fmt.Errorf("failed to get broadcast notifications update: %w", err) } diff --git a/service/config.go b/service/config.go index 7b7e0f08..f7b1f12c 100644 --- a/service/config.go +++ b/service/config.go @@ -9,6 +9,8 @@ import ( "github.com/safing/jess" "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/service/configure" + "github.com/safing/portmaster/service/updates" ) type ServiceConfig struct { @@ -76,11 +78,10 @@ func (sc *ServiceConfig) Init() error { // Apply defaults for required fields. if len(sc.BinariesIndexURLs) == 0 { - // FIXME: Select based on setting. - sc.BinariesIndexURLs = DefaultStableBinaryIndexURLs + sc.BinariesIndexURLs = configure.DefaultStableBinaryIndexURLs } if len(sc.IntelIndexURLs) == 0 { - sc.IntelIndexURLs = DefaultIntelIndexURLs + sc.IntelIndexURLs = configure.DefaultIntelIndexURLs } // Check log level. @@ -109,3 +110,71 @@ func getCurrentBinaryFolder() (string, error) { return installDir, nil } + +func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateConfig *updates.Config, err error) { + switch runtime.GOOS { + case "windows": + binaryUpdateConfig = &updates.Config{ + Name: "binaries", + Directory: svcCfg.BinDir, + DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_binaries"), + PurgeDirectory: filepath.Join(svcCfg.BinDir, "upgrade_obsolete_binaries"), + Ignore: []string{"databases", "intel", "config.json"}, + IndexURLs: svcCfg.BinariesIndexURLs, // May be changed by config during instance startup. + IndexFile: "index.json", + Verify: svcCfg.VerifyBinaryUpdates, + AutoCheck: true, // May be changed by config during instance startup. + AutoDownload: false, + AutoApply: false, + NeedsRestart: true, + Notify: true, + } + intelUpdateConfig = &updates.Config{ + Name: "intel", + Directory: filepath.Join(svcCfg.DataDir, "intel"), + DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_intel"), + PurgeDirectory: filepath.Join(svcCfg.DataDir, "upgrade_obsolete_intel"), + IndexURLs: svcCfg.IntelIndexURLs, + IndexFile: "index.json", + Verify: svcCfg.VerifyIntelUpdates, + AutoCheck: true, // May be changed by config during instance startup. + AutoDownload: true, + AutoApply: true, + NeedsRestart: false, + Notify: false, + } + + case "linux": + binaryUpdateConfig = &updates.Config{ + Name: "binaries", + Directory: svcCfg.BinDir, + DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_binaries"), + PurgeDirectory: filepath.Join(svcCfg.DataDir, "upgrade_obsolete_binaries"), + Ignore: []string{"databases", "intel", "config.json"}, + IndexURLs: svcCfg.BinariesIndexURLs, // May be changed by config during instance startup. + IndexFile: "index.json", + Verify: svcCfg.VerifyBinaryUpdates, + AutoCheck: true, // May be changed by config during instance startup. + AutoDownload: false, + AutoApply: false, + NeedsRestart: true, + Notify: true, + } + intelUpdateConfig = &updates.Config{ + Name: "intel", + Directory: filepath.Join(svcCfg.DataDir, "intel"), + DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_intel"), + PurgeDirectory: filepath.Join(svcCfg.DataDir, "upgrade_obsolete_intel"), + IndexURLs: svcCfg.IntelIndexURLs, + IndexFile: "index.json", + Verify: svcCfg.VerifyIntelUpdates, + AutoCheck: true, // May be changed by config during instance startup. + AutoDownload: true, + AutoApply: true, + NeedsRestart: false, + Notify: false, + } + } + + return +} diff --git a/service/configure/updates.go b/service/configure/updates.go new file mode 100644 index 00000000..3fec4afc --- /dev/null +++ b/service/configure/updates.go @@ -0,0 +1,65 @@ +package configure + +import ( + "github.com/safing/jess" +) + +var ( + DefaultStableBinaryIndexURLs = []string{ + "https://updates.safing.io/stable.v3.json", + } + DefaultBetaBinaryIndexURLs = []string{ + "https://updates.safing.io/beta.v3.json", + } + DefaultStagingBinaryIndexURLs = []string{ + "https://updates.safing.io/staging.v3.json", + } + DefaultSupportBinaryIndexURLs = []string{ + "https://updates.safing.io/support.v3.json", + } + + DefaultIntelIndexURLs = []string{ + "https://updates.safing.io/intel.v3.json", + } + + // BinarySigningKeys holds the signing keys in text format. + BinarySigningKeys = []string{ + // Safing Code Signing Key #1 + "recipient:public-ed25519-key:safing-code-signing-key-1:92bgBLneQUWrhYLPpBDjqHbpFPuNVCPAaivQ951A4aq72HcTiw7R1QmPJwFM1mdePAvEVDjkeb8S4fp2pmRCsRa8HrCvWQEjd88rfZ6TznJMfY4g7P8ioGFjfpyx2ZJ8WCZJG5Qt4Z9nkabhxo2Nbi3iywBTYDLSbP5CXqi7jryW7BufWWuaRVufFFzhwUC2ryWFWMdkUmsAZcvXwde4KLN9FrkWAy61fGaJ8GCwGnGCSitANnU2cQrsGBXZzxmzxwrYD", + // Safing Code Signing Key #2 + "recipient:public-ed25519-key:safing-code-signing-key-2:92bgBLneQUWrhYLPpBDjqHbPC2d1o5JMyZFdavWBNVtdvbPfzDewLW95ScXfYPHd3QvWHSWCtB4xpthaYWxSkK1kYiGp68DPa2HaU8yQ5dZhaAUuV4Kzv42pJcWkCeVnBYqgGBXobuz52rFqhDJy3rz7soXEmYhJEJWwLwMeioK3VzN3QmGSYXXjosHMMNC76rjufSoLNtUQUWZDSnHmqbuxbKMCCsjFXUGGhtZVyb7bnu7QLTLk6SKHBJDMB6zdL9sw3", + } + + // BinarySigningTrustStore is an in-memory trust store with the signing keys. + BinarySigningTrustStore = jess.NewMemTrustStore() +) + +func init() { + for _, signingKey := range BinarySigningKeys { + rcpt, err := jess.RecipientFromTextFormat(signingKey) + if err != nil { + panic(err) + } + err = BinarySigningTrustStore.StoreSignet(rcpt) + if err != nil { + panic(err) + } + } +} + +// GetBinaryUpdateURLs returns the correct binary update URLs for the given release channel. +// Silently falls back to stable if release channel is invalid. +func GetBinaryUpdateURLs(releaseChannel string) []string { + switch releaseChannel { + case "stable": + return DefaultStableBinaryIndexURLs + case "beta": + return DefaultBetaBinaryIndexURLs + case "staging": + return DefaultStagingBinaryIndexURLs + case "support": + return DefaultSupportBinaryIndexURLs + default: + return DefaultStableBinaryIndexURLs + } +} diff --git a/service/core/api.go b/service/core/api.go index ea4f18d1..6f419ced 100644 --- a/service/core/api.go +++ b/service/core/api.go @@ -1,19 +1,27 @@ package core import ( + "bytes" "context" "encoding/hex" "errors" "fmt" + "io" "net/http" "net/url" + "os" + "path/filepath" + "strings" "time" + "github.com/ghodss/yaml" + "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/base/rng" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/base/utils/debug" "github.com/safing/portmaster/service/compat" "github.com/safing/portmaster/service/process" @@ -149,6 +157,17 @@ func registerAPIEndpoints() error { return err } + if err := api.RegisterEndpoint(api.Endpoint{ + Name: "Get Resource", + Description: "Returns the requested resource from the udpate system", + Path: `updates/get/?{artifact_path:[A-Za-z0-9/\.\-_]{1,255}}/{artifact_name:[A-Za-z0-9\.\-_]{1,255}}`, + Read: api.PermitUser, + ReadMethod: http.MethodGet, + HandlerFunc: getUpdateResource, + }); err != nil { + return err + } + return nil } @@ -170,6 +189,113 @@ func restart(_ *api.Request) (msg string, err error) { return "restart initiated", nil } +func getUpdateResource(w http.ResponseWriter, r *http.Request) { + // Get identifier from URL. + var identifier string + if ar := api.GetAPIRequest(r); ar != nil { + identifier = ar.URLVars["artifact_name"] + } + if identifier == "" { + http.Error(w, "no resource specified", http.StatusBadRequest) + return + } + + // Get resource. + artifact, err := module.instance.BinaryUpdates().GetFile(identifier) + if err != nil { + intelArtifact, intelErr := module.instance.IntelUpdates().GetFile(identifier) + if intelErr == nil { + artifact = intelArtifact + } else { + http.Error(w, err.Error(), http.StatusNotFound) + return + } + } + + // Open file for reading. + file, err := os.Open(artifact.Path()) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer file.Close() //nolint:errcheck,gosec + + // Assign file to reader + var reader io.Reader = file + + // Add version and hash to header. + if artifact.Version != "" { + w.Header().Set("Resource-Version", artifact.Version) + } + if artifact.SHA256 != "" { + w.Header().Set("Resource-SHA256", artifact.SHA256) + } + + // Set Content-Type. + contentType, _ := utils.MimeTypeByExtension(filepath.Ext(artifact.Path())) + w.Header().Set("Content-Type", contentType) + + // Check if the content type may be returned. + accept := r.Header.Get("Accept") + if accept != "" { + mimeTypes := strings.Split(accept, ",") + // First, clean mime types. + for i, mimeType := range mimeTypes { + mimeType = strings.TrimSpace(mimeType) + mimeType, _, _ = strings.Cut(mimeType, ";") + mimeTypes[i] = mimeType + } + // Second, check if we may return anything. + var acceptsAny bool + for _, mimeType := range mimeTypes { + switch mimeType { + case "*", "*/*": + acceptsAny = true + } + } + // Third, check if we can convert. + if !acceptsAny { + var converted bool + sourceType, _, _ := strings.Cut(contentType, ";") + findConvertiblePair: + for _, mimeType := range mimeTypes { + switch { + case sourceType == "application/yaml" && mimeType == "application/json": + yamlData, err := io.ReadAll(reader) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + jsonData, err := yaml.YAMLToJSON(yamlData) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + reader = bytes.NewReader(jsonData) + converted = true + break findConvertiblePair + } + } + + // If we could not convert to acceptable format, return an error. + if !converted { + http.Error(w, "conversion to requested format not supported", http.StatusNotAcceptable) + return + } + } + } + + // Write file. + w.WriteHeader(http.StatusOK) + if r.Method != http.MethodHead { + _, err = io.Copy(w, reader) + if err != nil { + log.Errorf("updates: failed to serve resource file: %s", err) + return + } + } +} + // debugInfo returns the debugging information for support requests. func debugInfo(ar *api.Request) (data []byte, err error) { // Create debug information helper. @@ -192,7 +318,7 @@ func debugInfo(ar *api.Request) (data []byte, err error) { config.AddToDebugInfo(di) // Detailed information. - // TODO(vladimir): updates.AddToDebugInfo(di) + AddVersionsToDebugInfo(di) compat.AddToDebugInfo(di) module.instance.AddWorkerInfoToDebugInfo(di) di.AddGoroutineStack() diff --git a/service/core/base/global.go b/service/core/base/global.go deleted file mode 100644 index 912e975a..00000000 --- a/service/core/base/global.go +++ /dev/null @@ -1,46 +0,0 @@ -package base - -import ( - "errors" - "flag" - "fmt" - - "github.com/safing/portmaster/base/api" - "github.com/safing/portmaster/base/info" - "github.com/safing/portmaster/service/mgr" -) - -// Default Values (changeable for testing). -var ( - DefaultAPIListenAddress = "127.0.0.1:817" - - showVersion bool -) - -func init() { - flag.BoolVar(&showVersion, "version", false, "show version and exit") -} - -func prep(instance instance) error { - // check if meta info is ok - err := info.CheckVersion() - if err != nil { - return errors.New("compile error: please compile using the provided build script") - } - - // print version - if showVersion { - instance.SetCmdLineOperation(printVersion) - return mgr.ErrExecuteCmdLineOp - } - - // set api listen address - api.SetDefaultAPIListenAddress(DefaultAPIListenAddress) - - return nil -} - -func printVersion() error { - fmt.Println(info.FullVersion()) - return nil -} diff --git a/service/core/base/module.go b/service/core/base/module.go index 0bb7aba2..05eacec9 100644 --- a/service/core/base/module.go +++ b/service/core/base/module.go @@ -4,9 +4,13 @@ import ( "errors" "sync/atomic" + "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/service/mgr" ) +// DefaultAPIListenAddress is the default listen address for the API. +var DefaultAPIListenAddress = "127.0.0.1:817" + // Base is the base module. type Base struct { mgr *mgr.Manager @@ -47,9 +51,9 @@ func New(instance instance) (*Base, error) { instance: instance, } - if err := prep(instance); err != nil { - return nil, err - } + // Set api listen address. + api.SetDefaultAPIListenAddress(DefaultAPIListenAddress) + if err := registerDatabases(); err != nil { return nil, err } diff --git a/service/core/core.go b/service/core/core.go index 356bd2eb..48f262a1 100644 --- a/service/core/core.go +++ b/service/core/core.go @@ -6,6 +6,8 @@ import ( "fmt" "sync/atomic" + "github.com/safing/portmaster/base/config" + "github.com/safing/portmaster/base/database" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/metrics" "github.com/safing/portmaster/base/utils/debug" @@ -19,6 +21,11 @@ import ( "github.com/safing/portmaster/service/updates" ) +var db = database.NewInterface(&database.Options{ + Local: true, + Internal: true, +}) + // Core is the core service module. type Core struct { m *mgr.Manager @@ -56,8 +63,10 @@ func init() { func prep() error { // init config - err := registerConfig() - if err != nil { + if err := registerConfig(); err != nil { + return err + } + if err := registerUpdateConfig(); err != nil { return err } @@ -77,6 +86,10 @@ func start() error { return fmt.Errorf("failed to start plattform-specific components: %w", err) } + // Setup update system. + initUpdateConfig() + initVersionExport() + // Enable persistent metrics. if err := metrics.EnableMetricPersistence("core:metrics/storage"); err != nil { log.Warningf("core: failed to enable persisted metrics: %s", err) @@ -116,6 +129,7 @@ type instance interface { Shutdown() Restart() AddWorkerInfoToDebugInfo(di *debug.Info) + Config() *config.Config BinaryUpdates() *updates.Updater IntelUpdates() *updates.Updater } diff --git a/service/core/update_config.go b/service/core/update_config.go new file mode 100644 index 00000000..10fdb84c --- /dev/null +++ b/service/core/update_config.go @@ -0,0 +1,134 @@ +package core + +import ( + "github.com/safing/portmaster/base/config" + "github.com/safing/portmaster/service/configure" + "github.com/safing/portmaster/service/mgr" +) + +// Release Channel Configuration Keys. +const ( + ReleaseChannelKey = "core/releaseChannel" + ReleaseChannelJSONKey = "core.releaseChannel" +) + +// Release Channels. +const ( + ReleaseChannelStable = "stable" + ReleaseChannelBeta = "beta" + ReleaseChannelStaging = "staging" + ReleaseChannelSupport = "support" +) + +const ( + enableSoftwareUpdatesKey = "core/automaticUpdates" + enableIntelUpdatesKey = "core/automaticIntelUpdates" +) + +var ( + releaseChannel config.StringOption + enableSoftwareUpdates config.BoolOption + enableIntelUpdates config.BoolOption + + initialReleaseChannel string +) + +func registerUpdateConfig() error { + err := config.Register(&config.Option{ + Name: "Release Channel", + Key: ReleaseChannelKey, + Description: `Use "Stable" for the best experience. The "Beta" channel will have the newest features and fixes, but may also break and cause interruption. Use others only temporarily and when instructed.`, + OptType: config.OptTypeString, + ExpertiseLevel: config.ExpertiseLevelExpert, + ReleaseLevel: config.ReleaseLevelStable, + RequiresRestart: true, + DefaultValue: ReleaseChannelStable, + PossibleValues: []config.PossibleValue{ + { + Name: "Stable", + Description: "Production releases.", + Value: ReleaseChannelStable, + }, + { + Name: "Beta", + Description: "Production releases for testing new features that may break and cause interruption.", + Value: ReleaseChannelBeta, + }, + { + Name: "Support", + Description: "Support releases or version changes for troubleshooting. Only use temporarily and when instructed.", + Value: ReleaseChannelSupport, + }, + { + Name: "Staging", + Description: "Dangerous development releases for testing random things and experimenting. Only use temporarily and when instructed.", + Value: ReleaseChannelStaging, + }, + }, + Annotations: config.Annotations{ + config.DisplayOrderAnnotation: -4, + config.DisplayHintAnnotation: config.DisplayHintOneOf, + config.CategoryAnnotation: "Updates", + }, + }) + if err != nil { + return err + } + + err = config.Register(&config.Option{ + Name: "Automatic Software Updates", + Key: enableSoftwareUpdatesKey, + Description: "Automatically check for and download software updates. This does not include intelligence data updates.", + OptType: config.OptTypeBool, + ExpertiseLevel: config.ExpertiseLevelExpert, + ReleaseLevel: config.ReleaseLevelStable, + RequiresRestart: false, + DefaultValue: true, + Annotations: config.Annotations{ + config.DisplayOrderAnnotation: -12, + config.CategoryAnnotation: "Updates", + }, + }) + if err != nil { + return err + } + + err = config.Register(&config.Option{ + Name: "Automatic Intelligence Data Updates", + Key: enableIntelUpdatesKey, + Description: "Automatically check for and download intelligence data updates. This includes filter lists, geo-ip data, and more. Does not include software updates.", + OptType: config.OptTypeBool, + ExpertiseLevel: config.ExpertiseLevelExpert, + ReleaseLevel: config.ReleaseLevelStable, + RequiresRestart: false, + DefaultValue: true, + Annotations: config.Annotations{ + config.DisplayOrderAnnotation: -11, + config.CategoryAnnotation: "Updates", + }, + }) + if err != nil { + return err + } + + return nil +} + +func initUpdateConfig() { + releaseChannel = config.Concurrent.GetAsString(ReleaseChannelKey, ReleaseChannelStable) + enableSoftwareUpdates = config.Concurrent.GetAsBool(enableSoftwareUpdatesKey, true) + enableIntelUpdates = config.Concurrent.GetAsBool(enableIntelUpdatesKey, true) + + initialReleaseChannel = releaseChannel() + + module.instance.Config().EventConfigChange.AddCallback("configure updates", func(wc *mgr.WorkerCtx, s struct{}) (cancel bool, err error) { + configureUpdates() + return false, nil + }) + configureUpdates() +} + +func configureUpdates() { + module.instance.BinaryUpdates().Configure(enableSoftwareUpdates(), configure.GetBinaryUpdateURLs(releaseChannel())) + module.instance.IntelUpdates().Configure(enableIntelUpdates(), configure.DefaultIntelIndexURLs) +} diff --git a/service/core/update_versions.go b/service/core/update_versions.go new file mode 100644 index 00000000..8427a505 --- /dev/null +++ b/service/core/update_versions.go @@ -0,0 +1,176 @@ +package core + +import ( + "bytes" + "fmt" + "sync" + "text/tabwriter" + + "github.com/safing/portmaster/base/database/record" + "github.com/safing/portmaster/base/info" + "github.com/safing/portmaster/base/utils/debug" + "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/updates" +) + +const ( + // versionsDBKey is the database key for update version information. + versionsDBKey = "core:status/versions" + + // versionsDBKey is the database key for simple update version information. + simpleVersionsDBKey = "core:status/simple-versions" +) + +// Versions holds update versions and status information. +type Versions struct { + record.Base + sync.Mutex + + Core *info.Info + Resources map[string]*updates.Artifact + Channel string + Beta bool + Staging bool +} + +// SimpleVersions holds simplified update versions and status information. +type SimpleVersions struct { + record.Base + sync.Mutex + + Build *info.Info + Resources map[string]*SimplifiedResourceVersion + Channel string +} + +// SimplifiedResourceVersion holds version information about one resource. +type SimplifiedResourceVersion struct { + Version string +} + +// GetVersions returns the update versions and status information. +// Resources must be locked when accessed. +func GetVersions() *Versions { + // Get all artifacts. + resources := make(map[string]*updates.Artifact) + if artifacts, err := module.instance.BinaryUpdates().GetFiles(); err == nil { + for _, artifact := range artifacts { + resources[artifact.Filename] = artifact + } + } + if artifacts, err := module.instance.IntelUpdates().GetFiles(); err == nil { + for _, artifact := range artifacts { + resources[artifact.Filename] = artifact + } + } + + return &Versions{ + Core: info.GetInfo(), + Resources: resources, + Channel: initialReleaseChannel, + Beta: initialReleaseChannel == ReleaseChannelBeta, + Staging: initialReleaseChannel == ReleaseChannelStaging, + } +} + +// GetSimpleVersions returns the simplified update versions and status information. +func GetSimpleVersions() *SimpleVersions { + // Get all artifacts, simply map. + resources := make(map[string]*SimplifiedResourceVersion) + if artifacts, err := module.instance.BinaryUpdates().GetFiles(); err == nil { + for _, artifact := range artifacts { + resources[artifact.Filename] = &SimplifiedResourceVersion{ + Version: artifact.Version, + } + } + } + if artifacts, err := module.instance.IntelUpdates().GetFiles(); err == nil { + for _, artifact := range artifacts { + resources[artifact.Filename] = &SimplifiedResourceVersion{ + Version: artifact.Version, + } + } + } + + // Fill base info. + return &SimpleVersions{ + Build: info.GetInfo(), + Resources: resources, + Channel: initialReleaseChannel, + } +} + +func initVersionExport() { + module.instance.BinaryUpdates().EventResourcesUpdated.AddCallback("export version status", export) + module.instance.IntelUpdates().EventResourcesUpdated.AddCallback("export version status", export) + + _, _ = export(nil, struct{}{}) +} + +func (v *Versions) save() error { + if !v.KeyIsSet() { + v.SetKey(versionsDBKey) + } + return db.Put(v) +} + +func (v *SimpleVersions) save() error { + if !v.KeyIsSet() { + v.SetKey(simpleVersionsDBKey) + } + return db.Put(v) +} + +// export is an event hook. +func export(_ *mgr.WorkerCtx, _ struct{}) (cancel bool, err error) { + // Export versions. + if err := GetVersions().save(); err != nil { + return false, err + } + if err := GetSimpleVersions().save(); err != nil { + return false, err + } + + return false, nil +} + +// AddVersionsToDebugInfo adds the update system status to the given debug.Info. +func AddVersionsToDebugInfo(di *debug.Info) { + overviewBuf := bytes.NewBuffer(nil) + tableBuf := bytes.NewBuffer(nil) + tabWriter := tabwriter.NewWriter(tableBuf, 8, 4, 3, ' ', 0) + fmt.Fprint(tabWriter, "\nFile\tVersion\tIndex\tSHA256\n") + + // Collect data for debug info. + var cnt int + if index, err := module.instance.BinaryUpdates().GetIndex(); err == nil { + fmt.Fprintf(overviewBuf, "Binaries Index: v%s from %s\n", index.Version, index.Published) + for _, artifact := range index.Artifacts { + fmt.Fprintf(tabWriter, "\n%s\t%s\t%s\t%s", artifact.Filename, vStr(artifact.Version), "binaries", artifact.SHA256) + cnt++ + } + } + if index, err := module.instance.IntelUpdates().GetIndex(); err == nil { + fmt.Fprintf(overviewBuf, "Intel Index: v%s from %s\n", index.Version, index.Published) + for _, artifact := range index.Artifacts { + fmt.Fprintf(tabWriter, "\n%s\t%s\t%s\t%s", artifact.Filename, vStr(artifact.Version), "intel", artifact.SHA256) + cnt++ + } + } + _ = tabWriter.Flush() + + // Add section. + di.AddSection( + fmt.Sprintf("Updates: %s (%d)", initialReleaseChannel, cnt), + debug.UseCodeSection, + overviewBuf.String(), + tableBuf.String(), + ) +} + +func vStr(v string) string { + if v != "" { + return v + } + return "unknown" +} diff --git a/service/instance.go b/service/instance.go index ddb23671..840bcdb0 100644 --- a/service/instance.go +++ b/service/instance.go @@ -167,10 +167,6 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx } // Service modules - instance.core, err = core.New(instance) - if err != nil { - return instance, fmt.Errorf("create core module: %w", err) - } binaryUpdateConfig, intelUpdateConfig, err := MakeUpdateConfigs(svcCfg) if err != nil { return instance, fmt.Errorf("create updates config: %w", err) @@ -183,6 +179,10 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx if err != nil { return instance, fmt.Errorf("create updates module: %w", err) } + instance.core, err = core.New(instance) + if err != nil { + return instance, fmt.Errorf("create core module: %w", err) + } instance.geoip, err = geoip.New(instance) if err != nil { return instance, fmt.Errorf("create customlist module: %w", err) @@ -708,3 +708,23 @@ func (i *Instance) ShutdownComplete() <-chan struct{} { func (i *Instance) ExitCode() int { return int(i.exitCode.Load()) } + +// ShouldRestartIsSet returns whether the service/instance should be restarted. +func (i *Instance) ShouldRestartIsSet() bool { + return i.ShouldRestart +} + +// CommandLineOperationIsSet returns whether the command line option is set. +func (i *Instance) CommandLineOperationIsSet() bool { + return i.CommandLineOperation != nil +} + +// CommandLineOperationExecute executes the set command line option. +func (i *Instance) CommandLineOperationExecute() error { + return i.CommandLineOperation() +} + +// AddModule adds a module to the service group. +func (i *Instance) AddModule(m mgr.Module) { + i.serviceGroup.Add(m) +} diff --git a/service/updates.go b/service/updates.go deleted file mode 100644 index 3c717951..00000000 --- a/service/updates.go +++ /dev/null @@ -1,120 +0,0 @@ -package service - -import ( - "path/filepath" - go_runtime "runtime" - - "github.com/safing/jess" - "github.com/safing/portmaster/service/updates" -) - -var ( - DefaultStableBinaryIndexURLs = []string{ - "https://updates.safing.io/stable.v3.json", - } - DefaultBetaBinaryIndexURLs = []string{ - "https://updates.safing.io/beta.v3.json", - } - DefaultStagingBinaryIndexURLs = []string{ - "https://updates.safing.io/staging.v3.json", - } - DefaultSupportBinaryIndexURLs = []string{ - "https://updates.safing.io/support.v3.json", - } - - DefaultIntelIndexURLs = []string{ - "https://updates.safing.io/intel.v3.json", - } - - // BinarySigningKeys holds the signing keys in text format. - BinarySigningKeys = []string{ - // Safing Code Signing Key #1 - "recipient:public-ed25519-key:safing-code-signing-key-1:92bgBLneQUWrhYLPpBDjqHbpFPuNVCPAaivQ951A4aq72HcTiw7R1QmPJwFM1mdePAvEVDjkeb8S4fp2pmRCsRa8HrCvWQEjd88rfZ6TznJMfY4g7P8ioGFjfpyx2ZJ8WCZJG5Qt4Z9nkabhxo2Nbi3iywBTYDLSbP5CXqi7jryW7BufWWuaRVufFFzhwUC2ryWFWMdkUmsAZcvXwde4KLN9FrkWAy61fGaJ8GCwGnGCSitANnU2cQrsGBXZzxmzxwrYD", - // Safing Code Signing Key #2 - "recipient:public-ed25519-key:safing-code-signing-key-2:92bgBLneQUWrhYLPpBDjqHbPC2d1o5JMyZFdavWBNVtdvbPfzDewLW95ScXfYPHd3QvWHSWCtB4xpthaYWxSkK1kYiGp68DPa2HaU8yQ5dZhaAUuV4Kzv42pJcWkCeVnBYqgGBXobuz52rFqhDJy3rz7soXEmYhJEJWwLwMeioK3VzN3QmGSYXXjosHMMNC76rjufSoLNtUQUWZDSnHmqbuxbKMCCsjFXUGGhtZVyb7bnu7QLTLk6SKHBJDMB6zdL9sw3", - } - - // BinarySigningTrustStore is an in-memory trust store with the signing keys. - BinarySigningTrustStore = jess.NewMemTrustStore() -) - -func init() { - for _, signingKey := range BinarySigningKeys { - rcpt, err := jess.RecipientFromTextFormat(signingKey) - if err != nil { - panic(err) - } - err = BinarySigningTrustStore.StoreSignet(rcpt) - if err != nil { - panic(err) - } - } -} - -func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateConfig *updates.Config, err error) { - switch go_runtime.GOOS { - case "windows": - binaryUpdateConfig = &updates.Config{ - Name: "binaries", - Directory: svcCfg.BinDir, - DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_binaries"), - PurgeDirectory: filepath.Join(svcCfg.BinDir, "upgrade_obsolete_binaries"), - Ignore: []string{"databases", "intel", "config.json"}, - IndexURLs: svcCfg.BinariesIndexURLs, - IndexFile: "index.json", - Verify: svcCfg.VerifyBinaryUpdates, - AutoCheck: true, // FIXME: Get from setting. - AutoDownload: false, - AutoApply: false, - NeedsRestart: true, - Notify: true, - } - intelUpdateConfig = &updates.Config{ - Name: "intel", - Directory: filepath.Join(svcCfg.DataDir, "intel"), - DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_intel"), - PurgeDirectory: filepath.Join(svcCfg.DataDir, "upgrade_obsolete_intel"), - IndexURLs: svcCfg.IntelIndexURLs, - IndexFile: "index.json", - Verify: svcCfg.VerifyIntelUpdates, - AutoCheck: true, // FIXME: Get from setting. - AutoDownload: true, - AutoApply: true, - NeedsRestart: false, - Notify: false, - } - - case "linux": - binaryUpdateConfig = &updates.Config{ - Name: "binaries", - Directory: svcCfg.BinDir, - DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_binaries"), - PurgeDirectory: filepath.Join(svcCfg.DataDir, "upgrade_obsolete_binaries"), - Ignore: []string{"databases", "intel", "config.json"}, - IndexURLs: svcCfg.BinariesIndexURLs, - IndexFile: "index.json", - Verify: svcCfg.VerifyBinaryUpdates, - AutoCheck: true, // FIXME: Get from setting. - AutoDownload: false, - AutoApply: false, - NeedsRestart: true, - Notify: true, - } - intelUpdateConfig = &updates.Config{ - Name: "intel", - Directory: filepath.Join(svcCfg.DataDir, "intel"), - DownloadDirectory: filepath.Join(svcCfg.DataDir, "download_intel"), - PurgeDirectory: filepath.Join(svcCfg.DataDir, "upgrade_obsolete_intel"), - IndexURLs: svcCfg.IntelIndexURLs, - IndexFile: "index.json", - Verify: svcCfg.VerifyIntelUpdates, - AutoCheck: true, // FIXME: Get from setting. - AutoDownload: true, - AutoApply: true, - NeedsRestart: false, - Notify: false, - } - } - - return -} diff --git a/service/updates/downloader.go b/service/updates/downloader.go index 30c32261..27836cac 100644 --- a/service/updates/downloader.go +++ b/service/updates/downloader.go @@ -192,7 +192,7 @@ artifacts: return nil } -func (d *Downloader) getArtifact(ctx context.Context, artifact Artifact, url string) ([]byte, error) { +func (d *Downloader) getArtifact(ctx context.Context, artifact *Artifact, url string) ([]byte, error) { // Download data from URL. artifactData, err := d.downloadData(ctx, url) if err != nil { diff --git a/service/updates/index.go b/service/updates/index.go index 8a30f643..baa76329 100644 --- a/service/updates/index.go +++ b/service/updates/index.go @@ -117,10 +117,10 @@ func (a *Artifact) export(dir string, indexVersion *semver.Version) *Artifact { // Index represents a collection of artifacts with metadata. type Index struct { - Name string `json:"Name"` - Version string `json:"Version"` - Published time.Time `json:"Published"` - Artifacts []Artifact `json:"Artifacts"` + Name string `json:"Name"` + Version string `json:"Version"` + Published time.Time `json:"Published"` + Artifacts []*Artifact `json:"Artifacts"` versionNum *semver.Version } @@ -173,7 +173,7 @@ func (index *Index) init() error { } // Filter artifacts by current platform. - filtered := make([]Artifact, 0) + filtered := make([]*Artifact, 0) for _, a := range index.Artifacts { if a.Platform == "" || a.Platform == currentPlatform { filtered = append(filtered, a) @@ -189,6 +189,7 @@ func (index *Index) init() error { a.versionNum = v } } else { + a.Version = index.Version a.versionNum = index.versionNum } } diff --git a/service/updates/index_scan.go b/service/updates/index_scan.go index 6e6a6af2..bc5cc0e8 100644 --- a/service/updates/index_scan.go +++ b/service/updates/index_scan.go @@ -95,7 +95,7 @@ settings: // GenerateIndexFromDir generates a index from a given folder. func GenerateIndexFromDir(sourceDir string, cfg IndexScanConfig) (*Index, error) { //nolint:maintidx - artifacts := make(map[string]Artifact) + artifacts := make(map[string]*Artifact) // Initialize. err := cfg.init() @@ -187,11 +187,12 @@ func GenerateIndexFromDir(sourceDir string, cfg IndexScanConfig) (*Index, error) // Step 3: Create new Artifact. - artifact := Artifact{} + artifact := &Artifact{} // Check if the caller provided a template for the artifact. if t, ok := cfg.Templates[identifier]; ok { - artifact = t + fromTemplate := t + artifact = &fromTemplate } // Set artifact properties. @@ -249,7 +250,7 @@ func GenerateIndexFromDir(sourceDir string, cfg IndexScanConfig) (*Index, error) } // Convert to slice and compute hashes. - export := make([]Artifact, 0, len(artifacts)) + export := make([]*Artifact, 0, len(artifacts)) for _, artifact := range artifacts { // Compute hash. hash, err := getSHA256(artifact.localFile, artifact.Unpack) @@ -273,7 +274,7 @@ func GenerateIndexFromDir(sourceDir string, cfg IndexScanConfig) (*Index, error) } // Sort final artifacts. - slices.SortFunc(export, func(a, b Artifact) int { + slices.SortFunc(export, func(a, b *Artifact) int { switch { case a.Filename != b.Filename: return strings.Compare(a.Filename, b.Filename) diff --git a/service/updates/module.go b/service/updates/module.go index e5b32129..2e008d48 100644 --- a/service/updates/module.go +++ b/service/updates/module.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "runtime" + "slices" "strings" "sync" "time" @@ -132,9 +133,11 @@ type Updater struct { EventResourcesUpdated *mgr.EventMgr[struct{}] - corruptedInstallation bool + corruptedInstallation error isUpdateRunning *abool.AtomicBool + started *abool.AtomicBool + configureLock sync.Mutex instance instance } @@ -150,6 +153,7 @@ func New(instance instance, name string, cfg Config) (*Updater, error) { EventResourcesUpdated: mgr.NewEventMgr[struct{}](ResourceUpdateEvent, m), isUpdateRunning: abool.NewBool(false), + started: abool.NewBool(false), instance: instance, } @@ -166,6 +170,12 @@ func New(instance instance, name string, cfg Config) (*Updater, error) { // Load index. index, err := LoadIndex(filepath.Join(cfg.Directory, cfg.IndexFile), cfg.Verify) if err == nil { + // Verify artifacts. + if err := index.VerifyArtifacts(cfg.Directory); err != nil { + module.corruptedInstallation = fmt.Errorf("invalid artifact: %w", err) + } + + // Save index to module and return. module.index = index return module, nil } @@ -173,6 +183,7 @@ func New(instance instance, name string, cfg Config) (*Updater, error) { // Fall back to scanning the directory. if !errors.Is(err, os.ErrNotExist) { log.Errorf("updates/%s: invalid index file, falling back to dir scan: %s", cfg.Name, err) + module.corruptedInstallation = fmt.Errorf("invalid index: %w", err) } index, err = GenerateIndexFromDir(cfg.Directory, IndexScanConfig{Version: "0.0.0"}) if err == nil && index.init() == nil { @@ -259,6 +270,7 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV // Check if automatic downloads are enabled. if !u.cfg.AutoDownload && !forceApply { + log.Infof("updates/%s: new update to v%s available, action required to download and upgrade", u.cfg.Name, downloader.index.Version) if u.cfg.Notify && u.instance.Notifications() != nil { u.instance.Notifications().Notify(¬ifications.Notification{ EventID: updateAvailableNotificationID, @@ -304,6 +316,7 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV // Notify the user that an upgrade is available. if !u.cfg.AutoApply && !forceApply { + log.Infof("updates/%s: new update to v%s available, action required to upgrade", u.cfg.Name, downloader.index.Version) if u.cfg.Notify && u.instance.Notifications() != nil { u.instance.Notifications().Notify(¬ifications.Notification{ EventID: updateAvailableNotificationID, @@ -387,8 +400,15 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV return nil } +func (u *Updater) getIndexURLsWithLock() []string { + u.configureLock.Lock() + defer u.configureLock.Unlock() + + return u.cfg.IndexURLs +} + func (u *Updater) updateCheckWorker(w *mgr.WorkerCtx) error { - err := u.updateAndUpgrade(w, u.cfg.IndexURLs, false, false) + err := u.updateAndUpgrade(w, u.getIndexURLsWithLock(), false, false) switch { case err == nil: return nil // Success! @@ -404,7 +424,7 @@ func (u *Updater) updateCheckWorker(w *mgr.WorkerCtx) error { } func (u *Updater) upgradeWorker(w *mgr.WorkerCtx) error { - err := u.updateAndUpgrade(w, u.cfg.IndexURLs, false, true) + err := u.updateAndUpgrade(w, u.getIndexURLsWithLock(), false, true) switch { case err == nil: return nil // Success! @@ -423,7 +443,7 @@ func (u *Updater) upgradeWorker(w *mgr.WorkerCtx) error { // and is intended to be used only within a tool, not a service. func (u *Updater) ForceUpdate() error { return u.m.Do("update and upgrade", func(w *mgr.WorkerCtx) error { - return u.updateAndUpgrade(w, u.cfg.IndexURLs, true, true) + return u.updateAndUpgrade(w, u.getIndexURLsWithLock(), true, true) }) } @@ -437,6 +457,33 @@ func (u *Updater) UpdateFromURL(url string) error { return nil } +// Configure makes slight configuration changes to the updater. +// It locks the index, which can take a while an update is running. +func (u *Updater) Configure(autoCheck bool, indexURLs []string) { + u.configureLock.Lock() + defer u.configureLock.Unlock() + + // Apply new config. + var changed bool + if u.cfg.AutoCheck != autoCheck { + u.cfg.AutoCheck = autoCheck + changed = true + } + if !slices.Equal(u.cfg.IndexURLs, indexURLs) { + u.cfg.IndexURLs = indexURLs + changed = true + } + + // Trigger update check if enabled and something changed. + if changed && u.started.IsSet() { + if autoCheck { + u.updateCheckWorkerMgr.Repeat(updateTaskRepeatDuration).Go() + } else { + u.updateCheckWorkerMgr.Repeat(0) + } + } +} + // TriggerUpdateCheck triggers an update check. func (u *Updater) TriggerUpdateCheck() { u.updateCheckWorkerMgr.Go() @@ -459,13 +506,17 @@ func (u *Updater) Manager() *mgr.Manager { // Start starts the module. func (u *Updater) Start() error { - if u.corruptedInstallation && u.cfg.Notify && u.instance.Notifications() != nil { - // FIXME: this might make sense as a module state - u.instance.Notifications().NotifyError( - corruptInstallationNotificationID, - "Install Corruption", - "Portmaster has detected that one or more of its own files have been corrupted. Please re-install the software.", - ) + u.configureLock.Lock() + defer u.configureLock.Unlock() + + if u.corruptedInstallation != nil && u.cfg.Notify && u.instance.Notifications() != nil { + u.states.Add(mgr.State{ + ID: corruptInstallationNotificationID, + Name: "Install Corruption", + Message: "Portmaster has detected that one or more of its own files have been corrupted. Please re-install the software. Error: " + u.corruptedInstallation.Error(), + Type: mgr.StateTypeError, + Data: u.corruptedInstallation, + }) } // Check for updates automatically, if enabled. @@ -474,6 +525,8 @@ func (u *Updater) Start() error { Repeat(updateTaskRepeatDuration). Delay(15 * time.Second) } + + u.started.SetTo(true) return nil } @@ -481,6 +534,62 @@ func (u *Updater) GetMainDir() string { return u.cfg.Directory } +// GetIndex returns a copy of the index. +func (u *Updater) GetIndex() (*Index, error) { + // Copy Artifacts. + artifacts, err := u.GetFiles() + if err != nil { + return nil, err + } + + u.indexLock.Lock() + defer u.indexLock.Unlock() + + // Check if any index is active. + if u.index == nil { + return nil, ErrNotFound + } + + return &Index{ + Name: u.index.Name, + Version: u.index.Version, + Published: u.index.Published, + Artifacts: artifacts, + versionNum: u.index.versionNum, + }, nil +} + +// GetFiles returns all artifacts. Returns ErrNotFound if no artifacts are found. +func (u *Updater) GetFiles() ([]*Artifact, error) { + u.indexLock.Lock() + defer u.indexLock.Unlock() + + // Check if any index is active. + if u.index == nil { + return nil, ErrNotFound + } + + // Export all artifacts. + export := make([]*Artifact, 0, len(u.index.Artifacts)) + for _, artifact := range u.index.Artifacts { + switch { + case artifact.Platform != "" && artifact.Platform != currentPlatform: + // Platform is defined and does not match. + // Platforms are usually pre-filtered, but just to be sure. + default: + // Artifact matches! + export = append(export, artifact.export(u.cfg.Directory, u.index.versionNum)) + } + } + + // Check if anything was exported. + if len(export) == 0 { + return nil, ErrNotFound + } + + return export, nil +} + // GetFile returns the path of a file given the name. Returns ErrNotFound if file is not found. func (u *Updater) GetFile(name string) (*Artifact, error) { u.indexLock.Lock() @@ -509,6 +618,7 @@ func (u *Updater) GetFile(name string) (*Artifact, error) { // Stop stops the module. func (u *Updater) Stop() error { + u.started.SetTo(false) return nil } diff --git a/service/updates/upgrade.go b/service/updates/upgrade.go index 86077ee1..1008dcdd 100644 --- a/service/updates/upgrade.go +++ b/service/updates/upgrade.go @@ -12,8 +12,6 @@ import ( "github.com/safing/portmaster/base/log" ) -// FIXME: previous update system did in-place service file upgrades. Check if this is still necessary and if changes are in current installers. - const ( defaultFileMode = os.FileMode(0o0644) executableFileMode = os.FileMode(0o0744) diff --git a/spn/instance.go b/spn/instance.go index dcfe01aa..33af8ea5 100644 --- a/spn/instance.go +++ b/spn/instance.go @@ -3,17 +3,18 @@ package spn import ( "context" "fmt" + "os" "sync/atomic" "time" "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/database/dbmodule" - "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/metrics" "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/base/rng" "github.com/safing/portmaster/base/runtime" + "github.com/safing/portmaster/service" "github.com/safing/portmaster/service/core" "github.com/safing/portmaster/service/core/base" "github.com/safing/portmaster/service/intel/filterlists" @@ -79,27 +80,27 @@ type Instance struct { } // New returns a new Portmaster service instance. -func New() (*Instance, error) { +func New(svcCfg *service.ServiceConfig) (*Instance, error) { + // Initialize config. + err := svcCfg.Init() + if err != nil { + return nil, fmt.Errorf("internal service config error: %w", err) + } + + // Make sure data dir exists, so that child directories don't dictate the permissions. + err = os.MkdirAll(svcCfg.DataDir, 0o0755) + if err != nil { + return nil, fmt.Errorf("data directory %s is not accessible: %w", svcCfg.DataDir, err) + } + // Create instance to pass it to modules. - instance := &Instance{} + instance := &Instance{ + binDir: svcCfg.BinDir, + dataDir: svcCfg.DataDir, + } instance.ctx, instance.cancelCtx = context.WithCancel(context.Background()) instance.shutdownCtx, instance.cancelShutdownCtx = context.WithCancel(context.Background()) - binaryUpdateIndex := updates.Config{ - // FIXME: fill - } - - intelUpdateIndex := updates.Config{ - // FIXME: fill - } - - // Initialize log - log.GlobalWriter = log.NewStdoutWriter() - - // FIXME: initialize log file. - - var err error - // Base modules instance.base, err = base.New(instance) if err != nil { @@ -131,18 +132,22 @@ func New() (*Instance, error) { } // Service modules + binaryUpdateConfig, intelUpdateConfig, err := service.MakeUpdateConfigs(svcCfg) + if err != nil { + return instance, fmt.Errorf("create updates config: %w", err) + } + instance.binaryUpdates, err = updates.New(instance, "Binary Updater", *binaryUpdateConfig) + if err != nil { + return instance, fmt.Errorf("create updates module: %w", err) + } + instance.intelUpdates, err = updates.New(instance, "Intel Updater", *intelUpdateConfig) + if err != nil { + return instance, fmt.Errorf("create updates module: %w", err) + } instance.core, err = core.New(instance) if err != nil { return instance, fmt.Errorf("create core module: %w", err) } - instance.binaryUpdates, err = updates.New(instance, "Binary Updater", binaryUpdateIndex) - if err != nil { - return instance, fmt.Errorf("create updates module: %w", err) - } - instance.intelUpdates, err = updates.New(instance, "Intel Updater", intelUpdateIndex) - if err != nil { - return instance, fmt.Errorf("create updates module: %w", err) - } instance.geoip, err = geoip.New(instance) if err != nil { return instance, fmt.Errorf("create customlist module: %w", err) From 473f05becc0c5a110af2ed1d2df5bca60e1597ed Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 27 Nov 2024 16:19:02 +0100 Subject: [PATCH 15/63] Update service deps --- go.mod | 5 ++--- go.sum | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 5f609ef6..27dc3f2b 100644 --- a/go.mod +++ b/go.mod @@ -93,7 +93,6 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect - github.com/maruel/panicparse/v2 v2.3.1 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -123,8 +122,8 @@ require ( golang.org/x/tools v0.27.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - modernc.org/libc v1.61.0 // indirect + modernc.org/libc v1.61.2 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.33.1 // indirect + modernc.org/sqlite v1.34.1 // indirect ) diff --git a/go.sum b/go.sum index 13ec98f8..e75afa2b 100644 --- a/go.sum +++ b/go.sum @@ -465,16 +465,16 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= -modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= -modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4= -modernc.org/ccgo/v4 v4.21.0/go.mod h1:h6kt6H/A2+ew/3MW/p6KEoQmrq/i3pr0J/SiwiaF/g0= +modernc.org/cc/v4 v4.23.1 h1:WqJoPL3x4cUufQVHkXpXX7ThFJ1C4ik80i2eXEXbhD8= +modernc.org/cc/v4 v4.23.1/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.22.3 h1:C7AW89Zw3kygesTQWBzApwIn9ldM+cb/plrTIKq41Os= +modernc.org/ccgo/v4 v4.22.3/go.mod h1:Dz7n0/UkBbH3pnYaxgi1mFSfF4REqUOZNziphZASx6k= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/libc v1.61.0 h1:eGFcvWpqlnoGwzZeZe3PWJkkKbM/3SUGyk1DVZQ0TpE= -modernc.org/libc v1.61.0/go.mod h1:DvxVX89wtGTu+r72MLGhygpfi3aUGgZRdAYGCAVVud0= +modernc.org/libc v1.61.2 h1:dkO4DlowfClcJYsvf/RiK6fUwvzCQTmB34bJLt0CAGQ= +modernc.org/libc v1.61.2/go.mod h1:4QGjNyX3h+rn7V5oHpJY2yH0QN6frt1X+5BkXzwLPCo= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -483,8 +483,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= -modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= +modernc.org/sqlite v1.34.1 h1:u3Yi6M0N8t9yKRDwhXcyp1eS5/ErhPTBggxWFuR6Hfk= +modernc.org/sqlite v1.34.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= From acaf98144ab88fa17ba91a7d772d68a81a1198b0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 27 Nov 2024 16:19:09 +0100 Subject: [PATCH 16/63] Bump kext version --- windows_kext/kextinterface/version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows_kext/kextinterface/version.txt b/windows_kext/kextinterface/version.txt index 5db4ff8e..3030458d 100644 --- a/windows_kext/kextinterface/version.txt +++ b/windows_kext/kextinterface/version.txt @@ -1 +1 @@ -[2, 0, 4, 0] \ No newline at end of file +[2, 0, 6, 0] \ No newline at end of file From 614d8972a25a6d7f0038fbd7ecdc1b22b18bd8b8 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 27 Nov 2024 16:37:59 +0100 Subject: [PATCH 17/63] Improve logging --- .../firewall/interception/dnsmonitor/eventlistener_linux.go | 3 ++- service/firewall/interception/dnsmonitor/module.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/service/firewall/interception/dnsmonitor/eventlistener_linux.go b/service/firewall/interception/dnsmonitor/eventlistener_linux.go index d987a082..6e9bb3ee 100644 --- a/service/firewall/interception/dnsmonitor/eventlistener_linux.go +++ b/service/firewall/interception/dnsmonitor/eventlistener_linux.go @@ -10,10 +10,11 @@ import ( "os" "github.com/miekg/dns" + "github.com/varlink/go/varlink" + "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/resolver" - "github.com/varlink/go/varlink" ) type Listener struct { diff --git a/service/firewall/interception/dnsmonitor/module.go b/service/firewall/interception/dnsmonitor/module.go index eed8be11..974429f7 100644 --- a/service/firewall/interception/dnsmonitor/module.go +++ b/service/firewall/interception/dnsmonitor/module.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/miekg/dns" + "github.com/safing/portmaster/base/database" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/service/compat" @@ -38,7 +39,7 @@ func (dl *DNSMonitor) Start() error { var err error dl.listener, err = newListener(dl) if err != nil { - log.Errorf("dnsmonitor: failed to start dns listener: %s", err) + log.Warningf("dnsmonitor: failed to start dns listener: %s", err) } return nil From 05f4f3fc6dedca83aa80409af81021ffa67de707 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Wed, 16 Oct 2024 12:19:08 +0300 Subject: [PATCH 18/63] [service] Fix check for invalid kext handle (#1716) * [service] Fix check for invalid kext handle * [windows_kext] Use BTreeMap as cache structure * [windows_kext] Fix synchronization bug * Update windows_kext/kextinterface/kext_file.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update windows_kext/kextinterface/kext_file.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update windows_kext/kextinterface/kext_file.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- windows_kext/driver/Cargo.lock | 54 --------------- windows_kext/driver/Cargo.toml | 1 - windows_kext/driver/src/bandwidth.rs | 40 +++++------ windows_kext/driver/src/connection_cache.rs | 73 +-------------------- windows_kext/driver/src/connection_map.rs | 12 +--- windows_kext/driver/src/driver_hashmap.rs | 25 ------- windows_kext/driver/src/lib.rs | 1 - windows_kext/driver/src/stream_callouts.rs | 15 +++-- windows_kext/kextinterface/kext.go | 10 +-- windows_kext/kextinterface/kext_file.go | 51 +++++++++++++- 10 files changed, 86 insertions(+), 196 deletions(-) delete mode 100644 windows_kext/driver/src/driver_hashmap.rs diff --git a/windows_kext/driver/Cargo.lock b/windows_kext/driver/Cargo.lock index b8746745..4a0e0b39 100644 --- a/windows_kext/driver/Cargo.lock +++ b/windows_kext/driver/Cargo.lock @@ -2,18 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "atomic-polyfill" version = "1.0.3" @@ -57,7 +45,6 @@ checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" name = "driver" version = "0.0.0" dependencies = [ - "hashbrown", "num", "num-derive", "num-traits", @@ -76,15 +63,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", -] - [[package]] name = "heapless" version = "0.7.17" @@ -217,12 +195,6 @@ dependencies = [ "syn", ] -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - [[package]] name = "proc-macro2" version = "1.0.78" @@ -316,12 +288,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "wdk" version = "0.0.0" @@ -399,23 +365,3 @@ source = "git+https://github.com/microsoft/windows-rs?rev=dffa8b03dc4987c278d82e name = "windows_x86_64_msvc" version = "0.52.5" source = "git+https://github.com/microsoft/windows-rs?rev=dffa8b03dc4987c278d82e88015ffe96aa8ac317#dffa8b03dc4987c278d82e88015ffe96aa8ac317" - -[[package]] -name = "zerocopy" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/windows_kext/driver/Cargo.toml b/windows_kext/driver/Cargo.toml index 66dffaca..034627c0 100644 --- a/windows_kext/driver/Cargo.toml +++ b/windows_kext/driver/Cargo.toml @@ -17,7 +17,6 @@ num = { version = "0.4", default-features = false } num-derive = { version = "0.4", default-features = false } num-traits = { version = "0.2", default-features = false } smoltcp = { version = "0.10", default-features = false, features = ["proto-ipv4", "proto-ipv6"] } -hashbrown = { version = "0.14.3", default-features = false, features = ["ahash"]} # WARNING: Do not update. The version was choosen for a reason. See wdk/README.md for more detiels. [dependencies.windows-sys] diff --git a/windows_kext/driver/src/bandwidth.rs b/windows_kext/driver/src/bandwidth.rs index 4fb48786..0105ac72 100644 --- a/windows_kext/driver/src/bandwidth.rs +++ b/windows_kext/driver/src/bandwidth.rs @@ -1,14 +1,10 @@ +use alloc::collections::BTreeMap; use protocol::info::{BandwidthValueV4, BandwidthValueV6, Info}; use smoltcp::wire::{IpProtocol, Ipv4Address, Ipv6Address}; use wdk::rw_spin_lock::RwSpinLock; -use crate::driver_hashmap::DeviceHashMap; - -#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] -pub struct Key
-where - Address: Eq + PartialEq, -{ +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] +pub struct Key { pub local_ip: Address, pub local_port: u16, pub remote_ip: Address, @@ -25,32 +21,32 @@ enum Direction { Rx(usize), } pub struct Bandwidth { - stats_tcp_v4: DeviceHashMap, Value>, + stats_tcp_v4: BTreeMap, Value>, stats_tcp_v4_lock: RwSpinLock, - stats_tcp_v6: DeviceHashMap, Value>, + stats_tcp_v6: BTreeMap, Value>, stats_tcp_v6_lock: RwSpinLock, - stats_udp_v4: DeviceHashMap, Value>, + stats_udp_v4: BTreeMap, Value>, stats_udp_v4_lock: RwSpinLock, - stats_udp_v6: DeviceHashMap, Value>, + stats_udp_v6: BTreeMap, Value>, stats_udp_v6_lock: RwSpinLock, } impl Bandwidth { pub fn new() -> Self { Self { - stats_tcp_v4: DeviceHashMap::new(), + stats_tcp_v4: BTreeMap::new(), stats_tcp_v4_lock: RwSpinLock::default(), - stats_tcp_v6: DeviceHashMap::new(), + stats_tcp_v6: BTreeMap::new(), stats_tcp_v6_lock: RwSpinLock::default(), - stats_udp_v4: DeviceHashMap::new(), + stats_udp_v4: BTreeMap::new(), stats_udp_v4_lock: RwSpinLock::default(), - stats_udp_v6: DeviceHashMap::new(), + stats_udp_v6: BTreeMap::new(), stats_udp_v6_lock: RwSpinLock::default(), } } @@ -62,7 +58,7 @@ impl Bandwidth { if self.stats_tcp_v4.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_tcp_v4, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_tcp_v4, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -89,7 +85,7 @@ impl Bandwidth { if self.stats_tcp_v6.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_tcp_v6, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_tcp_v6, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -116,7 +112,7 @@ impl Bandwidth { if self.stats_udp_v4.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_udp_v4, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_udp_v4, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -140,10 +136,10 @@ impl Bandwidth { let stats_map; { let _guard = self.stats_udp_v6_lock.write_lock(); - if self.stats_tcp_v6.is_empty() { + if self.stats_udp_v6.is_empty() { return None; } - stats_map = core::mem::replace(&mut self.stats_tcp_v6, DeviceHashMap::new()); + stats_map = core::mem::replace(&mut self.stats_udp_v6, BTreeMap::new()); } let mut values = alloc::vec::Vec::with_capacity(stats_map.len()); @@ -235,8 +231,8 @@ impl Bandwidth { ); } - fn update( - map: &mut DeviceHashMap, Value>, + fn update( + map: &mut BTreeMap, Value>, lock: &mut RwSpinLock, key: Key
, bytes: Direction, diff --git a/windows_kext/driver/src/connection_cache.rs b/windows_kext/driver/src/connection_cache.rs index 665e60f4..a076df02 100644 --- a/windows_kext/driver/src/connection_cache.rs +++ b/windows_kext/driver/src/connection_cache.rs @@ -1,10 +1,8 @@ -use core::time::Duration; - use crate::{ connection::{Connection, ConnectionV4, ConnectionV6, RedirectInfo, Verdict}, connection_map::{ConnectionMap, Key}, }; -use alloc::{format, string::String, vec::Vec}; +use alloc::vec::Vec; use smoltcp::wire::IpProtocol; use wdk::rw_spin_lock::RwSpinLock; @@ -128,73 +126,4 @@ impl ConnectionCache { return size; } - - #[allow(dead_code)] - pub fn get_full_cache_info(&self) -> String { - let mut info = String::new(); - let now = wdk::utils::get_system_timestamp_ms(); - { - let _guard = self.lock_v4.read_lock(); - for ((protocol, port), connections) in self.connections_v4.iter() { - info.push_str(&format!("{} -> {}\n", protocol, port,)); - for conn in connections { - let active_time_seconds = - Duration::from_millis(now - conn.get_last_accessed_time()).as_secs(); - info.push_str(&format!( - "\t{}:{} -> {}:{} {} last active {}m {}s ago", - conn.local_address, - conn.local_port, - conn.remote_address, - conn.remote_port, - conn.verdict, - active_time_seconds / 60, - active_time_seconds % 60 - )); - if conn.has_ended() { - let end_time_seconds = - Duration::from_millis(now - conn.get_end_time()).as_secs(); - info.push_str(&format!( - "\t ended {}m {}s ago", - end_time_seconds / 60, - end_time_seconds % 60 - )); - } - info.push('\n'); - } - } - } - - { - let _guard = self.lock_v6.read_lock(); - for ((protocol, port), connections) in self.connections_v6.iter() { - info.push_str(&format!("{} -> {} \n", protocol, port)); - for conn in connections { - let active_time_seconds = - Duration::from_millis(now - conn.get_last_accessed_time()).as_secs(); - info.push_str(&format!( - "\t{}:{} -> {}:{} {} last active {}m {}s ago", - conn.local_address, - conn.local_port, - conn.remote_address, - conn.remote_port, - conn.verdict, - active_time_seconds / 60, - active_time_seconds % 60 - )); - if conn.has_ended() { - let end_time_seconds = - Duration::from_millis(now - conn.get_end_time()).as_secs(); - info.push_str(&format!( - "\t ended {}m {}s ago", - end_time_seconds / 60, - end_time_seconds % 60 - )); - } - info.push('\n'); - } - } - } - - return info; - } } diff --git a/windows_kext/driver/src/connection_map.rs b/windows_kext/driver/src/connection_map.rs index bf2210f8..7cadf87b 100644 --- a/windows_kext/driver/src/connection_map.rs +++ b/windows_kext/driver/src/connection_map.rs @@ -1,8 +1,7 @@ use core::{fmt::Display, time::Duration}; use crate::connection::Connection; -use alloc::vec::Vec; -use hashbrown::HashMap; +use alloc::{collections::BTreeMap, vec::Vec}; use smoltcp::wire::{IpAddress, IpProtocol}; #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord)] @@ -63,11 +62,11 @@ impl Key { } } -pub struct ConnectionMap(HashMap<(IpProtocol, u16), Vec>); +pub struct ConnectionMap(BTreeMap<(IpProtocol, u16), Vec>); impl ConnectionMap { pub fn new() -> Self { - Self(HashMap::new()) + Self(BTreeMap::new()) } pub fn add(&mut self, conn: T) { @@ -164,7 +163,6 @@ impl ConnectionMap { self.0.retain(|_, v| !v.is_empty()); } - #[allow(dead_code)] pub fn get_count(&self) -> usize { let mut count = 0; for conn in self.0.values() { @@ -172,8 +170,4 @@ impl ConnectionMap { } return count; } - - pub fn iter(&self) -> hashbrown::hash_map::Iter<'_, (IpProtocol, u16), Vec> { - self.0.iter() - } } diff --git a/windows_kext/driver/src/driver_hashmap.rs b/windows_kext/driver/src/driver_hashmap.rs deleted file mode 100644 index 1c8b706a..00000000 --- a/windows_kext/driver/src/driver_hashmap.rs +++ /dev/null @@ -1,25 +0,0 @@ -use core::ops::{Deref, DerefMut}; - -use hashbrown::HashMap; - -pub struct DeviceHashMap(Option>); - -impl DeviceHashMap { - pub fn new() -> Self { - Self(Some(HashMap::new())) - } -} - -impl Deref for DeviceHashMap { - type Target = HashMap; - - fn deref(&self) -> &Self::Target { - self.0.as_ref().unwrap() - } -} - -impl DerefMut for DeviceHashMap { - fn deref_mut(&mut self) -> &mut Self::Target { - self.0.as_mut().unwrap() - } -} diff --git a/windows_kext/driver/src/lib.rs b/windows_kext/driver/src/lib.rs index d13e9d3f..7d9fe3a1 100644 --- a/windows_kext/driver/src/lib.rs +++ b/windows_kext/driver/src/lib.rs @@ -13,7 +13,6 @@ mod connection; mod connection_cache; mod connection_map; mod device; -mod driver_hashmap; mod entry; mod id_cache; pub mod logger; diff --git a/windows_kext/driver/src/stream_callouts.rs b/windows_kext/driver/src/stream_callouts.rs index a6393764..f0a0f0d0 100644 --- a/windows_kext/driver/src/stream_callouts.rs +++ b/windows_kext/driver/src/stream_callouts.rs @@ -4,6 +4,8 @@ use wdk::filter_engine::{callout_data::CalloutData, layer, net_buffer::NetBuffer use crate::{bandwidth, connection::Direction}; pub fn stream_layer_tcp_v4(data: CalloutData) { + type Fields = layer::FieldsStreamV4; + let Some(device) = crate::entry::get_device() else { return; }; @@ -16,7 +18,6 @@ pub fn stream_layer_tcp_v4(data: CalloutData) { } else { return; }; - type Fields = layer::FieldsStreamV4; let local_ip = Ipv4Address::from_bytes( &data .get_value_u32(Fields::IpLocalAddress as usize) @@ -56,6 +57,8 @@ pub fn stream_layer_tcp_v4(data: CalloutData) { } pub fn stream_layer_tcp_v6(data: CalloutData) { + type Fields = layer::FieldsStreamV6; + let Some(device) = crate::entry::get_device() else { return; }; @@ -68,16 +71,18 @@ pub fn stream_layer_tcp_v6(data: CalloutData) { } else { return; }; - type Fields = layer::FieldsStreamV6; + if data_length == 0 { return; } let local_ip = Ipv6Address::from_bytes(data.get_value_byte_array16(Fields::IpLocalAddress as usize)); let local_port = data.get_value_u16(Fields::IpLocalPort as usize); + let remote_ip = Ipv6Address::from_bytes(data.get_value_byte_array16(Fields::IpRemoteAddress as usize)); let remote_port = data.get_value_u16(Fields::IpRemotePort as usize); + match direction { Direction::Outbound => { device.bandwidth_stats.update_tcp_v6_tx( @@ -105,6 +110,8 @@ pub fn stream_layer_tcp_v6(data: CalloutData) { } pub fn stream_layer_udp_v4(data: CalloutData) { + type Fields = layer::FieldsDatagramDataV4; + let Some(device) = crate::entry::get_device() else { return; }; @@ -112,7 +119,6 @@ pub fn stream_layer_udp_v4(data: CalloutData) { for nbl in NetBufferListIter::new(data.get_layer_data() as _) { data_length += nbl.get_data_length() as usize; } - type Fields = layer::FieldsDatagramDataV4; let mut direction = Direction::Inbound; if data.get_value_u8(Fields::Direction as usize) == 0 { direction = Direction::Outbound; @@ -157,6 +163,8 @@ pub fn stream_layer_udp_v4(data: CalloutData) { } pub fn stream_layer_udp_v6(data: CalloutData) { + type Fields = layer::FieldsDatagramDataV6; + let Some(device) = crate::entry::get_device() else { return; }; @@ -164,7 +172,6 @@ pub fn stream_layer_udp_v6(data: CalloutData) { for nbl in NetBufferListIter::new(data.get_layer_data() as _) { data_length += nbl.get_data_length() as usize; } - type Fields = layer::FieldsDatagramDataV6; let mut direction = Direction::Inbound; if data.get_value_u8(Fields::Direction as usize) == 0 { direction = Direction::Outbound; diff --git a/windows_kext/kextinterface/kext.go b/windows_kext/kextinterface/kext.go index 8322ead8..c9b61c7c 100644 --- a/windows_kext/kextinterface/kext.go +++ b/windows_kext/kextinterface/kext.go @@ -38,7 +38,7 @@ var ( ) const ( - winInvalidHandleValue = windows.Handle(^uintptr(0)) // Max value + winInvalidHandleValue = windows.InvalidHandle stopServiceTimeoutDuration = time.Duration(30 * time.Second) ) @@ -48,7 +48,7 @@ type KextService struct { } func (s *KextService) isValid() bool { - return s != nil && s.handle != winInvalidHandleValue && s.handle != 0 + return s != nil && s.handle != windows.InvalidHandle && s.handle != 0 } func (s *KextService) isRunning() (bool, error) { @@ -99,7 +99,7 @@ func (s *KextService) Start(wait bool) error { _ = windows.ControlService(s.handle, windows.SERVICE_CONTROL_STOP, &status) _ = windows.DeleteService(s.handle) _ = windows.CloseServiceHandle(s.handle) - s.handle = winInvalidHandleValue + s.handle = windows.InvalidHandle return err } } @@ -158,7 +158,7 @@ func (s *KextService) Delete() error { return fmt.Errorf("failed to close service handle: %s", err) } - s.handle = winInvalidHandleValue + s.handle = windows.InvalidHandle return nil } @@ -234,7 +234,7 @@ func CreateKextService(driverName string, driverPath string) (*KextService, erro return nil, err } - service = winInvalidHandleValue + service = windows.InvalidHandle log.Warning("kext: old driver service was deleted successfully") } diff --git a/windows_kext/kextinterface/kext_file.go b/windows_kext/kextinterface/kext_file.go index 045ee06e..fac6c5cd 100644 --- a/windows_kext/kextinterface/kext_file.go +++ b/windows_kext/kextinterface/kext_file.go @@ -4,6 +4,8 @@ package kextinterface import ( + "fmt" + "golang.org/x/sys/windows" ) @@ -13,7 +15,16 @@ type KextFile struct { read_slice []byte } +// Read tries to read the supplied buffer length from the driver. +// The data from the driver is read in chunks `len(f.buffer)` and the extra data is cached for the next call. +// The performance penalty of calling the function with small buffers is very small. +// The function will block until the next info packet is received from the kext. func (f *KextFile) Read(buffer []byte) (int, error) { + if err := f.IsValid(); err != nil { + return 0, fmt.Errorf("failed to read: %w", err) + } + + // If no data is available from previous calls, read from kext. if f.read_slice == nil || len(f.read_slice) == 0 { err := f.refill_read_buffer() if err != nil { @@ -22,14 +33,19 @@ func (f *KextFile) Read(buffer []byte) (int, error) { } if len(f.read_slice) >= len(buffer) { - // Write all requested bytes. + // There is enough data to fill the requested buffer. copy(buffer, f.read_slice[0:len(buffer)]) + // Move the slice to contain the remaining data. f.read_slice = f.read_slice[len(buffer):] } else { - // Write all available bytes and read again. + // There is not enough data to fill the requested buffer. + + // Write everything available. copy(buffer[0:len(f.read_slice)], f.read_slice) copiedBytes := len(f.read_slice) f.read_slice = nil + + // Read again. _, err := f.Read(buffer[copiedBytes:]) if err != nil { return 0, err @@ -51,20 +67,33 @@ func (f *KextFile) refill_read_buffer() error { return nil } +// Write sends the buffer bytes to the kext. The function will block until the whole buffer is written to the kext. func (f *KextFile) Write(buffer []byte) (int, error) { + if err := f.IsValid(); err != nil { + return 0, fmt.Errorf("failed to write: %w", err) + } var count uint32 = 0 overlapped := &windows.Overlapped{} err := windows.WriteFile(f.handle, buffer, &count, overlapped) return int(count), err } +// Close closes the handle to the kext. This will cancel all active Reads and Writes. func (f *KextFile) Close() error { + if err := f.IsValid(); err != nil { + return fmt.Errorf("failed to close: %w", err) + } err := windows.CloseHandle(f.handle) - f.handle = winInvalidHandleValue + f.handle = windows.InvalidHandle return err } +// deviceIOControl exists for compatibility with the old kext. func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) (*windows.Overlapped, error) { + if err := f.IsValid(); err != nil { + return nil, fmt.Errorf("failed to send io control: %w", err) + } + // Prepare the input data var inDataPtr *byte = nil var inDataSize uint32 = 0 if inData != nil { @@ -72,6 +101,7 @@ func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) ( inDataSize = uint32(len(inData)) } + // Prepare the output data var outDataPtr *byte = nil var outDataSize uint32 = 0 if outData != nil { @@ -79,6 +109,7 @@ func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) ( outDataSize = uint32(len(outData)) } + // Make the request to the kext. overlapped := &windows.Overlapped{} err := windows.DeviceIoControl(f.handle, code, @@ -92,6 +123,20 @@ func (f *KextFile) deviceIOControl(code uint32, inData []byte, outData []byte) ( return overlapped, nil } +// GetHandle returns the handle of the kext. func (f *KextFile) GetHandle() windows.Handle { return f.handle } + +// IsValid checks if kext file holds a valid handle to the kext driver. +func (f *KextFile) IsValid() error { + if f == nil { + return fmt.Errorf("nil kext file") + } + + if f.handle == windows.Handle(0) || f.handle == windows.InvalidHandle { + return fmt.Errorf("invalid handle") + } + + return nil +} From c02e0cdade7671e3f927f6c74b604e8505b246fa Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 16 Oct 2024 13:53:48 +0200 Subject: [PATCH 19/63] Bump kext version --- windows_kext/kextinterface/version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows_kext/kextinterface/version.txt b/windows_kext/kextinterface/version.txt index 19dfc079..5db4ff8e 100644 --- a/windows_kext/kextinterface/version.txt +++ b/windows_kext/kextinterface/version.txt @@ -1 +1 @@ -[2, 0, 3, 0] \ No newline at end of file +[2, 0, 4, 0] \ No newline at end of file From 2a40b42339c10adc71a058c5c27d08bcc6d608ba Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 28 Oct 2024 08:35:02 +0200 Subject: [PATCH 20/63] [windows_kext] Improve documentation (#1719) --- windows_kext/README.md | 46 ++++++++++++++++++--------------- windows_kext/protocol/README.md | 39 ++++++++++++++++++++++++++++ windows_kext/release/README.md | 5 ++-- 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/windows_kext/README.md b/windows_kext/README.md index f77de347..ce80d0b1 100644 --- a/windows_kext/README.md +++ b/windows_kext/README.md @@ -5,51 +5,55 @@ Implementation of Safing's Portmaster Windows kernel extension in Rust. - [Driver](driver/README.md) -> entry point. - [WDK](wdk/README.md) -> Windows Driver Kit interface. -- [Packet Path](PacketDoc.md) -> Detiled documentation of what happens to a packet when it enters the kernel extension. -- [Release](release/README.md) -> Guide how to do a release build +- [Packet Path](PacketFlow.md) -> Detailed documentation of what happens to a packet when it enters the kernel extension. +- [Release](release/README.md) -> Guide how to do a release build. +- [Windows Filtering Platform - MS](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/roadmap-for-developing-wfp-callout-drivers) -> The driver is build on top of WFP. + ### Building The Windows Portmaster Kernel Extension is currently only developed and tested for the amd64 (64-bit) architecture. -__Prerequesites:__ +__Prerequirements:__ - Visual Studio 2022 - Install C++ and Windows 11 SDK (22H2) components - Add `link.exe` and `signtool` in the PATH -- Rust +- Windows Driver Kit + - https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk +- Rust (Can be separate machine) - https://www.rust-lang.org/tools/install -- Cargo make(optional) - - https://github.com/sagiegurari/cargo-make __Setup Test Signing:__ -In order to test the driver on your machine, you will have to test sign it (starting with Windows 10). +> Not recommended for a work machine. Usually done on virtual machine dedicated for testing. +In order to test the driver on your machine, you will have to sign it (starting with Windows 10). Create a new certificate for test signing: - :: Open a *x64 Free Build Environment* console as Administrator. +```ps1 + # Open a *x64 Free Build Environment* console as Administrator. - :: Run the MakeCert.exe tool to create a test certificate: + # Run the MakeCert.exe tool to create a test certificate: MakeCert -r -pe -ss PrivateCertStore -n "CN=DriverCertificate" DriverCertificate.cer - :: Install the test certificate with CertMgr.exe: + # Install the test certificate with CertMgr.exe: CertMgr /add DriverCertificate.cer /s /r localMachine root - +``` Enable Test Signing on the dev machine: - - :: Before you can load test-signed drivers, you must enable Windows test mode. To do this, run this command: +```ps1 + # Before you can load test-signed drivers, you must enable Windows test mode. To do this, run this command: Bcdedit.exe -set TESTSIGNING ON - :: Then, restart Windows. For more information, see The TESTSIGNING Boot Configuration Option. - + # Then, restart Windows. For more information, see The TESTSIGNING Boot Configuration Option. +``` __Build driver:__ -``` -cd driver -cargo build +```sh + cd driver + cargo build ``` > Build also works on linux @@ -63,9 +67,9 @@ Run `link.bat`. - Install go - https://go.dev/dl/ -``` -cd kext_tester -go run . +```sh + cd kext_tester + go run . ``` > make sure the hardcoded path in main.go is pointing to the correct `.sys` file diff --git a/windows_kext/protocol/README.md b/windows_kext/protocol/README.md index cde5d85c..2547f988 100644 --- a/windows_kext/protocol/README.md +++ b/windows_kext/protocol/README.md @@ -2,3 +2,42 @@ Defines protocol that communicates with `kextinterface` / Portmaster. +The crate implements simple binary protocol. The communications is designed to be concurrent stream of packets. +Input and output work independent of each other. + - Pormtaster can read multiple info packets from the queue with single read request. + - Portmaster can write one command packet to the kernel extension with single write request. + +## Info: Kext -> Portmaster + +Info is a packet that sends information/events from the kernel extension to portmaster. +For example: `new connection`, `end of connection`, `bandwidth stats` ... check `info.rs` for full list. + +The Info packet contains a header that is 5 bytes +``` +0 1 2 3 4 +0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Info Type | Length | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` +> Note that one tick mark represents one bit position. + +The header is followed by the info data. + + +## Command: Portmaster -> Kext + +Command is a packet that portmaster sends to the kernel extension. +For example: `verdict response`, `shutdown`, `get logs` ... check `command.rs` for full list. + +The header of the command packet is 1 byte +``` +0 1 2 3 4 5 6 7 ++-+-+-+-+-+-+-+-+ +| Command Type | ++-+-+-+-+-+-+-+-+ +``` +> Note that one tick mark represents one bit position. + +Rest of the packet will be the payload of the command (some commands don't contain payload just the command type). + diff --git a/windows_kext/release/README.md b/windows_kext/release/README.md index 939f88d6..28898c9d 100644 --- a/windows_kext/release/README.md +++ b/windows_kext/release/README.md @@ -7,12 +7,13 @@ ### Generate the cab file - Copy the zip and extract it on a windows machine. - * Some version Visual Studio needs to be installed. + * Visual Studio 2022 and WDK need to be installed. - From VS Command Prompt / PowerShell run: ``` cd kext_release_v.../ ./build_cab.bat ``` +> Script is written for VS `$SDK_Version = "10.0.22621.0"`. If different version is used update the script. 3. Sing the cab file @@ -25,4 +26,4 @@ cd kext_release_v.../ - Wait for the process to finish, download the `.zip`. The zip will contain the release files. -> Optionally sign the .sys file. +> Optionally sign the .sys file, with company certificate. From d8f11aa650325eb8a8e4253c9deb5bef1d38ec3d Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Thu, 7 Nov 2024 15:52:26 +0200 Subject: [PATCH 21/63] Fix reading only the needed TCP/UDP header bytes (#1730) * [windows_kext] Fix reading only the needed TCP/UDP header bytes * [windows_kext] Disable debug mode * [windows_kext] Block all fragment packets * [windows_kext] Improve wording for compiler error --- windows_kext/driver/src/lib.rs | 5 +++++ windows_kext/driver/src/logger.rs | 5 +---- windows_kext/driver/src/packet_callouts.rs | 7 +++++++ windows_kext/driver/src/packet_util.rs | 13 +++++++------ windows_kext/wdk/src/filter_engine/callout_data.rs | 4 ++++ windows_kext/wdk/src/filter_engine/metadata.rs | 14 +++++++++++--- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/windows_kext/driver/src/lib.rs b/windows_kext/driver/src/lib.rs index 7d9fe3a1..45bc6c60 100644 --- a/windows_kext/driver/src/lib.rs +++ b/windows_kext/driver/src/lib.rs @@ -22,6 +22,11 @@ mod stream_callouts; use wdk::allocator::WindowsAllocator; +// For consistent behavior during development and production only release mode should be used. +// Certain behavior of the compiler will change and this can result in errors and different behavior in debug and release mode. +#[cfg(debug_assertions)] +compile_error!("Must be built in release mode to ensure consistent behavior and prevent optimization-related issues. Use `cargo build --release`."); + #[cfg(not(test))] use core::panic::PanicInfo; diff --git a/windows_kext/driver/src/logger.rs b/windows_kext/driver/src/logger.rs index 5a0440a2..129f9f7c 100644 --- a/windows_kext/driver/src/logger.rs +++ b/windows_kext/driver/src/logger.rs @@ -6,11 +6,8 @@ use core::{ }; use protocol::info::{Info, Severity}; -#[cfg(not(debug_assertions))] pub const LOG_LEVEL: u8 = Severity::Warning as u8; - -#[cfg(debug_assertions)] -pub const LOG_LEVEL: u8 = Severity::Trace as u8; +// pub const LOG_LEVEL: u8 = Severity::Trace as u8; pub const MAX_LOG_LINE_SIZE: usize = 150; diff --git a/windows_kext/driver/src/packet_callouts.rs b/windows_kext/driver/src/packet_callouts.rs index fb3ee90b..4609aad0 100644 --- a/windows_kext/driver/src/packet_callouts.rs +++ b/windows_kext/driver/src/packet_callouts.rs @@ -110,6 +110,13 @@ fn ip_packet_layer( interface_index: u32, sub_interface_index: u32, ) { + // Block all fragment data. No easy way to keep track of the origin and they are rarely used. + if data.is_fragment_data() { + data.action_block(); + crate::err!("blocked fragment packet"); + return; + } + let Some(device) = crate::entry::get_device() else { return; }; diff --git a/windows_kext/driver/src/packet_util.rs b/windows_kext/driver/src/packet_util.rs index 42b4dac7..6f5b4eb3 100644 --- a/windows_kext/driver/src/packet_util.rs +++ b/windows_kext/driver/src/packet_util.rs @@ -245,8 +245,6 @@ fn print_packet(packet: &[u8]) { /// /// * `Ok(Key)` - A key containing the protocol, local and remote addresses and ports. /// * `Err(String)` - An error message if the function fails to get net_buffer data. -const HEADERS_LEN: usize = smoltcp::wire::IPV4_HEADER_LEN + smoltcp::wire::TCP_HEADER_LEN; - fn get_ports(packet: &[u8], protocol: smoltcp::wire::IpProtocol) -> (u16, u16) { match protocol { smoltcp::wire::IpProtocol::Tcp => { @@ -262,12 +260,13 @@ fn get_ports(packet: &[u8], protocol: smoltcp::wire::IpProtocol) -> (u16, u16) { } pub fn get_key_from_nbl_v4(nbl: &NetBufferList, direction: Direction) -> Result { - // Get bytes - let mut headers = [0; HEADERS_LEN]; + // Get first bytes of the packet. IP header + src port (2 bytes) + dst port (2 bytes) + let mut headers = [0; smoltcp::wire::IPV4_HEADER_LEN + 4]; if nbl.read_bytes(&mut headers).is_err() { return Err("failed to get net_buffer data".to_string()); } + // This will panic in debug mode, probably because of runtime checks. // Parse packet let ip_packet = Ipv4Packet::new_unchecked(&headers); let (src_port, dst_port) = get_ports( @@ -307,11 +306,13 @@ pub fn get_key_from_nbl_v4(nbl: &NetBufferList, direction: Direction) -> Result< /// * `Ok(Key)` - A key containing the protocol, local and remote addresses and ports. /// * `Err(String)` - An error message if the function fails to get net_buffer data. pub fn get_key_from_nbl_v6(nbl: &NetBufferList, direction: Direction) -> Result { - // Get bytes - let mut headers = [0; smoltcp::wire::IPV6_HEADER_LEN + smoltcp::wire::TCP_HEADER_LEN]; + // Get first bytes of the packet. IP header + src port (2 bytes) + dst port (2 bytes) + let mut headers = [0; smoltcp::wire::IPV6_HEADER_LEN + 4]; let Ok(()) = nbl.read_bytes(&mut headers) else { return Err("failed to get net_buffer data".to_string()); }; + + // This will panic in debug mode, probably because of runtime checks. // Parse packet let ip_packet = Ipv6Packet::new_unchecked(&headers); let (src_port, dst_port) = get_ports( diff --git a/windows_kext/wdk/src/filter_engine/callout_data.rs b/windows_kext/wdk/src/filter_engine/callout_data.rs index bb861f84..abb5e318 100644 --- a/windows_kext/wdk/src/filter_engine/callout_data.rs +++ b/windows_kext/wdk/src/filter_engine/callout_data.rs @@ -133,6 +133,10 @@ impl<'a> CalloutData<'a> { } } + pub fn is_fragment_data(&self) -> bool { + unsafe { (*self.metadata).is_fragment_data() } + } + pub fn pend_operation( &mut self, packet_list: Option, diff --git a/windows_kext/wdk/src/filter_engine/metadata.rs b/windows_kext/wdk/src/filter_engine/metadata.rs index 632830fa..55b3b7de 100644 --- a/windows_kext/wdk/src/filter_engine/metadata.rs +++ b/windows_kext/wdk/src/filter_engine/metadata.rs @@ -7,9 +7,9 @@ use windows_sys::Win32::{ NetworkManagement::{ IpHelper::IP_ADDRESS_PREFIX, WindowsFilteringPlatform::{ - FWPS_METADATA_FIELD_COMPLETION_HANDLE, FWPS_METADATA_FIELD_PROCESS_ID, - FWPS_METADATA_FIELD_PROCESS_PATH, FWPS_METADATA_FIELD_REMOTE_SCOPE_ID, - FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA, + FWPS_METADATA_FIELD_COMPLETION_HANDLE, FWPS_METADATA_FIELD_FRAGMENT_DATA, + FWPS_METADATA_FIELD_PROCESS_ID, FWPS_METADATA_FIELD_PROCESS_PATH, + FWPS_METADATA_FIELD_REMOTE_SCOPE_ID, FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA, FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE, FWP_BYTE_BLOB, FWP_DIRECTION, }, }, @@ -137,6 +137,14 @@ impl FwpsIncomingMetadataValues { None } + pub(crate) fn is_fragment_data(&self) -> bool { + if self.has_field(FWPS_METADATA_FIELD_FRAGMENT_DATA) { + return self.fragment_metadata.fragment_offset != 0; + } + + false + } + pub(crate) unsafe fn get_control_data(&self) -> Option> { if self.has_field(FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA) { if self.control_data.is_null() || self.control_data_length == 0 { From 1ff6f3463103873483a552eef16f075850d83aa3 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 15:11:07 +0100 Subject: [PATCH 22/63] Notify packet issues asynchronously --- service/compat/callbacks.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/service/compat/callbacks.go b/service/compat/callbacks.go index 2abfa858..71fd8b69 100644 --- a/service/compat/callbacks.go +++ b/service/compat/callbacks.go @@ -3,6 +3,7 @@ package compat import ( "net" + "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/network/packet" "github.com/safing/portmaster/service/process" ) @@ -31,10 +32,16 @@ func SubmitDNSCheckDomain(subdomain string) (respondWith net.IP) { // ReportSecureDNSBypassIssue reports a DNS bypassing issue for the given process. func ReportSecureDNSBypassIssue(p *process.Process) { - secureDNSBypassIssue.notify(p) + module.mgr.Go("report secure dns bypass issue", func(w *mgr.WorkerCtx) error { + secureDNSBypassIssue.notify(p) + return nil + }) } // ReportMultiPeerUDPTunnelIssue reports a multi-peer UDP tunnel for the given process. func ReportMultiPeerUDPTunnelIssue(p *process.Process) { - multiPeerUDPTunnelIssue.notify(p) + module.mgr.Go("report multi-peer udp tunnel issue", func(w *mgr.WorkerCtx) error { + multiPeerUDPTunnelIssue.notify(p) + return nil + }) } From ed861d606b4b62fdd705de7f9b83edbb164e46f5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 15:13:44 +0100 Subject: [PATCH 23/63] Make saving IP and CNAMEs more defensive --- service/firewall/dns.go | 6 +++--- service/nameserver/nameserver.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/service/firewall/dns.go b/service/firewall/dns.go index 8a6e1973..9b1a55e5 100644 --- a/service/firewall/dns.go +++ b/service/firewall/dns.go @@ -302,11 +302,11 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw Expires: rrCache.Expires, } - // Resolve all CNAMEs in the correct order and add the to the record. + // Resolve all CNAMEs in the correct order and add the to the record - up to max 50 layers. domain := q.FQDN - for { + for range 50 { nextDomain, isCNAME := cnames[domain] - if !isCNAME { + if !isCNAME || nextDomain == domain { break } diff --git a/service/nameserver/nameserver.go b/service/nameserver/nameserver.go index c699cd99..1d346220 100644 --- a/service/nameserver/nameserver.go +++ b/service/nameserver/nameserver.go @@ -224,8 +224,8 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) } // Save the request as open, as we don't know if there will be a connection or not. - network.SaveOpenDNSRequest(q, rrCache, conn) firewall.UpdateIPsAndCNAMEs(q, rrCache, conn) + network.SaveOpenDNSRequest(q, rrCache, conn) case network.VerdictUndeterminable: fallthrough From 590fe74610e0223935e84dd11ecdc1ac9eacc414 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Nov 2024 15:42:49 +0100 Subject: [PATCH 24/63] Update deps --- go.mod | 39 +++++++++++++-------------- go.sum | 83 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/go.mod b/go.mod index eb548caa..8ffd3e37 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ replace github.com/tc-hib/winres => github.com/dhaavi/winres v0.2.2 require ( github.com/VictoriaMetrics/metrics v1.35.1 - github.com/Xuanwo/go-locale v1.1.1 + github.com/Xuanwo/go-locale v1.1.2 github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 github.com/agext/levenshtein v1.2.3 github.com/armon/go-radix v1.0.0 @@ -15,7 +15,7 @@ require ( github.com/bluele/gcache v0.0.2 github.com/brianvoe/gofakeit v3.18.0+incompatible github.com/cilium/ebpf v0.16.0 - github.com/coreos/go-iptables v0.7.0 + github.com/coreos/go-iptables v0.8.0 github.com/davecgh/go-spew v1.1.1 github.com/dgraph-io/badger v1.6.2 github.com/florianl/go-conntrack v0.4.0 @@ -31,7 +31,7 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.7.0 - github.com/jackc/puddle/v2 v2.2.1 + github.com/jackc/puddle/v2 v2.2.2 github.com/lmittmann/tint v1.0.5 github.com/maruel/panicparse/v2 v2.3.1 github.com/mat/besticon v3.12.0+incompatible @@ -52,18 +52,18 @@ require ( github.com/tannerryan/ring v1.1.2 github.com/tc-hib/winres v0.3.1 github.com/tevino/abool v1.2.0 - github.com/tidwall/gjson v1.17.3 + github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 github.com/vincent-petithory/dataurl v1.0.0 - go.etcd.io/bbolt v1.3.10 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/image v0.19.0 - golang.org/x/net v0.28.0 - golang.org/x/sync v0.8.0 - golang.org/x/sys v0.24.0 + go.etcd.io/bbolt v1.3.11 + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f + golang.org/x/image v0.22.0 + golang.org/x/net v0.31.0 + golang.org/x/sync v0.9.0 + golang.org/x/sys v0.27.0 gopkg.in/yaml.v3 v3.0.1 - zombiezen.com/go/sqlite v1.3.0 + zombiezen.com/go/sqlite v1.4.0 ) require ( @@ -84,8 +84,9 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/maruel/panicparse/v2 v2.3.1 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -100,7 +101,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.8.0 // indirect + github.com/tklauser/numcpus v0.9.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect @@ -108,14 +109,14 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/text v0.20.0 // indirect + golang.org/x/tools v0.27.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - modernc.org/libc v1.59.9 // indirect + modernc.org/libc v1.61.0 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.32.0 // indirect + modernc.org/sqlite v1.33.1 // indirect ) diff --git a/go.sum b/go.sum index ef8feec4..6f47c5af 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/VictoriaMetrics/metrics v1.35.1 h1:o84wtBKQbzLdDy14XeskkCZih6anG+veZ1SwJHFGwrU= github.com/VictoriaMetrics/metrics v1.35.1/go.mod h1:r7hveu6xMdUACXvB8TYdAj8WEsKzWB0EkpJN+RDtOf8= -github.com/Xuanwo/go-locale v1.1.1 h1:nhvzo1phY4LRwdrwVwKWXn5iZ0pMwwsa3o29yiDRuZc= -github.com/Xuanwo/go-locale v1.1.1/go.mod h1:ldC3FzZeMYALkL3YYpwhr4iVYdOIUx42kORcnAHdKUo= +github.com/Xuanwo/go-locale v1.1.2 h1:6H+olvrQcyVOZ+GAC2rXu4armacTT4ZrFCA0mB24XVo= +github.com/Xuanwo/go-locale v1.1.2/go.mod h1:1JBER4QV7Ji39GJ4AvVlfvqmTUqopzxQxdg2mXYOw94= github.com/aead/ecdh v0.2.0 h1:pYop54xVaq/CEREFEcukHRZfTdjiWvYIsZDXXrBapQQ= github.com/aead/ecdh v0.2.0/go.mod h1:a9HHtXuSo8J1Js1MwLQx2mBhkXMT6YwUmVVEY4tTB8U= github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 h1:5L8Mj9Co9sJVgW3TpYk2gxGJnDjsYuboNTcRmbtGKGs= @@ -34,8 +34,8 @@ github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= -github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= +github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -133,8 +133,8 @@ github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cO github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= -github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= @@ -151,8 +151,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786 h1:N527AHMa79 github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786/go.mod h1:v4hqbTdfQngbVSZJVWUhGE/lbTFf9jb+ygmNUDQMuOs= github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM= github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= -github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= -github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -239,6 +239,8 @@ github.com/safing/jess v0.3.4 h1:/p6ensqEUn2jI/z1EB9JUdwH4MJQirh/C9jEwNBzxw8= github.com/safing/jess v0.3.4/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= github.com/safing/jess v0.3.5 h1:KS5elTKfWcDUow8SUoCj5QdyyGJNoExJNySerNkbxUU= github.com/safing/jess v0.3.5/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= +github.com/safing/jess v0.3.5 h1:KS5elTKfWcDUow8SUoCj5QdyyGJNoExJNySerNkbxUU= +github.com/safing/jess v0.3.5/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= github.com/safing/structures v1.1.0 h1:QzHBQBjaZSLzw2f6PM4ibSmPcfBHAOB5CKJ+k4FYkhQ= github.com/safing/structures v1.1.0/go.mod h1:QUrB74FcU41ahQ5oy3YNFCoSq+twE/n3+vNZc2K35II= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= @@ -280,8 +282,8 @@ github.com/tannerryan/ring v1.1.2/go.mod h1:DkELJEjbZhJBtFKR9Xziwj3HKZnb/knRgljN github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= -github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -291,8 +293,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= -github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= +github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 h1:UFHFmFfixpmfRBcxuu+LA9l8MdURWVdVNUHxO5n1d2w= github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26/go.mod h1:IGhd0qMDsUa9acVjsbsT7bu3ktadtGOHI79+idTew/M= @@ -320,26 +322,26 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= -go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= -golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= +golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g= +golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -361,15 +363,15 @@ golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -405,10 +407,9 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -416,16 +417,16 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -449,14 +450,14 @@ honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.20.7 h1:skrinQsjxWfvj6nbC3ztZPJy+NuwmB3hV9zX/pthNYQ= -modernc.org/ccgo/v4 v4.20.7/go.mod h1:UOkI3JSG2zT4E2ioHlncSOZsXbuDCZLvPi3uMlZT5GY= +modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4= +modernc.org/ccgo/v4 v4.21.0/go.mod h1:h6kt6H/A2+ew/3MW/p6KEoQmrq/i3pr0J/SiwiaF/g0= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/libc v1.59.9 h1:k+nNDDakwipimgmJ1D9H466LhFeSkaPPycAs1OZiDmY= -modernc.org/libc v1.59.9/go.mod h1:EY/egGEU7Ju66eU6SBqCNYaFUDuc4npICkMWnU5EE3A= +modernc.org/libc v1.61.0 h1:eGFcvWpqlnoGwzZeZe3PWJkkKbM/3SUGyk1DVZQ0TpE= +modernc.org/libc v1.61.0/go.mod h1:DvxVX89wtGTu+r72MLGhygpfi3aUGgZRdAYGCAVVud0= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -465,11 +466,11 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= -modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= +modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -zombiezen.com/go/sqlite v1.3.0 h1:98g1gnCm+CNz6AuQHu0gqyw7gR2WU3O3PJufDOStpUs= -zombiezen.com/go/sqlite v1.3.0/go.mod h1:yRl27//s/9aXU3RWs8uFQwjkTG9gYNGEls6+6SvrclY= +zombiezen.com/go/sqlite v1.4.0 h1:N1s3RIljwtp4541Y8rM880qgGIgq3fTD2yks1xftnKU= +zombiezen.com/go/sqlite v1.4.0/go.mod h1:0w9F1DN9IZj9AcLS9YDKMboubCACkwYCGkzoy3eG5ik= From f35256c025c9a26347ae6018b4e7afb65a6d8349 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 25 Nov 2024 14:03:35 +0200 Subject: [PATCH 25/63] Feature/kext default action drop (#1747) * [windows_kext] Make default action to drop * [windows_kext] Minor improvments --- windows_kext/driver/src/ale_callouts.rs | 3 +++ windows_kext/driver/src/packet_callouts.rs | 7 +++++-- windows_kext/wdk/src/filter_engine/callout_data.rs | 11 ++++------- windows_kext/wdk/src/filter_engine/classify.rs | 5 +++++ windows_kext/wdk/src/filter_engine/ffi.rs | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/windows_kext/driver/src/ale_callouts.rs b/windows_kext/driver/src/ale_callouts.rs index ed478938..51c5cc30 100644 --- a/windows_kext/driver/src/ale_callouts.rs +++ b/windows_kext/driver/src/ale_callouts.rs @@ -105,6 +105,9 @@ pub fn ale_layer_connect_v6(data: CalloutData) { } fn ale_layer_auth(mut data: CalloutData, ale_data: AleLayerData) { + // Make the default path as drop. + data.block_and_absorb(); + let Some(device) = crate::entry::get_device() else { return; }; diff --git a/windows_kext/driver/src/packet_callouts.rs b/windows_kext/driver/src/packet_callouts.rs index 4609aad0..1e8c28f1 100644 --- a/windows_kext/driver/src/packet_callouts.rs +++ b/windows_kext/driver/src/packet_callouts.rs @@ -110,9 +110,12 @@ fn ip_packet_layer( interface_index: u32, sub_interface_index: u32, ) { + // Make the default path as drop. + data.block_and_absorb(); + // Block all fragment data. No easy way to keep track of the origin and they are rarely used. if data.is_fragment_data() { - data.action_block(); + data.block_and_absorb(); crate::err!("blocked fragment packet"); return; } @@ -147,7 +150,7 @@ fn ip_packet_layer( } { Ok(key) => key, Err(err) => { - crate::dbg!("failed to get key from nbl: {}", err); + crate::err!("failed to get key from nbl: {}", err); return; } }; diff --git a/windows_kext/wdk/src/filter_engine/callout_data.rs b/windows_kext/wdk/src/filter_engine/callout_data.rs index abb5e318..ff155dd1 100644 --- a/windows_kext/wdk/src/filter_engine/callout_data.rs +++ b/windows_kext/wdk/src/filter_engine/callout_data.rs @@ -161,24 +161,28 @@ impl<'a> CalloutData<'a> { pub fn action_permit(&mut self) { unsafe { (*self.classify_out).action_permit(); + (*self.classify_out).clear_absorb_flag(); } } pub fn action_continue(&mut self) { unsafe { (*self.classify_out).action_continue(); + (*self.classify_out).clear_absorb_flag(); } } pub fn action_block(&mut self) { unsafe { (*self.classify_out).action_block(); + (*self.classify_out).clear_absorb_flag(); } } pub fn action_none(&mut self) { unsafe { (*self.classify_out).set_none(); + (*self.classify_out).clear_absorb_flag(); } } @@ -198,13 +202,6 @@ impl<'a> CalloutData<'a> { self.get_value_u32(flags_index) & FWP_CONDITION_FLAG_IS_REAUTHORIZE > 0 } - pub fn parmit_and_absorb(&mut self) { - unsafe { - (*self.classify_out).action_permit(); - (*self.classify_out).set_absorb(); - } - } - pub fn get_callout_id(&self) -> usize { self.callout_id } diff --git a/windows_kext/wdk/src/filter_engine/classify.rs b/windows_kext/wdk/src/filter_engine/classify.rs index 1acff2ed..6d5b9b05 100644 --- a/windows_kext/wdk/src/filter_engine/classify.rs +++ b/windows_kext/wdk/src/filter_engine/classify.rs @@ -80,6 +80,11 @@ impl ClassifyOut { self.flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } + // Removes the absorb flag. + pub fn clear_absorb_flag(&mut self) { + self.flags &= !FWPS_CLASSIFY_OUT_FLAG_ABSORB; + } + // Clear the write flag permission. Next filter in the chain will not change the action. pub fn clear_write_flag(&mut self) { self.rights &= !FWPS_RIGHT_ACTION_WRITE; diff --git a/windows_kext/wdk/src/filter_engine/ffi.rs b/windows_kext/wdk/src/filter_engine/ffi.rs index 45103272..bf5fa361 100644 --- a/windows_kext/wdk/src/filter_engine/ffi.rs +++ b/windows_kext/wdk/src/filter_engine/ffi.rs @@ -62,7 +62,7 @@ pub(crate) fn register_sublayer( sublayer.displayData.name = name.as_ptr() as _; sublayer.displayData.description = description.as_ptr() as _; sublayer.flags = 0; - sublayer.weight = 0xFFFF; + sublayer.weight = 0xFFFF; // Set to Max value. Weight compared to other sublayers. let status = FwpmSubLayerAdd0(filter_engine_handle, &sublayer, core::ptr::null_mut()); check_ntstatus(status as i32)?; From 85031e861b4972334eb525d1bafca111d6f6a1fb Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 26 Nov 2024 16:59:06 +0200 Subject: [PATCH 26/63] [desktop] Update tauri (#1760) --- Earthfile | 3 +- desktop/angular/package-lock.json | 134 +- desktop/angular/package.json | 14 +- desktop/tauri/src-tauri/Cargo.toml | 16 +- .../src-tauri/gen/schemas/desktop-schema.json | 4 +- .../src-tauri/gen/schemas/linux-schema.json | 4 +- .../src-tauri/gen/schemas/windows-schema.json | 2705 +++++++---------- desktop/tauri/src-tauri/src/traymenu.rs | 4 +- 8 files changed, 1141 insertions(+), 1743 deletions(-) diff --git a/Earthfile b/Earthfile index 8937bd05..5d720d17 100644 --- a/Earthfile +++ b/Earthfile @@ -420,8 +420,7 @@ rust-base: DO rust+INIT --keep_fingerprints=true - # For now we need tauri-cli 2.0.0 for bulding - DO rust+CARGO --args="install tauri-cli --version ${tauri_version} --locked" + DO rust+CARGO --args="install tauri-cli --version 2.1.0" # Explicitly cache here. SAVE IMAGE --cache-hint diff --git a/desktop/angular/package-lock.json b/desktop/angular/package-lock.json index b8527c1d..8bf3faab 100644 --- a/desktop/angular/package-lock.json +++ b/desktop/angular/package-lock.json @@ -23,13 +23,13 @@ "@fortawesome/free-brands-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@tauri-apps/api": ">=2.0.0-rc.1", - "@tauri-apps/plugin-cli": ">=2.0.0-rc.1", - "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-rc.1", - "@tauri-apps/plugin-dialog": ">=2.0.0-rc.1", - "@tauri-apps/plugin-notification": ">=2.0.0-rc.1", - "@tauri-apps/plugin-os": ">=2.0.0-rc.1", - "@tauri-apps/plugin-shell": "^2.0.0-rc", + "@tauri-apps/api": ">=2.1.1", + "@tauri-apps/plugin-cli": ">=2.0.0", + "@tauri-apps/plugin-clipboard-manager": ">=2.0.0", + "@tauri-apps/plugin-dialog": ">=2.0.0", + "@tauri-apps/plugin-notification": ">=2.0.0", + "@tauri-apps/plugin-os": ">=2.0.0", + "@tauri-apps/plugin-shell": "^2.0.1", "autoprefixer": "^10.4.14", "d3": "^7.8.4", "data-urls": "^5.0.0", @@ -4406,9 +4406,9 @@ "peer": true }, "node_modules/@tauri-apps/api": { - "version": "2.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.4.tgz", - "integrity": "sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.1.1.tgz", + "integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==", "license": "Apache-2.0 OR MIT", "funding": { "type": "opencollective", @@ -4416,57 +4416,57 @@ } }, "node_modules/@tauri-apps/plugin-cli": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0-rc.1.tgz", - "integrity": "sha512-EcSTRfEU3zzlNbgwVtZVzqB19z3PNjyXD9H+YXuuLpV+Hwuh6Oi1fhUdCI0mp5zr9HSMWE+HzHkpBI7sVP1RyA==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0.tgz", + "integrity": "sha512-glQmlL1IiCGEa1FHYa/PTPSeYhfu56omLRgHXWlJECDt6DbJyRuJWVgtkQfUxtqnVdYnnU+DGIGeiInoEqtjLw==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-clipboard-manager": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.1.tgz", - "integrity": "sha512-hFgUABMmQuVGKwHb8PR9fuqfk0WRkedbWUt/ZV5sL4Q6kLrsp3JYJvtzVPeMYdeBvMqHl8WXNxAc/zwSld2h9w==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0.tgz", + "integrity": "sha512-V1sXmbjnwfXt/r48RJMwfUmDMSaP/8/YbH4CLNxt+/sf1eHlIP8PRFdFDQwLN0cNQKu2rqQVbG/Wc/Ps6cDUhw==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-dialog": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.1.tgz", - "integrity": "sha512-H28gh6BfZtjflHQ+HrmWwunDriBI3AQLAKnMs50GA6zeNUULqbQr7VXbAAKeJL/0CmWcecID4PKXVoSlaWRhEg==", - "license": "MIT or APACHE-2.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.1.tgz", + "integrity": "sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-notification": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-rc.1.tgz", - "integrity": "sha512-ddDj7xM8XR7Zv2vdpofNXlLjcp49p/VjlL0D+/eBcMuyooaLNMor3jz/+H6s23iHerdxMWA50mzy26BRN1BySA==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0.tgz", + "integrity": "sha512-6qEDYJS7mgXZWLXA0EFL+DVCJh8sJlzSoyw6B50pxhLPVFjc5Vr5DVzl5W3mUHaYhod5wsC984eQnlCCGqxYDA==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-os": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.1.tgz", - "integrity": "sha512-PV8zlSTmYfiN2xzILUmlDSEycS7UYbH2yXk/ZqF+qQU6/s+OVQvmSth4EhllFjcpvPbtqELvpzfjw+2qEouchA==", - "license": "MIT or APACHE-2.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0.tgz", + "integrity": "sha512-M7hG/nNyQYTJxVG/UhTKhp9mpXriwWzrs9mqDreB8mIgqA3ek5nHLdwRZJWhkKjZrnDT4v9CpA9BhYeplTlAiA==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tauri-apps/plugin-shell": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.1.tgz", - "integrity": "sha512-JtNROc0rqEwN/g93ig5pK4cl1vUo2yn+osCpY9de64cy/d9hRzof7AuYOgvt/Xcd5VPQmlgo2AGvUh5sQRSR1A==", - "license": "MIT or APACHE-2.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.1.tgz", + "integrity": "sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==", + "license": "MIT OR Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "node_modules/@tootallnate/once": { @@ -21067,56 +21067,56 @@ "peer": true }, "@tauri-apps/api": { - "version": "2.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.4.tgz", - "integrity": "sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.1.1.tgz", + "integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==" }, "@tauri-apps/plugin-cli": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0-rc.1.tgz", - "integrity": "sha512-EcSTRfEU3zzlNbgwVtZVzqB19z3PNjyXD9H+YXuuLpV+Hwuh6Oi1fhUdCI0mp5zr9HSMWE+HzHkpBI7sVP1RyA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0.tgz", + "integrity": "sha512-glQmlL1IiCGEa1FHYa/PTPSeYhfu56omLRgHXWlJECDt6DbJyRuJWVgtkQfUxtqnVdYnnU+DGIGeiInoEqtjLw==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-clipboard-manager": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.1.tgz", - "integrity": "sha512-hFgUABMmQuVGKwHb8PR9fuqfk0WRkedbWUt/ZV5sL4Q6kLrsp3JYJvtzVPeMYdeBvMqHl8WXNxAc/zwSld2h9w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0.tgz", + "integrity": "sha512-V1sXmbjnwfXt/r48RJMwfUmDMSaP/8/YbH4CLNxt+/sf1eHlIP8PRFdFDQwLN0cNQKu2rqQVbG/Wc/Ps6cDUhw==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-dialog": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.1.tgz", - "integrity": "sha512-H28gh6BfZtjflHQ+HrmWwunDriBI3AQLAKnMs50GA6zeNUULqbQr7VXbAAKeJL/0CmWcecID4PKXVoSlaWRhEg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.1.tgz", + "integrity": "sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-notification": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-rc.1.tgz", - "integrity": "sha512-ddDj7xM8XR7Zv2vdpofNXlLjcp49p/VjlL0D+/eBcMuyooaLNMor3jz/+H6s23iHerdxMWA50mzy26BRN1BySA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0.tgz", + "integrity": "sha512-6qEDYJS7mgXZWLXA0EFL+DVCJh8sJlzSoyw6B50pxhLPVFjc5Vr5DVzl5W3mUHaYhod5wsC984eQnlCCGqxYDA==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-os": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.1.tgz", - "integrity": "sha512-PV8zlSTmYfiN2xzILUmlDSEycS7UYbH2yXk/ZqF+qQU6/s+OVQvmSth4EhllFjcpvPbtqELvpzfjw+2qEouchA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0.tgz", + "integrity": "sha512-M7hG/nNyQYTJxVG/UhTKhp9mpXriwWzrs9mqDreB8mIgqA3ek5nHLdwRZJWhkKjZrnDT4v9CpA9BhYeplTlAiA==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tauri-apps/plugin-shell": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.1.tgz", - "integrity": "sha512-JtNROc0rqEwN/g93ig5pK4cl1vUo2yn+osCpY9de64cy/d9hRzof7AuYOgvt/Xcd5VPQmlgo2AGvUh5sQRSR1A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.1.tgz", + "integrity": "sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==", "requires": { - "@tauri-apps/api": "^2.0.0-rc.4" + "@tauri-apps/api": "^2.0.0" } }, "@tootallnate/once": { diff --git a/desktop/angular/package.json b/desktop/angular/package.json index 5e916e51..2b0f9ea2 100644 --- a/desktop/angular/package.json +++ b/desktop/angular/package.json @@ -37,13 +37,13 @@ "@fortawesome/free-brands-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@tauri-apps/api": ">=2.0.0-rc.1", - "@tauri-apps/plugin-cli": ">=2.0.0-rc.1", - "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-rc.1", - "@tauri-apps/plugin-dialog": ">=2.0.0-rc.1", - "@tauri-apps/plugin-notification": ">=2.0.0-rc.1", - "@tauri-apps/plugin-os": ">=2.0.0-rc.1", - "@tauri-apps/plugin-shell": "^2.0.0-rc", + "@tauri-apps/api": ">=2.1.1", + "@tauri-apps/plugin-cli": ">=2.0.0", + "@tauri-apps/plugin-clipboard-manager": ">=2.0.0", + "@tauri-apps/plugin-dialog": ">=2.0.0", + "@tauri-apps/plugin-notification": ">=2.0.0", + "@tauri-apps/plugin-os": ">=2.0.0", + "@tauri-apps/plugin-shell": "^2.0.1", "autoprefixer": "^10.4.14", "d3": "^7.8.4", "data-urls": "^5.0.0", diff --git a/desktop/tauri/src-tauri/Cargo.toml b/desktop/tauri/src-tauri/Cargo.toml index 78f87926..33e2dfeb 100644 --- a/desktop/tauri/src-tauri/Cargo.toml +++ b/desktop/tauri/src-tauri/Cargo.toml @@ -12,21 +12,21 @@ rust-version = "1.64" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -tauri-build = { version = "2.0.1", features = [] } +tauri-build = { version = "2.0.3", features = [] } [dependencies] # Tauri -tauri = { version = "2.0.1", features = ["tray-icon", "image-png", "config-json5", "devtools"] } -tauri-plugin-shell = "2.0.1" -tauri-plugin-dialog = "2.0.1" -tauri-plugin-clipboard-manager = "2.0.1" +tauri = { version = "2.1.1", features = ["tray-icon", "image-png", "config-json5", "devtools"] } +tauri-plugin-shell = "2.0.2" +tauri-plugin-dialog = "2.0.3" +tauri-plugin-clipboard-manager = "2.0.2" tauri-plugin-os = "2.0.1" tauri-plugin-single-instance = "2.0.1" tauri-plugin-notification = "2.0.1" -tauri-plugin-log = "2.0.1" -tauri-plugin-window-state = "2.0.1" +tauri-plugin-log = "2.0.2" +tauri-plugin-window-state = "2.0.2" -tauri-cli = "2.0.1" +tauri-cli = "2.1.0" clap_lex = "0.7.2" # General diff --git a/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json b/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json index 10fb08fb..905008b7 100644 --- a/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json +++ b/desktop/tauri/src-tauri/gen/schemas/desktop-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/desktop/tauri/src-tauri/gen/schemas/linux-schema.json b/desktop/tauri/src-tauri/gen/schemas/linux-schema.json index 10fb08fb..905008b7 100644 --- a/desktop/tauri/src-tauri/gen/schemas/linux-schema.json +++ b/desktop/tauri/src-tauri/gen/schemas/linux-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/desktop/tauri/src-tauri/gen/schemas/windows-schema.json b/desktop/tauri/src-tauri/gen/schemas/windows-schema.json index 797ccb5c..905008b7 100644 --- a/desktop/tauri/src-tauri/gen/schemas/windows-schema.json +++ b/desktop/tauri/src-tauri/gen/schemas/windows-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" @@ -133,2803 +133,2202 @@ { "description": "Reference a permission or permission set by identifier and extends its scope.", "type": "object", - "oneOf": [ + "allOf": [ { - "type": "object", - "required": [ - "identifier" - ], + "if": { + "properties": { + "identifier": { + "anyOf": [ + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "const": "shell:default" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute" + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + } + ] + } + } + }, + "then": { + "properties": { + "allow": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + }, + "deny": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + } + } + }, "properties": { "identifier": { - "oneOf": [ + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", - "type": "string", - "enum": [ - "shell:default" - ] - }, + "$ref": "#/definitions/Identifier" + } + ] + } + } + }, + { + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-execute" - ] - }, - { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-kill" - ] - }, - { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-open" - ] - }, - { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-spawn" - ] - }, - { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] - }, - { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-execute" - ] - }, - { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-kill" - ] - }, - { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-open" - ] - }, - { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-spawn" - ] - }, - { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", - "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "$ref": "#/definitions/Identifier" } ] }, "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } }, "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], "items": { - "title": "Entry", - "description": "A command allowed to be executed by the webview API.", - "type": "object", - "required": [ - "args", - "cmd", - "name", - "sidecar" - ], - "properties": { - "args": { - "description": "The allowed arguments for the command execution.", - "allOf": [ - { - "$ref": "#/definitions/ShellAllowedArgs" - } - ] - }, - "cmd": { - "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", - "type": "string" - }, - "name": { - "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", - "type": "string" - }, - "sidecar": { - "description": "If this command is a sidecar command.", - "type": "boolean" - } - } + "$ref": "#/definitions/Value" } } } } + ], + "required": [ + "identifier" ] } ] }, "Identifier": { + "description": "Permission identifier", "oneOf": [ { - "description": "clipboard-manager:default -> No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", + "description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", "type": "string", - "enum": [ - "clipboard-manager:default" - ] + "const": "clipboard-manager:default" }, { - "description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.", + "description": "Enables the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-clear" - ] + "const": "clipboard-manager:allow-clear" }, { - "description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.", + "description": "Enables the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-image" - ] + "const": "clipboard-manager:allow-read-image" }, { - "description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.", + "description": "Enables the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-read-text" - ] + "const": "clipboard-manager:allow-read-text" }, { - "description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.", + "description": "Enables the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-html" - ] + "const": "clipboard-manager:allow-write-html" }, { - "description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.", + "description": "Enables the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-image" - ] + "const": "clipboard-manager:allow-write-image" }, { - "description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.", + "description": "Enables the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:allow-write-text" - ] + "const": "clipboard-manager:allow-write-text" }, { - "description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.", + "description": "Denies the clear command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-clear" - ] + "const": "clipboard-manager:deny-clear" }, { - "description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.", + "description": "Denies the read_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-image" - ] + "const": "clipboard-manager:deny-read-image" }, { - "description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.", + "description": "Denies the read_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-read-text" - ] + "const": "clipboard-manager:deny-read-text" }, { - "description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.", + "description": "Denies the write_html command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-html" - ] + "const": "clipboard-manager:deny-write-html" }, { - "description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.", + "description": "Denies the write_image command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-image" - ] + "const": "clipboard-manager:deny-write-image" }, { - "description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.", + "description": "Denies the write_text command without any pre-configured scope.", "type": "string", - "enum": [ - "clipboard-manager:deny-write-text" - ] + "const": "clipboard-manager:deny-write-text" }, { - "description": "core:app:default -> Default permissions for the plugin.", + "description": "Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n", "type": "string", - "enum": [ - "core:app:default" - ] + "const": "core:default" }, { - "description": "core:app:allow-app-hide -> Enables the app_hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:app:allow-app-hide" - ] + "const": "core:app:default" }, { - "description": "core:app:allow-app-show -> Enables the app_show command without any pre-configured scope.", + "description": "Enables the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-app-show" - ] + "const": "core:app:allow-app-hide" }, { - "description": "core:app:allow-default-window-icon -> Enables the default_window_icon command without any pre-configured scope.", + "description": "Enables the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-default-window-icon" - ] + "const": "core:app:allow-app-show" }, { - "description": "core:app:allow-name -> Enables the name command without any pre-configured scope.", + "description": "Enables the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-name" - ] + "const": "core:app:allow-default-window-icon" }, { - "description": "core:app:allow-tauri-version -> Enables the tauri_version command without any pre-configured scope.", + "description": "Enables the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-tauri-version" - ] + "const": "core:app:allow-name" }, { - "description": "core:app:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Enables the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:allow-version" - ] + "const": "core:app:allow-set-app-theme" }, { - "description": "core:app:deny-app-hide -> Denies the app_hide command without any pre-configured scope.", + "description": "Enables the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-hide" - ] + "const": "core:app:allow-tauri-version" }, { - "description": "core:app:deny-app-show -> Denies the app_show command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-app-show" - ] + "const": "core:app:allow-version" }, { - "description": "core:app:deny-default-window-icon -> Denies the default_window_icon command without any pre-configured scope.", + "description": "Denies the app_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-default-window-icon" - ] + "const": "core:app:deny-app-hide" }, { - "description": "core:app:deny-name -> Denies the name command without any pre-configured scope.", + "description": "Denies the app_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-name" - ] + "const": "core:app:deny-app-show" }, { - "description": "core:app:deny-tauri-version -> Denies the tauri_version command without any pre-configured scope.", + "description": "Denies the default_window_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-tauri-version" - ] + "const": "core:app:deny-default-window-icon" }, { - "description": "core:app:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Denies the name command without any pre-configured scope.", "type": "string", - "enum": [ - "core:app:deny-version" - ] + "const": "core:app:deny-name" }, { - "description": "core:event:default -> Default permissions for the plugin.", + "description": "Denies the set_app_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:default" - ] + "const": "core:app:deny-set-app-theme" }, { - "description": "core:event:allow-emit -> Enables the emit command without any pre-configured scope.", + "description": "Denies the tauri_version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit" - ] + "const": "core:app:deny-tauri-version" }, { - "description": "core:event:allow-emit-to -> Enables the emit_to command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-emit-to" - ] + "const": "core:app:deny-version" }, { - "description": "core:event:allow-listen -> Enables the listen command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:event:allow-listen" - ] + "const": "core:event:default" }, { - "description": "core:event:allow-unlisten -> Enables the unlisten command without any pre-configured scope.", + "description": "Enables the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:allow-unlisten" - ] + "const": "core:event:allow-emit" }, { - "description": "core:event:deny-emit -> Denies the emit command without any pre-configured scope.", + "description": "Enables the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit" - ] + "const": "core:event:allow-emit-to" }, { - "description": "core:event:deny-emit-to -> Denies the emit_to command without any pre-configured scope.", + "description": "Enables the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-emit-to" - ] + "const": "core:event:allow-listen" }, { - "description": "core:event:deny-listen -> Denies the listen command without any pre-configured scope.", + "description": "Enables the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-listen" - ] + "const": "core:event:allow-unlisten" }, { - "description": "core:event:deny-unlisten -> Denies the unlisten command without any pre-configured scope.", + "description": "Denies the emit command without any pre-configured scope.", "type": "string", - "enum": [ - "core:event:deny-unlisten" - ] + "const": "core:event:deny-emit" }, { - "description": "core:image:default -> Default permissions for the plugin.", + "description": "Denies the emit_to command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:default" - ] + "const": "core:event:deny-emit-to" }, { - "description": "core:image:allow-from-bytes -> Enables the from_bytes command without any pre-configured scope.", + "description": "Denies the listen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-bytes" - ] + "const": "core:event:deny-listen" }, { - "description": "core:image:allow-from-path -> Enables the from_path command without any pre-configured scope.", + "description": "Denies the unlisten command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-from-path" - ] + "const": "core:event:deny-unlisten" }, { - "description": "core:image:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:image:allow-new" - ] + "const": "core:image:default" }, { - "description": "core:image:allow-rgba -> Enables the rgba command without any pre-configured scope.", + "description": "Enables the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-rgba" - ] + "const": "core:image:allow-from-bytes" }, { - "description": "core:image:allow-size -> Enables the size command without any pre-configured scope.", + "description": "Enables the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:allow-size" - ] + "const": "core:image:allow-from-path" }, { - "description": "core:image:deny-from-bytes -> Denies the from_bytes command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-bytes" - ] + "const": "core:image:allow-new" }, { - "description": "core:image:deny-from-path -> Denies the from_path command without any pre-configured scope.", + "description": "Enables the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-from-path" - ] + "const": "core:image:allow-rgba" }, { - "description": "core:image:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-new" - ] + "const": "core:image:allow-size" }, { - "description": "core:image:deny-rgba -> Denies the rgba command without any pre-configured scope.", + "description": "Denies the from_bytes command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-rgba" - ] + "const": "core:image:deny-from-bytes" }, { - "description": "core:image:deny-size -> Denies the size command without any pre-configured scope.", + "description": "Denies the from_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:image:deny-size" - ] + "const": "core:image:deny-from-path" }, { - "description": "core:menu:default -> Default permissions for the plugin.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:default" - ] + "const": "core:image:deny-new" }, { - "description": "core:menu:allow-append -> Enables the append command without any pre-configured scope.", + "description": "Denies the rgba command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-append" - ] + "const": "core:image:deny-rgba" }, { - "description": "core:menu:allow-create-default -> Enables the create_default command without any pre-configured scope.", + "description": "Denies the size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-create-default" - ] + "const": "core:image:deny-size" }, { - "description": "core:menu:allow-get -> Enables the get command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:menu:allow-get" - ] + "const": "core:menu:default" }, { - "description": "core:menu:allow-insert -> Enables the insert command without any pre-configured scope.", + "description": "Enables the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-insert" - ] + "const": "core:menu:allow-append" }, { - "description": "core:menu:allow-is-checked -> Enables the is_checked command without any pre-configured scope.", + "description": "Enables the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-checked" - ] + "const": "core:menu:allow-create-default" }, { - "description": "core:menu:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "description": "Enables the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-is-enabled" - ] + "const": "core:menu:allow-get" }, { - "description": "core:menu:allow-items -> Enables the items command without any pre-configured scope.", + "description": "Enables the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-items" - ] + "const": "core:menu:allow-insert" }, { - "description": "core:menu:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Enables the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-new" - ] + "const": "core:menu:allow-is-checked" }, { - "description": "core:menu:allow-popup -> Enables the popup command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-popup" - ] + "const": "core:menu:allow-is-enabled" }, { - "description": "core:menu:allow-prepend -> Enables the prepend command without any pre-configured scope.", + "description": "Enables the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-prepend" - ] + "const": "core:menu:allow-items" }, { - "description": "core:menu:allow-remove -> Enables the remove command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove" - ] + "const": "core:menu:allow-new" }, { - "description": "core:menu:allow-remove-at -> Enables the remove_at command without any pre-configured scope.", + "description": "Enables the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-remove-at" - ] + "const": "core:menu:allow-popup" }, { - "description": "core:menu:allow-set-accelerator -> Enables the set_accelerator command without any pre-configured scope.", + "description": "Enables the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-accelerator" - ] + "const": "core:menu:allow-prepend" }, { - "description": "core:menu:allow-set-as-app-menu -> Enables the set_as_app_menu command without any pre-configured scope.", + "description": "Enables the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-app-menu" - ] + "const": "core:menu:allow-remove" }, { - "description": "core:menu:allow-set-as-help-menu-for-nsapp -> Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:allow-remove-at" }, { - "description": "core:menu:allow-set-as-window-menu -> Enables the set_as_window_menu command without any pre-configured scope.", + "description": "Enables the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-window-menu" - ] + "const": "core:menu:allow-set-accelerator" }, { - "description": "core:menu:allow-set-as-windows-menu-for-nsapp -> Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Enables the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:allow-set-as-app-menu" }, { - "description": "core:menu:allow-set-checked -> Enables the set_checked command without any pre-configured scope.", + "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-checked" - ] + "const": "core:menu:allow-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:allow-set-enabled -> Enables the set_enabled command without any pre-configured scope.", + "description": "Enables the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-enabled" - ] + "const": "core:menu:allow-set-as-window-menu" }, { - "description": "core:menu:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-icon" - ] + "const": "core:menu:allow-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:allow-set-text -> Enables the set_text command without any pre-configured scope.", + "description": "Enables the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-set-text" - ] + "const": "core:menu:allow-set-checked" }, { - "description": "core:menu:allow-text -> Enables the text command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:allow-text" - ] + "const": "core:menu:allow-set-enabled" }, { - "description": "core:menu:deny-append -> Denies the append command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-append" - ] + "const": "core:menu:allow-set-icon" }, { - "description": "core:menu:deny-create-default -> Denies the create_default command without any pre-configured scope.", + "description": "Enables the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-create-default" - ] + "const": "core:menu:allow-set-text" }, { - "description": "core:menu:deny-get -> Denies the get command without any pre-configured scope.", + "description": "Enables the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-get" - ] + "const": "core:menu:allow-text" }, { - "description": "core:menu:deny-insert -> Denies the insert command without any pre-configured scope.", + "description": "Denies the append command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-insert" - ] + "const": "core:menu:deny-append" }, { - "description": "core:menu:deny-is-checked -> Denies the is_checked command without any pre-configured scope.", + "description": "Denies the create_default command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-checked" - ] + "const": "core:menu:deny-create-default" }, { - "description": "core:menu:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "description": "Denies the get command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-is-enabled" - ] + "const": "core:menu:deny-get" }, { - "description": "core:menu:deny-items -> Denies the items command without any pre-configured scope.", + "description": "Denies the insert command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-items" - ] + "const": "core:menu:deny-insert" }, { - "description": "core:menu:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Denies the is_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-new" - ] + "const": "core:menu:deny-is-checked" }, { - "description": "core:menu:deny-popup -> Denies the popup command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-popup" - ] + "const": "core:menu:deny-is-enabled" }, { - "description": "core:menu:deny-prepend -> Denies the prepend command without any pre-configured scope.", + "description": "Denies the items command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-prepend" - ] + "const": "core:menu:deny-items" }, { - "description": "core:menu:deny-remove -> Denies the remove command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove" - ] + "const": "core:menu:deny-new" }, { - "description": "core:menu:deny-remove-at -> Denies the remove_at command without any pre-configured scope.", + "description": "Denies the popup command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-remove-at" - ] + "const": "core:menu:deny-popup" }, { - "description": "core:menu:deny-set-accelerator -> Denies the set_accelerator command without any pre-configured scope.", + "description": "Denies the prepend command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-accelerator" - ] + "const": "core:menu:deny-prepend" }, { - "description": "core:menu:deny-set-as-app-menu -> Denies the set_as_app_menu command without any pre-configured scope.", + "description": "Denies the remove command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-app-menu" - ] + "const": "core:menu:deny-remove" }, { - "description": "core:menu:deny-set-as-help-menu-for-nsapp -> Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the remove_at command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-help-menu-for-nsapp" - ] + "const": "core:menu:deny-remove-at" }, { - "description": "core:menu:deny-set-as-window-menu -> Denies the set_as_window_menu command without any pre-configured scope.", + "description": "Denies the set_accelerator command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-window-menu" - ] + "const": "core:menu:deny-set-accelerator" }, { - "description": "core:menu:deny-set-as-windows-menu-for-nsapp -> Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "description": "Denies the set_as_app_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-as-windows-menu-for-nsapp" - ] + "const": "core:menu:deny-set-as-app-menu" }, { - "description": "core:menu:deny-set-checked -> Denies the set_checked command without any pre-configured scope.", + "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-checked" - ] + "const": "core:menu:deny-set-as-help-menu-for-nsapp" }, { - "description": "core:menu:deny-set-enabled -> Denies the set_enabled command without any pre-configured scope.", + "description": "Denies the set_as_window_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-enabled" - ] + "const": "core:menu:deny-set-as-window-menu" }, { - "description": "core:menu:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-icon" - ] + "const": "core:menu:deny-set-as-windows-menu-for-nsapp" }, { - "description": "core:menu:deny-set-text -> Denies the set_text command without any pre-configured scope.", + "description": "Denies the set_checked command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-set-text" - ] + "const": "core:menu:deny-set-checked" }, { - "description": "core:menu:deny-text -> Denies the text command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:menu:deny-text" - ] + "const": "core:menu:deny-set-enabled" }, { - "description": "core:path:default -> Default permissions for the plugin.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:default" - ] + "const": "core:menu:deny-set-icon" }, { - "description": "core:path:allow-basename -> Enables the basename command without any pre-configured scope.", + "description": "Denies the set_text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-basename" - ] + "const": "core:menu:deny-set-text" }, { - "description": "core:path:allow-dirname -> Enables the dirname command without any pre-configured scope.", + "description": "Denies the text command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-dirname" - ] + "const": "core:menu:deny-text" }, { - "description": "core:path:allow-extname -> Enables the extname command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:path:allow-extname" - ] + "const": "core:path:default" }, { - "description": "core:path:allow-is-absolute -> Enables the is_absolute command without any pre-configured scope.", + "description": "Enables the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-is-absolute" - ] + "const": "core:path:allow-basename" }, { - "description": "core:path:allow-join -> Enables the join command without any pre-configured scope.", + "description": "Enables the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-join" - ] + "const": "core:path:allow-dirname" }, { - "description": "core:path:allow-normalize -> Enables the normalize command without any pre-configured scope.", + "description": "Enables the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-normalize" - ] + "const": "core:path:allow-extname" }, { - "description": "core:path:allow-resolve -> Enables the resolve command without any pre-configured scope.", + "description": "Enables the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve" - ] + "const": "core:path:allow-is-absolute" }, { - "description": "core:path:allow-resolve-directory -> Enables the resolve_directory command without any pre-configured scope.", + "description": "Enables the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:allow-resolve-directory" - ] + "const": "core:path:allow-join" }, { - "description": "core:path:deny-basename -> Denies the basename command without any pre-configured scope.", + "description": "Enables the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-basename" - ] + "const": "core:path:allow-normalize" }, { - "description": "core:path:deny-dirname -> Denies the dirname command without any pre-configured scope.", + "description": "Enables the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-dirname" - ] + "const": "core:path:allow-resolve" }, { - "description": "core:path:deny-extname -> Denies the extname command without any pre-configured scope.", + "description": "Enables the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-extname" - ] + "const": "core:path:allow-resolve-directory" }, { - "description": "core:path:deny-is-absolute -> Denies the is_absolute command without any pre-configured scope.", + "description": "Denies the basename command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-is-absolute" - ] + "const": "core:path:deny-basename" }, { - "description": "core:path:deny-join -> Denies the join command without any pre-configured scope.", + "description": "Denies the dirname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-join" - ] + "const": "core:path:deny-dirname" }, { - "description": "core:path:deny-normalize -> Denies the normalize command without any pre-configured scope.", + "description": "Denies the extname command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-normalize" - ] + "const": "core:path:deny-extname" }, { - "description": "core:path:deny-resolve -> Denies the resolve command without any pre-configured scope.", + "description": "Denies the is_absolute command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve" - ] + "const": "core:path:deny-is-absolute" }, { - "description": "core:path:deny-resolve-directory -> Denies the resolve_directory command without any pre-configured scope.", + "description": "Denies the join command without any pre-configured scope.", "type": "string", - "enum": [ - "core:path:deny-resolve-directory" - ] + "const": "core:path:deny-join" }, { - "description": "core:resources:default -> Default permissions for the plugin.", + "description": "Denies the normalize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:default" - ] + "const": "core:path:deny-normalize" }, { - "description": "core:resources:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the resolve command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:allow-close" - ] + "const": "core:path:deny-resolve" }, { - "description": "core:resources:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Denies the resolve_directory command without any pre-configured scope.", "type": "string", - "enum": [ - "core:resources:deny-close" - ] + "const": "core:path:deny-resolve-directory" }, { - "description": "core:tray:default -> Default permissions for the plugin.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:default" - ] + "const": "core:resources:default" }, { - "description": "core:tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-get-by-id" - ] + "const": "core:resources:allow-close" }, { - "description": "core:tray:allow-new -> Enables the new command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-new" - ] + "const": "core:resources:deny-close" }, { - "description": "core:tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:tray:allow-remove-by-id" - ] + "const": "core:tray:default" }, { - "description": "core:tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon" - ] + "const": "core:tray:allow-get-by-id" }, { - "description": "core:tray:allow-set-icon-as-template -> Enables the set_icon_as_template command without any pre-configured scope.", + "description": "Enables the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-icon-as-template" - ] + "const": "core:tray:allow-new" }, { - "description": "core:tray:allow-set-menu -> Enables the set_menu command without any pre-configured scope.", + "description": "Enables the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-menu" - ] + "const": "core:tray:allow-remove-by-id" }, { - "description": "core:tray:allow-set-show-menu-on-left-click -> Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-show-menu-on-left-click" - ] + "const": "core:tray:allow-set-icon" }, { - "description": "core:tray:allow-set-temp-dir-path -> Enables the set_temp_dir_path command without any pre-configured scope.", + "description": "Enables the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-temp-dir-path" - ] + "const": "core:tray:allow-set-icon-as-template" }, { - "description": "core:tray:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-title" - ] + "const": "core:tray:allow-set-menu" }, { - "description": "core:tray:allow-set-tooltip -> Enables the set_tooltip command without any pre-configured scope.", + "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-tooltip" - ] + "const": "core:tray:allow-set-show-menu-on-left-click" }, { - "description": "core:tray:allow-set-visible -> Enables the set_visible command without any pre-configured scope.", + "description": "Enables the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:allow-set-visible" - ] + "const": "core:tray:allow-set-temp-dir-path" }, { - "description": "core:tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-get-by-id" - ] + "const": "core:tray:allow-set-title" }, { - "description": "core:tray:deny-new -> Denies the new command without any pre-configured scope.", + "description": "Enables the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-new" - ] + "const": "core:tray:allow-set-tooltip" }, { - "description": "core:tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.", + "description": "Enables the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-remove-by-id" - ] + "const": "core:tray:allow-set-visible" }, { - "description": "core:tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the get_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon" - ] + "const": "core:tray:deny-get-by-id" }, { - "description": "core:tray:deny-set-icon-as-template -> Denies the set_icon_as_template command without any pre-configured scope.", + "description": "Denies the new command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-icon-as-template" - ] + "const": "core:tray:deny-new" }, { - "description": "core:tray:deny-set-menu -> Denies the set_menu command without any pre-configured scope.", + "description": "Denies the remove_by_id command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-menu" - ] + "const": "core:tray:deny-remove-by-id" }, { - "description": "core:tray:deny-set-show-menu-on-left-click -> Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-show-menu-on-left-click" - ] + "const": "core:tray:deny-set-icon" }, { - "description": "core:tray:deny-set-temp-dir-path -> Denies the set_temp_dir_path command without any pre-configured scope.", + "description": "Denies the set_icon_as_template command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-temp-dir-path" - ] + "const": "core:tray:deny-set-icon-as-template" }, { - "description": "core:tray:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_menu command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-title" - ] + "const": "core:tray:deny-set-menu" }, { - "description": "core:tray:deny-set-tooltip -> Denies the set_tooltip command without any pre-configured scope.", + "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-tooltip" - ] + "const": "core:tray:deny-set-show-menu-on-left-click" }, { - "description": "core:tray:deny-set-visible -> Denies the set_visible command without any pre-configured scope.", + "description": "Denies the set_temp_dir_path command without any pre-configured scope.", "type": "string", - "enum": [ - "core:tray:deny-set-visible" - ] + "const": "core:tray:deny-set-temp-dir-path" }, { - "description": "core:webview:default -> Default permissions for the plugin.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:default" - ] + "const": "core:tray:deny-set-title" }, { - "description": "core:webview:allow-create-webview -> Enables the create_webview command without any pre-configured scope.", + "description": "Denies the set_tooltip command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview" - ] + "const": "core:tray:deny-set-tooltip" }, { - "description": "core:webview:allow-create-webview-window -> Enables the create_webview_window command without any pre-configured scope.", + "description": "Denies the set_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-create-webview-window" - ] + "const": "core:tray:deny-set-visible" }, { - "description": "core:webview:allow-get-all-webviews -> Enables the get_all_webviews command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:webview:allow-get-all-webviews" - ] + "const": "core:webview:default" }, { - "description": "core:webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-internal-toggle-devtools" - ] + "const": "core:webview:allow-clear-all-browsing-data" }, { - "description": "core:webview:allow-print -> Enables the print command without any pre-configured scope.", + "description": "Enables the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-print" - ] + "const": "core:webview:allow-create-webview" }, { - "description": "core:webview:allow-reparent -> Enables the reparent command without any pre-configured scope.", + "description": "Enables the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-reparent" - ] + "const": "core:webview:allow-create-webview-window" }, { - "description": "core:webview:allow-set-webview-focus -> Enables the set_webview_focus command without any pre-configured scope.", + "description": "Enables the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-focus" - ] + "const": "core:webview:allow-get-all-webviews" }, { - "description": "core:webview:allow-set-webview-position -> Enables the set_webview_position command without any pre-configured scope.", + "description": "Enables the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-position" - ] + "const": "core:webview:allow-internal-toggle-devtools" }, { - "description": "core:webview:allow-set-webview-size -> Enables the set_webview_size command without any pre-configured scope.", + "description": "Enables the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-size" - ] + "const": "core:webview:allow-print" }, { - "description": "core:webview:allow-set-webview-zoom -> Enables the set_webview_zoom command without any pre-configured scope.", + "description": "Enables the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-set-webview-zoom" - ] + "const": "core:webview:allow-reparent" }, { - "description": "core:webview:allow-webview-close -> Enables the webview_close command without any pre-configured scope.", + "description": "Enables the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-close" - ] + "const": "core:webview:allow-set-webview-focus" }, { - "description": "core:webview:allow-webview-position -> Enables the webview_position command without any pre-configured scope.", + "description": "Enables the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-position" - ] + "const": "core:webview:allow-set-webview-position" }, { - "description": "core:webview:allow-webview-size -> Enables the webview_size command without any pre-configured scope.", + "description": "Enables the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:allow-webview-size" - ] + "const": "core:webview:allow-set-webview-size" }, { - "description": "core:webview:deny-create-webview -> Denies the create_webview command without any pre-configured scope.", + "description": "Enables the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview" - ] + "const": "core:webview:allow-set-webview-zoom" }, { - "description": "core:webview:deny-create-webview-window -> Denies the create_webview_window command without any pre-configured scope.", + "description": "Enables the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-create-webview-window" - ] + "const": "core:webview:allow-webview-close" }, { - "description": "core:webview:deny-get-all-webviews -> Denies the get_all_webviews command without any pre-configured scope.", + "description": "Enables the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-get-all-webviews" - ] + "const": "core:webview:allow-webview-hide" }, { - "description": "core:webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.", + "description": "Enables the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-internal-toggle-devtools" - ] + "const": "core:webview:allow-webview-position" }, { - "description": "core:webview:deny-print -> Denies the print command without any pre-configured scope.", + "description": "Enables the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-print" - ] + "const": "core:webview:allow-webview-show" }, { - "description": "core:webview:deny-reparent -> Denies the reparent command without any pre-configured scope.", + "description": "Enables the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-reparent" - ] + "const": "core:webview:allow-webview-size" }, { - "description": "core:webview:deny-set-webview-focus -> Denies the set_webview_focus command without any pre-configured scope.", + "description": "Denies the clear_all_browsing_data command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-focus" - ] + "const": "core:webview:deny-clear-all-browsing-data" }, { - "description": "core:webview:deny-set-webview-position -> Denies the set_webview_position command without any pre-configured scope.", + "description": "Denies the create_webview command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-position" - ] + "const": "core:webview:deny-create-webview" }, { - "description": "core:webview:deny-set-webview-size -> Denies the set_webview_size command without any pre-configured scope.", + "description": "Denies the create_webview_window command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-size" - ] + "const": "core:webview:deny-create-webview-window" }, { - "description": "core:webview:deny-set-webview-zoom -> Denies the set_webview_zoom command without any pre-configured scope.", + "description": "Denies the get_all_webviews command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-set-webview-zoom" - ] + "const": "core:webview:deny-get-all-webviews" }, { - "description": "core:webview:deny-webview-close -> Denies the webview_close command without any pre-configured scope.", + "description": "Denies the internal_toggle_devtools command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-close" - ] + "const": "core:webview:deny-internal-toggle-devtools" }, { - "description": "core:webview:deny-webview-position -> Denies the webview_position command without any pre-configured scope.", + "description": "Denies the print command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-position" - ] + "const": "core:webview:deny-print" }, { - "description": "core:webview:deny-webview-size -> Denies the webview_size command without any pre-configured scope.", + "description": "Denies the reparent command without any pre-configured scope.", "type": "string", - "enum": [ - "core:webview:deny-webview-size" - ] + "const": "core:webview:deny-reparent" }, { - "description": "core:window:default -> Default permissions for the plugin.", + "description": "Denies the set_webview_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:default" - ] + "const": "core:webview:deny-set-webview-focus" }, { - "description": "core:window:allow-available-monitors -> Enables the available_monitors command without any pre-configured scope.", + "description": "Denies the set_webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-available-monitors" - ] + "const": "core:webview:deny-set-webview-position" }, { - "description": "core:window:allow-center -> Enables the center command without any pre-configured scope.", + "description": "Denies the set_webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-center" - ] + "const": "core:webview:deny-set-webview-size" }, { - "description": "core:window:allow-close -> Enables the close command without any pre-configured scope.", + "description": "Denies the set_webview_zoom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-close" - ] + "const": "core:webview:deny-set-webview-zoom" }, { - "description": "core:window:allow-create -> Enables the create command without any pre-configured scope.", + "description": "Denies the webview_close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-create" - ] + "const": "core:webview:deny-webview-close" }, { - "description": "core:window:allow-current-monitor -> Enables the current_monitor command without any pre-configured scope.", + "description": "Denies the webview_hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-current-monitor" - ] + "const": "core:webview:deny-webview-hide" }, { - "description": "core:window:allow-cursor-position -> Enables the cursor_position command without any pre-configured scope.", + "description": "Denies the webview_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-cursor-position" - ] + "const": "core:webview:deny-webview-position" }, { - "description": "core:window:allow-destroy -> Enables the destroy command without any pre-configured scope.", + "description": "Denies the webview_show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-destroy" - ] + "const": "core:webview:deny-webview-show" }, { - "description": "core:window:allow-get-all-windows -> Enables the get_all_windows command without any pre-configured scope.", + "description": "Denies the webview_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-get-all-windows" - ] + "const": "core:webview:deny-webview-size" }, { - "description": "core:window:allow-hide -> Enables the hide command without any pre-configured scope.", + "description": "Default permissions for the plugin.", "type": "string", - "enum": [ - "core:window:allow-hide" - ] + "const": "core:window:default" }, { - "description": "core:window:allow-inner-position -> Enables the inner_position command without any pre-configured scope.", + "description": "Enables the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-position" - ] + "const": "core:window:allow-available-monitors" }, { - "description": "core:window:allow-inner-size -> Enables the inner_size command without any pre-configured scope.", + "description": "Enables the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-inner-size" - ] + "const": "core:window:allow-center" }, { - "description": "core:window:allow-internal-toggle-maximize -> Enables the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-internal-toggle-maximize" - ] + "const": "core:window:allow-close" }, { - "description": "core:window:allow-is-closable -> Enables the is_closable command without any pre-configured scope.", + "description": "Enables the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-closable" - ] + "const": "core:window:allow-create" }, { - "description": "core:window:allow-is-decorated -> Enables the is_decorated command without any pre-configured scope.", + "description": "Enables the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-decorated" - ] + "const": "core:window:allow-current-monitor" }, { - "description": "core:window:allow-is-focused -> Enables the is_focused command without any pre-configured scope.", + "description": "Enables the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-focused" - ] + "const": "core:window:allow-cursor-position" }, { - "description": "core:window:allow-is-fullscreen -> Enables the is_fullscreen command without any pre-configured scope.", + "description": "Enables the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-fullscreen" - ] + "const": "core:window:allow-destroy" }, { - "description": "core:window:allow-is-maximizable -> Enables the is_maximizable command without any pre-configured scope.", + "description": "Enables the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximizable" - ] + "const": "core:window:allow-get-all-windows" }, { - "description": "core:window:allow-is-maximized -> Enables the is_maximized command without any pre-configured scope.", + "description": "Enables the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-maximized" - ] + "const": "core:window:allow-hide" }, { - "description": "core:window:allow-is-minimizable -> Enables the is_minimizable command without any pre-configured scope.", + "description": "Enables the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimizable" - ] + "const": "core:window:allow-inner-position" }, { - "description": "core:window:allow-is-minimized -> Enables the is_minimized command without any pre-configured scope.", + "description": "Enables the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-minimized" - ] + "const": "core:window:allow-inner-size" }, { - "description": "core:window:allow-is-resizable -> Enables the is_resizable command without any pre-configured scope.", + "description": "Enables the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-resizable" - ] + "const": "core:window:allow-internal-toggle-maximize" }, { - "description": "core:window:allow-is-visible -> Enables the is_visible command without any pre-configured scope.", + "description": "Enables the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-is-visible" - ] + "const": "core:window:allow-is-closable" }, { - "description": "core:window:allow-maximize -> Enables the maximize command without any pre-configured scope.", + "description": "Enables the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-maximize" - ] + "const": "core:window:allow-is-decorated" }, { - "description": "core:window:allow-minimize -> Enables the minimize command without any pre-configured scope.", + "description": "Enables the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-minimize" - ] + "const": "core:window:allow-is-enabled" }, { - "description": "core:window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.", + "description": "Enables the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-monitor-from-point" - ] + "const": "core:window:allow-is-focused" }, { - "description": "core:window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.", + "description": "Enables the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-position" - ] + "const": "core:window:allow-is-fullscreen" }, { - "description": "core:window:allow-outer-size -> Enables the outer_size command without any pre-configured scope.", + "description": "Enables the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-outer-size" - ] + "const": "core:window:allow-is-maximizable" }, { - "description": "core:window:allow-primary-monitor -> Enables the primary_monitor command without any pre-configured scope.", + "description": "Enables the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-primary-monitor" - ] + "const": "core:window:allow-is-maximized" }, { - "description": "core:window:allow-request-user-attention -> Enables the request_user_attention command without any pre-configured scope.", + "description": "Enables the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-request-user-attention" - ] + "const": "core:window:allow-is-minimizable" }, { - "description": "core:window:allow-scale-factor -> Enables the scale_factor command without any pre-configured scope.", + "description": "Enables the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-scale-factor" - ] + "const": "core:window:allow-is-minimized" }, { - "description": "core:window:allow-set-always-on-bottom -> Enables the set_always_on_bottom command without any pre-configured scope.", + "description": "Enables the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-bottom" - ] + "const": "core:window:allow-is-resizable" }, { - "description": "core:window:allow-set-always-on-top -> Enables the set_always_on_top command without any pre-configured scope.", + "description": "Enables the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-always-on-top" - ] + "const": "core:window:allow-is-visible" }, { - "description": "core:window:allow-set-closable -> Enables the set_closable command without any pre-configured scope.", + "description": "Enables the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-closable" - ] + "const": "core:window:allow-maximize" }, { - "description": "core:window:allow-set-content-protected -> Enables the set_content_protected command without any pre-configured scope.", + "description": "Enables the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-content-protected" - ] + "const": "core:window:allow-minimize" }, { - "description": "core:window:allow-set-cursor-grab -> Enables the set_cursor_grab command without any pre-configured scope.", + "description": "Enables the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-grab" - ] + "const": "core:window:allow-monitor-from-point" }, { - "description": "core:window:allow-set-cursor-icon -> Enables the set_cursor_icon command without any pre-configured scope.", + "description": "Enables the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-icon" - ] + "const": "core:window:allow-outer-position" }, { - "description": "core:window:allow-set-cursor-position -> Enables the set_cursor_position command without any pre-configured scope.", + "description": "Enables the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-position" - ] + "const": "core:window:allow-outer-size" }, { - "description": "core:window:allow-set-cursor-visible -> Enables the set_cursor_visible command without any pre-configured scope.", + "description": "Enables the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-cursor-visible" - ] + "const": "core:window:allow-primary-monitor" }, { - "description": "core:window:allow-set-decorations -> Enables the set_decorations command without any pre-configured scope.", + "description": "Enables the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-decorations" - ] + "const": "core:window:allow-request-user-attention" }, { - "description": "core:window:allow-set-effects -> Enables the set_effects command without any pre-configured scope.", + "description": "Enables the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-effects" - ] + "const": "core:window:allow-scale-factor" }, { - "description": "core:window:allow-set-focus -> Enables the set_focus command without any pre-configured scope.", + "description": "Enables the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-focus" - ] + "const": "core:window:allow-set-always-on-bottom" }, { - "description": "core:window:allow-set-fullscreen -> Enables the set_fullscreen command without any pre-configured scope.", + "description": "Enables the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-fullscreen" - ] + "const": "core:window:allow-set-always-on-top" }, { - "description": "core:window:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "description": "Enables the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-icon" - ] + "const": "core:window:allow-set-closable" }, { - "description": "core:window:allow-set-ignore-cursor-events -> Enables the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Enables the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-ignore-cursor-events" - ] + "const": "core:window:allow-set-content-protected" }, { - "description": "core:window:allow-set-max-size -> Enables the set_max_size command without any pre-configured scope.", + "description": "Enables the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-max-size" - ] + "const": "core:window:allow-set-cursor-grab" }, { - "description": "core:window:allow-set-maximizable -> Enables the set_maximizable command without any pre-configured scope.", + "description": "Enables the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-maximizable" - ] + "const": "core:window:allow-set-cursor-icon" }, { - "description": "core:window:allow-set-min-size -> Enables the set_min_size command without any pre-configured scope.", + "description": "Enables the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-min-size" - ] + "const": "core:window:allow-set-cursor-position" }, { - "description": "core:window:allow-set-minimizable -> Enables the set_minimizable command without any pre-configured scope.", + "description": "Enables the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-minimizable" - ] + "const": "core:window:allow-set-cursor-visible" }, { - "description": "core:window:allow-set-position -> Enables the set_position command without any pre-configured scope.", + "description": "Enables the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-position" - ] + "const": "core:window:allow-set-decorations" }, { - "description": "core:window:allow-set-progress-bar -> Enables the set_progress_bar command without any pre-configured scope.", + "description": "Enables the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-progress-bar" - ] + "const": "core:window:allow-set-effects" }, { - "description": "core:window:allow-set-resizable -> Enables the set_resizable command without any pre-configured scope.", + "description": "Enables the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-resizable" - ] + "const": "core:window:allow-set-enabled" }, { - "description": "core:window:allow-set-shadow -> Enables the set_shadow command without any pre-configured scope.", + "description": "Enables the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-shadow" - ] + "const": "core:window:allow-set-focus" }, { - "description": "core:window:allow-set-size -> Enables the set_size command without any pre-configured scope.", + "description": "Enables the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size" - ] + "const": "core:window:allow-set-fullscreen" }, { - "description": "core:window:allow-set-size-constraints -> Enables the set_size_constraints command without any pre-configured scope.", + "description": "Enables the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-size-constraints" - ] + "const": "core:window:allow-set-icon" }, { - "description": "core:window:allow-set-skip-taskbar -> Enables the set_skip_taskbar command without any pre-configured scope.", + "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-skip-taskbar" - ] + "const": "core:window:allow-set-ignore-cursor-events" }, { - "description": "core:window:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "description": "Enables the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title" - ] + "const": "core:window:allow-set-max-size" }, { - "description": "core:window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.", + "description": "Enables the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-title-bar-style" - ] + "const": "core:window:allow-set-maximizable" }, { - "description": "core:window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Enables the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-set-visible-on-all-workspaces" - ] + "const": "core:window:allow-set-min-size" }, { - "description": "core:window:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-show" - ] + "const": "core:window:allow-set-minimizable" }, { - "description": "core:window:allow-start-dragging -> Enables the start_dragging command without any pre-configured scope.", + "description": "Enables the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-dragging" - ] + "const": "core:window:allow-set-position" }, { - "description": "core:window:allow-start-resize-dragging -> Enables the start_resize_dragging command without any pre-configured scope.", + "description": "Enables the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-start-resize-dragging" - ] + "const": "core:window:allow-set-progress-bar" }, { - "description": "core:window:allow-theme -> Enables the theme command without any pre-configured scope.", + "description": "Enables the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-theme" - ] + "const": "core:window:allow-set-resizable" }, { - "description": "core:window:allow-title -> Enables the title command without any pre-configured scope.", + "description": "Enables the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-title" - ] + "const": "core:window:allow-set-shadow" }, { - "description": "core:window:allow-toggle-maximize -> Enables the toggle_maximize command without any pre-configured scope.", + "description": "Enables the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-toggle-maximize" - ] + "const": "core:window:allow-set-size" }, { - "description": "core:window:allow-unmaximize -> Enables the unmaximize command without any pre-configured scope.", + "description": "Enables the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unmaximize" - ] + "const": "core:window:allow-set-size-constraints" }, { - "description": "core:window:allow-unminimize -> Enables the unminimize command without any pre-configured scope.", + "description": "Enables the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:allow-unminimize" - ] + "const": "core:window:allow-set-skip-taskbar" }, { - "description": "core:window:deny-available-monitors -> Denies the available_monitors command without any pre-configured scope.", + "description": "Enables the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-available-monitors" - ] + "const": "core:window:allow-set-theme" }, { - "description": "core:window:deny-center -> Denies the center command without any pre-configured scope.", + "description": "Enables the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-center" - ] + "const": "core:window:allow-set-title" }, { - "description": "core:window:deny-close -> Denies the close command without any pre-configured scope.", + "description": "Enables the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-close" - ] + "const": "core:window:allow-set-title-bar-style" }, { - "description": "core:window:deny-create -> Denies the create command without any pre-configured scope.", + "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-create" - ] + "const": "core:window:allow-set-visible-on-all-workspaces" }, { - "description": "core:window:deny-current-monitor -> Denies the current_monitor command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-current-monitor" - ] + "const": "core:window:allow-show" }, { - "description": "core:window:deny-cursor-position -> Denies the cursor_position command without any pre-configured scope.", + "description": "Enables the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-cursor-position" - ] + "const": "core:window:allow-start-dragging" }, { - "description": "core:window:deny-destroy -> Denies the destroy command without any pre-configured scope.", + "description": "Enables the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-destroy" - ] + "const": "core:window:allow-start-resize-dragging" }, { - "description": "core:window:deny-get-all-windows -> Denies the get_all_windows command without any pre-configured scope.", + "description": "Enables the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-get-all-windows" - ] + "const": "core:window:allow-theme" }, { - "description": "core:window:deny-hide -> Denies the hide command without any pre-configured scope.", + "description": "Enables the title command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-hide" - ] + "const": "core:window:allow-title" }, { - "description": "core:window:deny-inner-position -> Denies the inner_position command without any pre-configured scope.", + "description": "Enables the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-position" - ] + "const": "core:window:allow-toggle-maximize" }, { - "description": "core:window:deny-inner-size -> Denies the inner_size command without any pre-configured scope.", + "description": "Enables the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-inner-size" - ] + "const": "core:window:allow-unmaximize" }, { - "description": "core:window:deny-internal-toggle-maximize -> Denies the internal_toggle_maximize command without any pre-configured scope.", + "description": "Enables the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-internal-toggle-maximize" - ] + "const": "core:window:allow-unminimize" }, { - "description": "core:window:deny-is-closable -> Denies the is_closable command without any pre-configured scope.", + "description": "Denies the available_monitors command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-closable" - ] + "const": "core:window:deny-available-monitors" }, { - "description": "core:window:deny-is-decorated -> Denies the is_decorated command without any pre-configured scope.", + "description": "Denies the center command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-decorated" - ] + "const": "core:window:deny-center" }, { - "description": "core:window:deny-is-focused -> Denies the is_focused command without any pre-configured scope.", + "description": "Denies the close command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-focused" - ] + "const": "core:window:deny-close" }, { - "description": "core:window:deny-is-fullscreen -> Denies the is_fullscreen command without any pre-configured scope.", + "description": "Denies the create command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-fullscreen" - ] + "const": "core:window:deny-create" }, { - "description": "core:window:deny-is-maximizable -> Denies the is_maximizable command without any pre-configured scope.", + "description": "Denies the current_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximizable" - ] + "const": "core:window:deny-current-monitor" }, { - "description": "core:window:deny-is-maximized -> Denies the is_maximized command without any pre-configured scope.", + "description": "Denies the cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-maximized" - ] + "const": "core:window:deny-cursor-position" }, { - "description": "core:window:deny-is-minimizable -> Denies the is_minimizable command without any pre-configured scope.", + "description": "Denies the destroy command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimizable" - ] + "const": "core:window:deny-destroy" }, { - "description": "core:window:deny-is-minimized -> Denies the is_minimized command without any pre-configured scope.", + "description": "Denies the get_all_windows command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-minimized" - ] + "const": "core:window:deny-get-all-windows" }, { - "description": "core:window:deny-is-resizable -> Denies the is_resizable command without any pre-configured scope.", + "description": "Denies the hide command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-resizable" - ] + "const": "core:window:deny-hide" }, { - "description": "core:window:deny-is-visible -> Denies the is_visible command without any pre-configured scope.", + "description": "Denies the inner_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-is-visible" - ] + "const": "core:window:deny-inner-position" }, { - "description": "core:window:deny-maximize -> Denies the maximize command without any pre-configured scope.", + "description": "Denies the inner_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-maximize" - ] + "const": "core:window:deny-inner-size" }, { - "description": "core:window:deny-minimize -> Denies the minimize command without any pre-configured scope.", + "description": "Denies the internal_toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-minimize" - ] + "const": "core:window:deny-internal-toggle-maximize" }, { - "description": "core:window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.", + "description": "Denies the is_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-monitor-from-point" - ] + "const": "core:window:deny-is-closable" }, { - "description": "core:window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.", + "description": "Denies the is_decorated command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-position" - ] + "const": "core:window:deny-is-decorated" }, { - "description": "core:window:deny-outer-size -> Denies the outer_size command without any pre-configured scope.", + "description": "Denies the is_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-outer-size" - ] + "const": "core:window:deny-is-enabled" }, { - "description": "core:window:deny-primary-monitor -> Denies the primary_monitor command without any pre-configured scope.", + "description": "Denies the is_focused command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-primary-monitor" - ] + "const": "core:window:deny-is-focused" }, { - "description": "core:window:deny-request-user-attention -> Denies the request_user_attention command without any pre-configured scope.", + "description": "Denies the is_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-request-user-attention" - ] + "const": "core:window:deny-is-fullscreen" }, { - "description": "core:window:deny-scale-factor -> Denies the scale_factor command without any pre-configured scope.", + "description": "Denies the is_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-scale-factor" - ] + "const": "core:window:deny-is-maximizable" }, { - "description": "core:window:deny-set-always-on-bottom -> Denies the set_always_on_bottom command without any pre-configured scope.", + "description": "Denies the is_maximized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-bottom" - ] + "const": "core:window:deny-is-maximized" }, { - "description": "core:window:deny-set-always-on-top -> Denies the set_always_on_top command without any pre-configured scope.", + "description": "Denies the is_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-always-on-top" - ] + "const": "core:window:deny-is-minimizable" }, { - "description": "core:window:deny-set-closable -> Denies the set_closable command without any pre-configured scope.", + "description": "Denies the is_minimized command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-closable" - ] + "const": "core:window:deny-is-minimized" }, { - "description": "core:window:deny-set-content-protected -> Denies the set_content_protected command without any pre-configured scope.", + "description": "Denies the is_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-content-protected" - ] + "const": "core:window:deny-is-resizable" }, { - "description": "core:window:deny-set-cursor-grab -> Denies the set_cursor_grab command without any pre-configured scope.", + "description": "Denies the is_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-grab" - ] + "const": "core:window:deny-is-visible" }, { - "description": "core:window:deny-set-cursor-icon -> Denies the set_cursor_icon command without any pre-configured scope.", + "description": "Denies the maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-icon" - ] + "const": "core:window:deny-maximize" }, { - "description": "core:window:deny-set-cursor-position -> Denies the set_cursor_position command without any pre-configured scope.", + "description": "Denies the minimize command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-position" - ] + "const": "core:window:deny-minimize" }, { - "description": "core:window:deny-set-cursor-visible -> Denies the set_cursor_visible command without any pre-configured scope.", + "description": "Denies the monitor_from_point command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-cursor-visible" - ] + "const": "core:window:deny-monitor-from-point" }, { - "description": "core:window:deny-set-decorations -> Denies the set_decorations command without any pre-configured scope.", + "description": "Denies the outer_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-decorations" - ] + "const": "core:window:deny-outer-position" }, { - "description": "core:window:deny-set-effects -> Denies the set_effects command without any pre-configured scope.", + "description": "Denies the outer_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-effects" - ] + "const": "core:window:deny-outer-size" }, { - "description": "core:window:deny-set-focus -> Denies the set_focus command without any pre-configured scope.", + "description": "Denies the primary_monitor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-focus" - ] + "const": "core:window:deny-primary-monitor" }, { - "description": "core:window:deny-set-fullscreen -> Denies the set_fullscreen command without any pre-configured scope.", + "description": "Denies the request_user_attention command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-fullscreen" - ] + "const": "core:window:deny-request-user-attention" }, { - "description": "core:window:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "description": "Denies the scale_factor command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-icon" - ] + "const": "core:window:deny-scale-factor" }, { - "description": "core:window:deny-set-ignore-cursor-events -> Denies the set_ignore_cursor_events command without any pre-configured scope.", + "description": "Denies the set_always_on_bottom command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-ignore-cursor-events" - ] + "const": "core:window:deny-set-always-on-bottom" }, { - "description": "core:window:deny-set-max-size -> Denies the set_max_size command without any pre-configured scope.", + "description": "Denies the set_always_on_top command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-max-size" - ] + "const": "core:window:deny-set-always-on-top" }, { - "description": "core:window:deny-set-maximizable -> Denies the set_maximizable command without any pre-configured scope.", + "description": "Denies the set_closable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-maximizable" - ] + "const": "core:window:deny-set-closable" }, { - "description": "core:window:deny-set-min-size -> Denies the set_min_size command without any pre-configured scope.", + "description": "Denies the set_content_protected command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-min-size" - ] + "const": "core:window:deny-set-content-protected" }, { - "description": "core:window:deny-set-minimizable -> Denies the set_minimizable command without any pre-configured scope.", + "description": "Denies the set_cursor_grab command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-minimizable" - ] + "const": "core:window:deny-set-cursor-grab" }, { - "description": "core:window:deny-set-position -> Denies the set_position command without any pre-configured scope.", + "description": "Denies the set_cursor_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-position" - ] + "const": "core:window:deny-set-cursor-icon" }, { - "description": "core:window:deny-set-progress-bar -> Denies the set_progress_bar command without any pre-configured scope.", + "description": "Denies the set_cursor_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-progress-bar" - ] + "const": "core:window:deny-set-cursor-position" }, { - "description": "core:window:deny-set-resizable -> Denies the set_resizable command without any pre-configured scope.", + "description": "Denies the set_cursor_visible command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-resizable" - ] + "const": "core:window:deny-set-cursor-visible" }, { - "description": "core:window:deny-set-shadow -> Denies the set_shadow command without any pre-configured scope.", + "description": "Denies the set_decorations command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-shadow" - ] + "const": "core:window:deny-set-decorations" }, { - "description": "core:window:deny-set-size -> Denies the set_size command without any pre-configured scope.", + "description": "Denies the set_effects command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size" - ] + "const": "core:window:deny-set-effects" }, { - "description": "core:window:deny-set-size-constraints -> Denies the set_size_constraints command without any pre-configured scope.", + "description": "Denies the set_enabled command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-size-constraints" - ] + "const": "core:window:deny-set-enabled" }, { - "description": "core:window:deny-set-skip-taskbar -> Denies the set_skip_taskbar command without any pre-configured scope.", + "description": "Denies the set_focus command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-skip-taskbar" - ] + "const": "core:window:deny-set-focus" }, { - "description": "core:window:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "description": "Denies the set_fullscreen command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title" - ] + "const": "core:window:deny-set-fullscreen" }, { - "description": "core:window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.", + "description": "Denies the set_icon command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-title-bar-style" - ] + "const": "core:window:deny-set-icon" }, { - "description": "core:window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-set-visible-on-all-workspaces" - ] + "const": "core:window:deny-set-ignore-cursor-events" }, { - "description": "core:window:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the set_max_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-show" - ] + "const": "core:window:deny-set-max-size" }, { - "description": "core:window:deny-start-dragging -> Denies the start_dragging command without any pre-configured scope.", + "description": "Denies the set_maximizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-dragging" - ] + "const": "core:window:deny-set-maximizable" }, { - "description": "core:window:deny-start-resize-dragging -> Denies the start_resize_dragging command without any pre-configured scope.", + "description": "Denies the set_min_size command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-start-resize-dragging" - ] + "const": "core:window:deny-set-min-size" }, { - "description": "core:window:deny-theme -> Denies the theme command without any pre-configured scope.", + "description": "Denies the set_minimizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-theme" - ] + "const": "core:window:deny-set-minimizable" }, { - "description": "core:window:deny-title -> Denies the title command without any pre-configured scope.", + "description": "Denies the set_position command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-title" - ] + "const": "core:window:deny-set-position" }, { - "description": "core:window:deny-toggle-maximize -> Denies the toggle_maximize command without any pre-configured scope.", + "description": "Denies the set_progress_bar command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-toggle-maximize" - ] + "const": "core:window:deny-set-progress-bar" }, { - "description": "core:window:deny-unmaximize -> Denies the unmaximize command without any pre-configured scope.", + "description": "Denies the set_resizable command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unmaximize" - ] + "const": "core:window:deny-set-resizable" }, { - "description": "core:window:deny-unminimize -> Denies the unminimize command without any pre-configured scope.", + "description": "Denies the set_shadow command without any pre-configured scope.", "type": "string", - "enum": [ - "core:window:deny-unminimize" - ] + "const": "core:window:deny-set-shadow" }, { - "description": "dialog:default -> This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", + "description": "Denies the set_size command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:default" - ] + "const": "core:window:deny-set-size" }, { - "description": "dialog:allow-ask -> Enables the ask command without any pre-configured scope.", + "description": "Denies the set_size_constraints command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-ask" - ] + "const": "core:window:deny-set-size-constraints" }, { - "description": "dialog:allow-confirm -> Enables the confirm command without any pre-configured scope.", + "description": "Denies the set_skip_taskbar command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-confirm" - ] + "const": "core:window:deny-set-skip-taskbar" }, { - "description": "dialog:allow-message -> Enables the message command without any pre-configured scope.", + "description": "Denies the set_theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-message" - ] + "const": "core:window:deny-set-theme" }, { - "description": "dialog:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Denies the set_title command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-open" - ] + "const": "core:window:deny-set-title" }, { - "description": "dialog:allow-save -> Enables the save command without any pre-configured scope.", + "description": "Denies the set_title_bar_style command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:allow-save" - ] + "const": "core:window:deny-set-title-bar-style" }, { - "description": "dialog:deny-ask -> Denies the ask command without any pre-configured scope.", + "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-ask" - ] + "const": "core:window:deny-set-visible-on-all-workspaces" }, { - "description": "dialog:deny-confirm -> Denies the confirm command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-confirm" - ] + "const": "core:window:deny-show" }, { - "description": "dialog:deny-message -> Denies the message command without any pre-configured scope.", + "description": "Denies the start_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-message" - ] + "const": "core:window:deny-start-dragging" }, { - "description": "dialog:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the start_resize_dragging command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-open" - ] + "const": "core:window:deny-start-resize-dragging" }, { - "description": "dialog:deny-save -> Denies the save command without any pre-configured scope.", + "description": "Denies the theme command without any pre-configured scope.", "type": "string", - "enum": [ - "dialog:deny-save" - ] + "const": "core:window:deny-theme" }, { - "description": "log:default -> Allows the log command", + "description": "Denies the title command without any pre-configured scope.", "type": "string", - "enum": [ - "log:default" - ] + "const": "core:window:deny-title" }, { - "description": "log:allow-log -> Enables the log command without any pre-configured scope.", + "description": "Denies the toggle_maximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:allow-log" - ] + "const": "core:window:deny-toggle-maximize" }, { - "description": "log:deny-log -> Denies the log command without any pre-configured scope.", + "description": "Denies the unmaximize command without any pre-configured scope.", "type": "string", - "enum": [ - "log:deny-log" - ] + "const": "core:window:deny-unmaximize" }, { - "description": "notification:default -> This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", + "description": "Denies the unminimize command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:default" - ] + "const": "core:window:deny-unminimize" }, { - "description": "notification:allow-batch -> Enables the batch command without any pre-configured scope.", + "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n", "type": "string", - "enum": [ - "notification:allow-batch" - ] + "const": "dialog:default" }, { - "description": "notification:allow-cancel -> Enables the cancel command without any pre-configured scope.", + "description": "Enables the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-cancel" - ] + "const": "dialog:allow-ask" }, { - "description": "notification:allow-check-permissions -> Enables the check_permissions command without any pre-configured scope.", + "description": "Enables the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-check-permissions" - ] + "const": "dialog:allow-confirm" }, { - "description": "notification:allow-create-channel -> Enables the create_channel command without any pre-configured scope.", + "description": "Enables the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-create-channel" - ] + "const": "dialog:allow-message" }, { - "description": "notification:allow-delete-channel -> Enables the delete_channel command without any pre-configured scope.", + "description": "Enables the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-delete-channel" - ] + "const": "dialog:allow-open" }, { - "description": "notification:allow-get-active -> Enables the get_active command without any pre-configured scope.", + "description": "Enables the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-active" - ] + "const": "dialog:allow-save" }, { - "description": "notification:allow-get-pending -> Enables the get_pending command without any pre-configured scope.", + "description": "Denies the ask command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-get-pending" - ] + "const": "dialog:deny-ask" }, { - "description": "notification:allow-is-permission-granted -> Enables the is_permission_granted command without any pre-configured scope.", + "description": "Denies the confirm command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-is-permission-granted" - ] + "const": "dialog:deny-confirm" }, { - "description": "notification:allow-list-channels -> Enables the list_channels command without any pre-configured scope.", + "description": "Denies the message command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-list-channels" - ] + "const": "dialog:deny-message" }, { - "description": "notification:allow-notify -> Enables the notify command without any pre-configured scope.", + "description": "Denies the open command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-notify" - ] + "const": "dialog:deny-open" }, { - "description": "notification:allow-permission-state -> Enables the permission_state command without any pre-configured scope.", + "description": "Denies the save command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-permission-state" - ] + "const": "dialog:deny-save" }, { - "description": "notification:allow-register-action-types -> Enables the register_action_types command without any pre-configured scope.", + "description": "Allows the log command", "type": "string", - "enum": [ - "notification:allow-register-action-types" - ] + "const": "log:default" }, { - "description": "notification:allow-register-listener -> Enables the register_listener command without any pre-configured scope.", + "description": "Enables the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-register-listener" - ] + "const": "log:allow-log" }, { - "description": "notification:allow-remove-active -> Enables the remove_active command without any pre-configured scope.", + "description": "Denies the log command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-remove-active" - ] + "const": "log:deny-log" }, { - "description": "notification:allow-request-permission -> Enables the request_permission command without any pre-configured scope.", + "description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n", "type": "string", - "enum": [ - "notification:allow-request-permission" - ] + "const": "notification:default" }, { - "description": "notification:allow-show -> Enables the show command without any pre-configured scope.", + "description": "Enables the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:allow-show" - ] + "const": "notification:allow-batch" }, { - "description": "notification:deny-batch -> Denies the batch command without any pre-configured scope.", + "description": "Enables the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-batch" - ] + "const": "notification:allow-cancel" }, { - "description": "notification:deny-cancel -> Denies the cancel command without any pre-configured scope.", + "description": "Enables the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-cancel" - ] + "const": "notification:allow-check-permissions" }, { - "description": "notification:deny-check-permissions -> Denies the check_permissions command without any pre-configured scope.", + "description": "Enables the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-check-permissions" - ] + "const": "notification:allow-create-channel" }, { - "description": "notification:deny-create-channel -> Denies the create_channel command without any pre-configured scope.", + "description": "Enables the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-create-channel" - ] + "const": "notification:allow-delete-channel" }, { - "description": "notification:deny-delete-channel -> Denies the delete_channel command without any pre-configured scope.", + "description": "Enables the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-delete-channel" - ] + "const": "notification:allow-get-active" }, { - "description": "notification:deny-get-active -> Denies the get_active command without any pre-configured scope.", + "description": "Enables the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-active" - ] + "const": "notification:allow-get-pending" }, { - "description": "notification:deny-get-pending -> Denies the get_pending command without any pre-configured scope.", + "description": "Enables the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-get-pending" - ] + "const": "notification:allow-is-permission-granted" }, { - "description": "notification:deny-is-permission-granted -> Denies the is_permission_granted command without any pre-configured scope.", + "description": "Enables the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-is-permission-granted" - ] + "const": "notification:allow-list-channels" }, { - "description": "notification:deny-list-channels -> Denies the list_channels command without any pre-configured scope.", + "description": "Enables the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-list-channels" - ] + "const": "notification:allow-notify" }, { - "description": "notification:deny-notify -> Denies the notify command without any pre-configured scope.", + "description": "Enables the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-notify" - ] + "const": "notification:allow-permission-state" }, { - "description": "notification:deny-permission-state -> Denies the permission_state command without any pre-configured scope.", + "description": "Enables the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-permission-state" - ] + "const": "notification:allow-register-action-types" }, { - "description": "notification:deny-register-action-types -> Denies the register_action_types command without any pre-configured scope.", + "description": "Enables the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-action-types" - ] + "const": "notification:allow-register-listener" }, { - "description": "notification:deny-register-listener -> Denies the register_listener command without any pre-configured scope.", + "description": "Enables the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-register-listener" - ] + "const": "notification:allow-remove-active" }, { - "description": "notification:deny-remove-active -> Denies the remove_active command without any pre-configured scope.", + "description": "Enables the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-remove-active" - ] + "const": "notification:allow-request-permission" }, { - "description": "notification:deny-request-permission -> Denies the request_permission command without any pre-configured scope.", + "description": "Enables the show command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-request-permission" - ] + "const": "notification:allow-show" }, { - "description": "notification:deny-show -> Denies the show command without any pre-configured scope.", + "description": "Denies the batch command without any pre-configured scope.", "type": "string", - "enum": [ - "notification:deny-show" - ] + "const": "notification:deny-batch" }, { - "description": "os:default -> This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", + "description": "Denies the cancel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:default" - ] + "const": "notification:deny-cancel" }, { - "description": "os:allow-arch -> Enables the arch command without any pre-configured scope.", + "description": "Denies the check_permissions command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-arch" - ] + "const": "notification:deny-check-permissions" }, { - "description": "os:allow-exe-extension -> Enables the exe_extension command without any pre-configured scope.", + "description": "Denies the create_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-exe-extension" - ] + "const": "notification:deny-create-channel" }, { - "description": "os:allow-family -> Enables the family command without any pre-configured scope.", + "description": "Denies the delete_channel command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-family" - ] + "const": "notification:deny-delete-channel" }, { - "description": "os:allow-hostname -> Enables the hostname command without any pre-configured scope.", + "description": "Denies the get_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-hostname" - ] + "const": "notification:deny-get-active" }, { - "description": "os:allow-locale -> Enables the locale command without any pre-configured scope.", + "description": "Denies the get_pending command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-locale" - ] + "const": "notification:deny-get-pending" }, { - "description": "os:allow-os-type -> Enables the os_type command without any pre-configured scope.", + "description": "Denies the is_permission_granted command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-os-type" - ] + "const": "notification:deny-is-permission-granted" }, { - "description": "os:allow-platform -> Enables the platform command without any pre-configured scope.", + "description": "Denies the list_channels command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-platform" - ] + "const": "notification:deny-list-channels" }, { - "description": "os:allow-version -> Enables the version command without any pre-configured scope.", + "description": "Denies the notify command without any pre-configured scope.", "type": "string", - "enum": [ - "os:allow-version" - ] + "const": "notification:deny-notify" }, { - "description": "os:deny-arch -> Denies the arch command without any pre-configured scope.", + "description": "Denies the permission_state command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-arch" - ] + "const": "notification:deny-permission-state" }, { - "description": "os:deny-exe-extension -> Denies the exe_extension command without any pre-configured scope.", + "description": "Denies the register_action_types command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-exe-extension" - ] + "const": "notification:deny-register-action-types" }, { - "description": "os:deny-family -> Denies the family command without any pre-configured scope.", + "description": "Denies the register_listener command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-family" - ] + "const": "notification:deny-register-listener" }, { - "description": "os:deny-hostname -> Denies the hostname command without any pre-configured scope.", + "description": "Denies the remove_active command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-hostname" - ] + "const": "notification:deny-remove-active" }, { - "description": "os:deny-locale -> Denies the locale command without any pre-configured scope.", + "description": "Denies the request_permission command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-locale" - ] + "const": "notification:deny-request-permission" }, { - "description": "os:deny-os-type -> Denies the os_type command without any pre-configured scope.", + "description": "Denies the show command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-os-type" - ] + "const": "notification:deny-show" }, { - "description": "os:deny-platform -> Denies the platform command without any pre-configured scope.", + "description": "This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n", "type": "string", - "enum": [ - "os:deny-platform" - ] + "const": "os:default" }, { - "description": "os:deny-version -> Denies the version command without any pre-configured scope.", + "description": "Enables the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "os:deny-version" - ] + "const": "os:allow-arch" }, { - "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "description": "Enables the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:default" - ] + "const": "os:allow-exe-extension" }, { - "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "description": "Enables the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-execute" - ] + "const": "os:allow-family" }, { - "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "description": "Enables the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-kill" - ] + "const": "os:allow-hostname" }, { - "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "description": "Enables the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-open" - ] + "const": "os:allow-locale" }, { - "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "description": "Enables the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-spawn" - ] + "const": "os:allow-os-type" }, { - "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "description": "Enables the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:allow-stdin-write" - ] + "const": "os:allow-platform" }, { - "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "description": "Enables the version command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-execute" - ] + "const": "os:allow-version" }, { - "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "description": "Denies the arch command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-kill" - ] + "const": "os:deny-arch" }, { - "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "description": "Denies the exe_extension command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-open" - ] + "const": "os:deny-exe-extension" }, { - "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "description": "Denies the family command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-spawn" - ] + "const": "os:deny-family" }, { - "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "description": "Denies the hostname command without any pre-configured scope.", "type": "string", - "enum": [ - "shell:deny-stdin-write" - ] + "const": "os:deny-hostname" }, { - "description": "window-state:default -> This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "description": "Denies the locale command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:default" - ] + "const": "os:deny-locale" }, { - "description": "window-state:allow-filename -> Enables the filename command without any pre-configured scope.", + "description": "Denies the os_type command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-filename" - ] + "const": "os:deny-os-type" }, { - "description": "window-state:allow-restore-state -> Enables the restore_state command without any pre-configured scope.", + "description": "Denies the platform command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-restore-state" - ] + "const": "os:deny-platform" }, { - "description": "window-state:allow-save-window-state -> Enables the save_window_state command without any pre-configured scope.", + "description": "Denies the version command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:allow-save-window-state" - ] + "const": "os:deny-version" }, { - "description": "window-state:deny-filename -> Denies the filename command without any pre-configured scope.", + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", "type": "string", - "enum": [ - "window-state:deny-filename" - ] + "const": "shell:default" }, { - "description": "window-state:deny-restore-state -> Denies the restore_state command without any pre-configured scope.", + "description": "Enables the execute command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-restore-state" - ] + "const": "shell:allow-execute" }, { - "description": "window-state:deny-save-window-state -> Denies the save_window_state command without any pre-configured scope.", + "description": "Enables the kill command without any pre-configured scope.", "type": "string", - "enum": [ - "window-state:deny-save-window-state" - ] + "const": "shell:allow-kill" + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open" + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn" + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write" + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute" + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill" + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open" + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn" + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write" + }, + { + "description": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "type": "string", + "const": "window-state:default" + }, + { + "description": "Enables the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-filename" + }, + { + "description": "Enables the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-restore-state" + }, + { + "description": "Enables the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:allow-save-window-state" + }, + { + "description": "Denies the filename command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-filename" + }, + { + "description": "Denies the restore_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-restore-state" + }, + { + "description": "Denies the save_window_state command without any pre-configured scope.", + "type": "string", + "const": "window-state:deny-save-window-state" } ] }, @@ -3027,7 +2426,7 @@ } ] }, - "ShellAllowedArg": { + "ShellScopeEntryAllowedArg": { "description": "A command argument allowed to be executed by the webview API.", "anyOf": [ { @@ -3055,18 +2454,18 @@ } ] }, - "ShellAllowedArgs": { - "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "ShellScopeEntryAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", "anyOf": [ { "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", "type": "boolean" }, { - "description": "A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.", + "description": "A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.", "type": "array", "items": { - "$ref": "#/definitions/ShellAllowedArg" + "$ref": "#/definitions/ShellScopeEntryAllowedArg" } } ] diff --git a/desktop/tauri/src-tauri/src/traymenu.rs b/desktop/tauri/src-tauri/src/traymenu.rs index 0983db28..777b9d23 100644 --- a/desktop/tauri/src-tauri/src/traymenu.rs +++ b/desktop/tauri/src-tauri/src/traymenu.rs @@ -30,7 +30,7 @@ use crate::{ portmaster::PortmasterExt, window::{create_main_window, may_navigate_to_ui, open_window}, }; -use tauri_plugin_dialog::DialogExt; +use tauri_plugin_dialog::{DialogExt, MessageDialogButtons}; pub type AppIcon = TrayIcon; @@ -185,7 +185,7 @@ pub fn setup_tray_menu( app.dialog() .message("This does not stop the Portmaster system service") .title("Do you really want to quit the user interface?") - .buttons(tauri_plugin_dialog::MessageDialogButtons::OkCancelCustom( + .buttons(MessageDialogButtons::OkCancelCustom( "Yes, exit".to_owned(), "No".to_owned(), )) From 35d1e4d2e3b69a2647dbe778297f140cdcfb9c8b Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 26 Nov 2024 17:00:01 +0200 Subject: [PATCH 27/63] Fix file permissions on windows (#1758) * [service] Set file permissions on windows * [service] Fix minor windows permission bugs * [service] Fix permission bugs * [service] Fix windows non admin user start --- base/database/storage/fstree/fstree.go | 12 ++++++++---- base/utils/fs.go | 15 ++++++++++++--- base/utils/renameio/writefile.go | 14 ++++++++++++-- go.mod | 1 + go.sum | 3 +++ 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/base/database/storage/fstree/fstree.go b/base/database/storage/fstree/fstree.go index 44cf384f..7965439a 100644 --- a/base/database/storage/fstree/fstree.go +++ b/base/database/storage/fstree/fstree.go @@ -15,6 +15,7 @@ import ( "strings" "time" + "github.com/hectane/go-acl" "github.com/safing/portmaster/base/database/iterator" "github.com/safing/portmaster/base/database/query" "github.com/safing/portmaster/base/database/record" @@ -288,10 +289,13 @@ func writeFile(filename string, data []byte, perm os.FileMode) error { defer t.Cleanup() //nolint:errcheck // Set permissions before writing data, in case the data is sensitive. - if !onWindows { - if err := t.Chmod(perm); err != nil { - return err - } + if onWindows { + err = acl.Chmod(filename, perm) + } else { + err = t.Chmod(perm) + } + if err != nil { + return err } if _, err := t.Write(data); err != nil { diff --git a/base/utils/fs.go b/base/utils/fs.go index b612a069..bb59960f 100644 --- a/base/utils/fs.go +++ b/base/utils/fs.go @@ -6,6 +6,8 @@ import ( "io/fs" "os" "runtime" + + "github.com/hectane/go-acl" ) const isWindows = runtime.GOOS == "windows" @@ -20,8 +22,9 @@ func EnsureDirectory(path string, perm os.FileMode) error { if f.IsDir() { // directory exists, check permissions if isWindows { - // TODO: set correct permission on windows - // acl.Chmod(path, perm) + // Ignore windows permission error. For none admin users it will always fail. + acl.Chmod(path, perm) + return nil } else if f.Mode().Perm() != perm { return os.Chmod(path, perm) } @@ -38,7 +41,13 @@ func EnsureDirectory(path string, perm os.FileMode) error { if err != nil { return fmt.Errorf("could not create dir %s: %w", path, err) } - return os.Chmod(path, perm) + if isWindows { + // Ignore windows permission error. For none admin users it will always fail. + acl.Chmod(path, perm) + return nil + } else { + return os.Chmod(path, perm) + } } // other error opening path return fmt.Errorf("failed to access %s: %w", path, err) diff --git a/base/utils/renameio/writefile.go b/base/utils/renameio/writefile.go index 21153025..073a1e1b 100644 --- a/base/utils/renameio/writefile.go +++ b/base/utils/renameio/writefile.go @@ -1,6 +1,11 @@ package renameio -import "os" +import ( + "os" + "runtime" + + "github.com/hectane/go-acl" +) // WriteFile mirrors os.WriteFile, replacing an existing file with the same // name atomically. @@ -14,7 +19,12 @@ func WriteFile(filename string, data []byte, perm os.FileMode) error { }() // Set permissions before writing data, in case the data is sensitive. - if err := t.Chmod(perm); err != nil { + if runtime.GOOS == "windows" { + err = acl.Chmod(t.path, perm) + } else { + err = t.Chmod(perm) + } + if err != nil { return err } diff --git a/go.mod b/go.mod index 8ffd3e37..f3d7a43e 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.7.0 + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb github.com/jackc/puddle/v2 v2.2.2 github.com/lmittmann/tint v1.0.5 github.com/maruel/panicparse/v2 v2.3.1 diff --git a/go.sum b/go.sum index 6f47c5af..f644b0d2 100644 --- a/go.sum +++ b/go.sum @@ -129,6 +129,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -377,6 +379,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From ef0995b1f72bc638c4c0375c346b91fb0c6f17bf Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 28 Nov 2024 11:45:29 +0100 Subject: [PATCH 28/63] Define identifier for portmaster-core.dll and make it mandatory --- service/integration/integration_windows.go | 2 +- service/updates/helper/updates.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/service/integration/integration_windows.go b/service/integration/integration_windows.go index 786d6da6..80b1fd74 100644 --- a/service/integration/integration_windows.go +++ b/service/integration/integration_windows.go @@ -18,7 +18,7 @@ type OSSpecific struct { // Initialize loads the dll and finds all the needed functions from it. func (i *OSIntegration) Initialize() error { // Find path to the dll. - file, err := updates.GetFile("portmaster-core.dll") + file, err := updates.GetPlatformFile("dll/portmaster-core.dll") if err != nil { return err } diff --git a/service/updates/helper/updates.go b/service/updates/helper/updates.go index efae917d..59001c1c 100644 --- a/service/updates/helper/updates.go +++ b/service/updates/helper/updates.go @@ -52,6 +52,7 @@ func MandatoryUpdates() (identifiers []string) { identifiers = append( identifiers, PlatformIdentifier("core/portmaster-core.exe"), + PlatformIdentifier("dll/portmaster-core.dll"), PlatformIdentifier("kext/portmaster-kext.sys"), PlatformIdentifier("kext/portmaster-kext.pdb"), PlatformIdentifier("start/portmaster-start.exe"), From de3f5a8692a30af6dfcc9c02ead3c79a728d09d1 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Thu, 28 Nov 2024 13:27:10 +0200 Subject: [PATCH 29/63] [WIP] Fix logger starting bug --- base/log/logging.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/log/logging.go b/base/log/logging.go index d9ed43d9..93be59e7 100644 --- a/base/log/logging.go +++ b/base/log/logging.go @@ -191,7 +191,7 @@ func ParseLevel(level string) Severity { } // Start starts the logging system. Must be called in order to see logs. -func Start(level string, logToStdout bool, logDir string) (err error) { +func Start(level string, logToStdout bool, logDir string) error { if !initializing.SetToIf(false, true) { return nil } @@ -232,13 +232,13 @@ func Start(level string, logToStdout bool, logDir string) (err error) { // Delete all logs older than one month. if !logToStdout { - err = CleanOldLogs(logDir, 30*24*time.Hour) + err := CleanOldLogs(logDir, 30*24*time.Hour) if err != nil { Errorf("log: failed to clean old log files: %s", err) } } - return err + return nil } // Shutdown writes remaining log lines and then stops the log system. From b52cde15c510f163a5b4f05066cbbc0163b8dd55 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Fri, 29 Nov 2024 10:53:01 +0200 Subject: [PATCH 30/63] [WIP] Fix installers bundle files --- desktop/tauri/src-tauri/tauri.conf.json5 | 8 ++++---- desktop/tauri/src-tauri/templates/files.wxs | 4 ++-- desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh | 4 ++-- packaging/windows/generate_windows_installers.ps1 | 3 ++- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/desktop/tauri/src-tauri/tauri.conf.json5 b/desktop/tauri/src-tauri/tauri.conf.json5 index 5bd85972..464b1071 100644 --- a/desktop/tauri/src-tauri/tauri.conf.json5 +++ b/desktop/tauri/src-tauri/tauri.conf.json5 @@ -63,13 +63,13 @@ "/usr/lib/systemd/system/portmaster.service": "../../../packaging/linux/portmaster.service", // Binary files - "/usr/lib/portmaster/bin-index.json": "binary/bin-index.json", + "/usr/lib/portmaster/index.json": "binary/index.json", "/usr/lib/portmaster/portmaster-core": "binary/portmaster-core", "/usr/lib/portmaster/portmaster.zip": "binary/portmaster.zip", "/usr/lib/portmaster/assets.zip": "binary/assets.zip", // Intel files - "/var/lib/portmaster/intel/intel-index.json": "intel/intel-index.json", + "/var/lib/portmaster/intel/index.json": "intel/index.json", "/var/lib/portmaster/intel/base.dsdl": "intel/base.dsdl", "/var/lib/portmaster/intel/geoipv4.mmdb": "intel/geoipv4.mmdb", "/var/lib/portmaster/intel/geoipv6.mmdb": "intel/geoipv6.mmdb", @@ -94,13 +94,13 @@ "/usr/lib/systemd/system/portmaster.service": "../../../packaging/linux/portmaster.service", // Binary files - "/usr/lib/portmaster/bin-index.json": "binary/bin-index.json", + "/usr/lib/portmaster/index.json": "binary/index.json", "/usr/lib/portmaster/portmaster-core": "binary/portmaster-core", "/usr/lib/portmaster/portmaster.zip": "binary/portmaster.zip", "/usr/lib/portmaster/assets.zip": "binary/assets.zip", // Intel files - "/var/lib/portmaster/intel/intel-index.json": "intel/intel-index.json", + "/var/lib/portmaster/intel/index.json": "intel/index.json", "/var/lib/portmaster/intel/base.dsdl": "intel/base.dsdl", "/var/lib/portmaster/intel/geoipv4.mmdb": "intel/geoipv4.mmdb", "/var/lib/portmaster/intel/geoipv6.mmdb": "intel/geoipv6.mmdb", diff --git a/desktop/tauri/src-tauri/templates/files.wxs b/desktop/tauri/src-tauri/templates/files.wxs index 4828178f..8623e435 100644 --- a/desktop/tauri/src-tauri/templates/files.wxs +++ b/desktop/tauri/src-tauri/templates/files.wxs @@ -12,7 +12,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh index 6b5afb58..0dd25f0d 100644 --- a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh +++ b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh @@ -3,7 +3,7 @@ SetOutPath "$INSTDIR" - File "..\..\..\..\binary\bin-index.json" + File "..\..\..\..\binary\index.json" File "..\..\..\..\binary\portmaster-core.exe" File "..\..\..\..\binary\portmaster-kext.sys" File "..\..\..\..\binary\portmaster.zip" @@ -11,7 +11,7 @@ SetOutPath "$COMMONPROGRAMDATA\Portmaster\intel" - File "..\..\..\..\intel\intel-index.json" + File "..\..\..\..\intel\index.json" File "..\..\..\..\intel\base.dsdl" File "..\..\..\..\intel\geoipv4.mmdb" File "..\..\..\..\intel\geoipv6.mmdb" diff --git a/packaging/windows/generate_windows_installers.ps1 b/packaging/windows/generate_windows_installers.ps1 index c18a0d1b..407a8cc3 100644 --- a/packaging/windows/generate_windows_installers.ps1 +++ b/packaging/windows/generate_windows_installers.ps1 @@ -53,7 +53,8 @@ if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { } Write-Output "Downloading tauri-cli" -Invoke-WebRequest -Uri https://github.com/tauri-apps/tauri/releases/download/tauri-cli-v2.0.1/cargo-tauri-x86_64-pc-windows-msvc.zip -OutFile tauri-cli.zip + +Invoke-WebRequest -Uri https://github.com/tauri-apps/tauri/releases/download/tauri-cli-v2.1.0/cargo-tauri-x86_64-pc-windows-msvc.zip -OutFile tauri-cli.zip Expand-Archive -Force tauri-cli.zip ./tauri-cli/cargo-tauri.exe bundle From 2a9d75433f5b1e1d2cd8105438cba6d1cfc0bef0 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 2 Dec 2024 14:02:49 +0200 Subject: [PATCH 31/63] [service] Fix module failure when dll is missing --- .../dnsmonitor/etwlink_windows.go | 9 ++++-- .../dnsmonitor/eventlistener_windows.go | 25 +++++++++++---- service/integration/etw_windows.go | 4 +-- service/integration/integration_windows.go | 32 ++++++++++++++++--- service/integration/module.go | 12 +++---- 5 files changed, 60 insertions(+), 22 deletions(-) diff --git a/service/firewall/interception/dnsmonitor/etwlink_windows.go b/service/firewall/interception/dnsmonitor/etwlink_windows.go index d014bbab..e0d48bdc 100644 --- a/service/firewall/interception/dnsmonitor/etwlink_windows.go +++ b/service/firewall/interception/dnsmonitor/etwlink_windows.go @@ -14,7 +14,7 @@ import ( ) type ETWSession struct { - i integration.ETWFunctions + i *integration.ETWFunctions shutdownGuard atomic.Bool shutdownMutex sync.Mutex @@ -23,7 +23,10 @@ type ETWSession struct { } // NewSession creates new ETW event listener and initilizes it. This is a low level interface, make sure to call DestorySession when you are done using it. -func NewSession(etwInterface integration.ETWFunctions, callback func(domain string, result string)) (*ETWSession, error) { +func NewSession(etwInterface *integration.ETWFunctions, callback func(domain string, result string)) (*ETWSession, error) { + if etwInterface == nil { + return nil, fmt.Errorf("etw interface was nil") + } etwSession := &ETWSession{ i: etwInterface, } @@ -47,7 +50,7 @@ func NewSession(etwInterface integration.ETWFunctions, callback func(domain stri // Initialize session. err := etwSession.i.InitializeSession(etwSession.state) if err != nil { - return nil, fmt.Errorf("failed to initialzie session: %q", err) + return nil, fmt.Errorf("failed to initialize session: %q", err) } return etwSession, nil diff --git a/service/firewall/interception/dnsmonitor/eventlistener_windows.go b/service/firewall/interception/dnsmonitor/eventlistener_windows.go index b6a39fd8..28310136 100644 --- a/service/firewall/interception/dnsmonitor/eventlistener_windows.go +++ b/service/firewall/interception/dnsmonitor/eventlistener_windows.go @@ -23,19 +23,32 @@ func newListener(module *DNSMonitor) (*Listener, error) { ResolverInfo.Source = resolver.ServerSourceETW listener := &Listener{} - var err error // Initialize new dns event session. + err := initializeSessions(module, listener) + if err != nil { + // Listen for event if the dll has been loaded + module.instance.OSIntegration().OnInitializedEvent.AddCallback("loader-listener", func(wc *mgr.WorkerCtx, s struct{}) (cancel bool, err error) { + err = initializeSessions(module, listener) + if err != nil { + return false, err + } + return true, nil + }) + } + return listener, nil +} + +func initializeSessions(module *DNSMonitor, listener *Listener) error { + var err error listener.etw, err = NewSession(module.instance.OSIntegration().GetETWInterface(), listener.processEvent) if err != nil { - return nil, err + return err } - - // Start listening for events. + // Start listener module.mgr.Go("etw-dns-event-listener", func(w *mgr.WorkerCtx) error { return listener.etw.StartTrace() }) - - return listener, nil + return nil } func (l *Listener) flush() error { diff --git a/service/integration/etw_windows.go b/service/integration/etw_windows.go index eac3ad8f..d655967a 100644 --- a/service/integration/etw_windows.go +++ b/service/integration/etw_windows.go @@ -19,8 +19,8 @@ type ETWFunctions struct { stopOldSession *windows.Proc } -func initializeETW(dll *windows.DLL) (ETWFunctions, error) { - var functions ETWFunctions +func initializeETW(dll *windows.DLL) (*ETWFunctions, error) { + functions := &ETWFunctions{} var err error functions.createState, err = dll.FindProc("PM_ETWCreateState") if err != nil { diff --git a/service/integration/integration_windows.go b/service/integration/integration_windows.go index 80b1fd74..0ca123fc 100644 --- a/service/integration/integration_windows.go +++ b/service/integration/integration_windows.go @@ -6,23 +6,42 @@ package integration import ( "fmt" + "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/updates" "golang.org/x/sys/windows" ) type OSSpecific struct { dll *windows.DLL - etwFunctions ETWFunctions + etwFunctions *ETWFunctions } // Initialize loads the dll and finds all the needed functions from it. func (i *OSIntegration) Initialize() error { + // Try to load dll + err := i.loadDLL() + if err != nil { + log.Errorf("integration: failed to load dll: %s", err) + + // listen for event from the updater and try to load again if any. + i.instance.Updates().EventResourcesUpdated.AddCallback("core-dll-loader", func(wc *mgr.WorkerCtx, s struct{}) (cancel bool, err error) { + err = i.loadDLL() + if err != nil { + log.Errorf("integration: failed to load dll: %s", err) + } + return false, nil + }) + } + return nil +} + +func (i *OSIntegration) loadDLL() error { // Find path to the dll. file, err := updates.GetPlatformFile("dll/portmaster-core.dll") if err != nil { return err } - // Load the DLL. i.os.dll, err = windows.LoadDLL(file.Path()) if err != nil { @@ -35,10 +54,13 @@ func (i *OSIntegration) Initialize() error { return err } + // Notify listeners + i.OnInitializedEvent.Submit(struct{}{}) + return nil } -// CleanUp releases any resourses allocated during initializaion. +// CleanUp releases any resources allocated during initialization. func (i *OSIntegration) CleanUp() error { if i.os.dll != nil { return i.os.dll.Release() @@ -46,7 +68,7 @@ func (i *OSIntegration) CleanUp() error { return nil } -// GetETWInterface return struct containing all the ETW related functions. -func (i *OSIntegration) GetETWInterface() ETWFunctions { +// GetETWInterface return struct containing all the ETW related functions, and nil if it was not loaded yet +func (i *OSIntegration) GetETWInterface() *ETWFunctions { return i.os.etwFunctions } diff --git a/service/integration/module.go b/service/integration/module.go index 0e43798a..6a237434 100644 --- a/service/integration/module.go +++ b/service/integration/module.go @@ -7,8 +7,9 @@ import ( // OSIntegration module provides special integration with the OS. type OSIntegration struct { - m *mgr.Manager - states *mgr.StateMgr + m *mgr.Manager + + OnInitializedEvent *mgr.EventMgr[struct{}] //nolint:unused os OSSpecific @@ -20,10 +21,9 @@ type OSIntegration struct { func New(instance instance) (*OSIntegration, error) { m := mgr.New("OSIntegration") module := &OSIntegration{ - m: m, - states: m.NewStateMgr(), - - instance: instance, + m: m, + OnInitializedEvent: mgr.NewEventMgr[struct{}]("on-initialized", m), + instance: instance, } return module, nil From ed2338fdb94478b462f5e833883e242e9023d9c8 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 2 Dec 2024 15:15:46 +0200 Subject: [PATCH 32/63] [service] Fix error on unitilized dns monitor --- .../interception/dnsmonitor/etwlink_windows.go | 7 +++++++ .../interception/dnsmonitor/eventlistener_windows.go | 3 +++ service/integration/integration_windows.go | 12 ++++++++++++ service/network/connection.go | 6 +++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/service/firewall/interception/dnsmonitor/etwlink_windows.go b/service/firewall/interception/dnsmonitor/etwlink_windows.go index e0d48bdc..cb9d8675 100644 --- a/service/firewall/interception/dnsmonitor/etwlink_windows.go +++ b/service/firewall/interception/dnsmonitor/etwlink_windows.go @@ -68,6 +68,10 @@ func (l *ETWSession) IsRunning() bool { // FlushTrace flushes the trace buffer. func (l *ETWSession) FlushTrace() error { + if l.i == nil { + return fmt.Errorf("session not initialized") + } + l.shutdownMutex.Lock() defer l.shutdownMutex.Unlock() @@ -86,6 +90,9 @@ func (l *ETWSession) StopTrace() error { // DestroySession closes the session and frees the allocated memory. Listener cannot be used after this function is called. func (l *ETWSession) DestroySession() error { + if l.i == nil { + return fmt.Errorf("session not initialized") + } l.shutdownMutex.Lock() defer l.shutdownMutex.Unlock() diff --git a/service/firewall/interception/dnsmonitor/eventlistener_windows.go b/service/firewall/interception/dnsmonitor/eventlistener_windows.go index 28310136..a46e8cc6 100644 --- a/service/firewall/interception/dnsmonitor/eventlistener_windows.go +++ b/service/firewall/interception/dnsmonitor/eventlistener_windows.go @@ -52,6 +52,9 @@ func initializeSessions(module *DNSMonitor, listener *Listener) error { } func (l *Listener) flush() error { + if l.etw == nil { + return fmt.Errorf("etw not initialized") + } return l.etw.FlushTrace() } diff --git a/service/integration/integration_windows.go b/service/integration/integration_windows.go index 0ca123fc..b297b363 100644 --- a/service/integration/integration_windows.go +++ b/service/integration/integration_windows.go @@ -5,6 +5,7 @@ package integration import ( "fmt" + "sync" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/service/mgr" @@ -24,14 +25,25 @@ func (i *OSIntegration) Initialize() error { if err != nil { log.Errorf("integration: failed to load dll: %s", err) + callbackLock := sync.Mutex{} // listen for event from the updater and try to load again if any. i.instance.Updates().EventResourcesUpdated.AddCallback("core-dll-loader", func(wc *mgr.WorkerCtx, s struct{}) (cancel bool, err error) { + // Make sure no multiple callas are executed at the same time. + callbackLock.Lock() + defer callbackLock.Unlock() + + // Try to load again. err = i.loadDLL() if err != nil { log.Errorf("integration: failed to load dll: %s", err) + } else { + log.Info("integration: initialize successful after updater event") } return false, nil }) + + } else { + log.Info("integration: initialize successful") } return nil } diff --git a/service/network/connection.go b/service/network/connection.go index b3dd70fc..1c1bbf19 100644 --- a/service/network/connection.go +++ b/service/network/connection.go @@ -550,7 +550,11 @@ func (conn *Connection) GatherConnectionInfo(pkt packet.Packet) (err error) { if module.instance.Resolver().IsDisabled() && conn.shouldWaitForDomain() { // Flush the dns listener buffer and try again. for i := range 4 { - _ = module.instance.DNSMonitor().Flush() + err = module.instance.DNSMonitor().Flush() + if err != nil { + // Error flushing, dont try again. + break + } ipinfo, err = resolver.GetIPInfo(resolver.IPInfoProfileScopeGlobal, pkt.Info().RemoteIP().String()) if err == nil { log.Tracer(pkt.Ctx()).Debugf("network: found domain from dnsmonitor after %d tries", i+1) From d15ede9f53ae01fc755fc1806ce142a65eb13c67 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 3 Dec 2024 17:27:33 +0200 Subject: [PATCH 33/63] [WIP] Fix winodws service installer --- desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh | 2 +- desktop/tauri/src-tauri/templates/service.wxs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh index 0dd25f0d..79bc1218 100644 --- a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh +++ b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh @@ -25,7 +25,7 @@ !macroend !macro NSIS_HOOK_POSTINSTALL - ExecWait 'sc.exe create PortmasterCore binPath= "$INSTDIR\portmaster-core.exe" --data="$COMMONPROGRAMDATA\Portmaster\data"' + ExecWait 'sc.exe create PortmasterCore binPath= "$INSTDIR\portmaster-core.exe"' !macroend !macro NSIS_HOOK_PREUNINSTALL diff --git a/desktop/tauri/src-tauri/templates/service.wxs b/desktop/tauri/src-tauri/templates/service.wxs index 4ade87cd..28a035d5 100644 --- a/desktop/tauri/src-tauri/templates/service.wxs +++ b/desktop/tauri/src-tauri/templates/service.wxs @@ -3,7 +3,7 @@ Date: Tue, 3 Dec 2024 17:28:40 +0200 Subject: [PATCH 34/63] [WIP] Fix tauri notifications --- Earthfile | 9 ++++++--- desktop/tauri/src-tauri/src/cli.rs | 18 +++++++++--------- desktop/tauri/src-tauri/src/main.rs | 16 ++++++++-------- .../src-tauri/src/portmaster/notifications.rs | 7 ++++--- desktop/tauri/src-tauri/tauri.conf.json5 | 8 ++++---- service/integration/integration_windows.go | 2 +- service/intel/filterlists/index.go | 14 +++++++------- 7 files changed, 39 insertions(+), 35 deletions(-) diff --git a/Earthfile b/Earthfile index 5d720d17..aaa60d87 100644 --- a/Earthfile +++ b/Earthfile @@ -474,10 +474,11 @@ tauri-build: # Binaries SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/portmaster" SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster.exe" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/portmaster.exe" - # SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/WebView2Loader.dll" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/WebView2Loader.dll" + SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/WebView2Loader.dll" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/WebView2Loader.dll" SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster" ./output/portmaster SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster.exe" ./output/portmaster.exe + SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/WebView2Loader.dll" ./output/WebView2Loader.dll tauri-release: @@ -517,9 +518,11 @@ release-prep: # Windows specific COPY (+tauri-build/output/portmaster.exe --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/portmaster.exe + COPY (+tauri-build/output/WebView2Loader.dll --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/WebView2Loader.dll COPY (+go-build/output/portmaster-core.exe --GOARCH=amd64 --GOOS=windows --CMDS=portmaster-core) ./output/binary/windows_amd64/portmaster-core.exe - # TODO(vladimir): figure out a way to get the lastest release of the kext. - RUN touch ./output/binary/windows_amd64/portmaster-kext.sys + # TODO(vladimir): figure out a way to get the lastest release of the kext and dll. + RUN wget -O ./output/binary/windows_amd64/portmaster-kext.sys https://updates.safing.io/windows_amd64/kext/portmaster-kext_v2-0-4.sys + RUN touch ./output/binary/windows_amd64/portmaster-core.dll # All platforms COPY (+assets/assets.zip) ./output/binary/all/assets.zip diff --git a/desktop/tauri/src-tauri/src/cli.rs b/desktop/tauri/src-tauri/src/cli.rs index d11c2aed..61a7462e 100644 --- a/desktop/tauri/src-tauri/src/cli.rs +++ b/desktop/tauri/src-tauri/src/cli.rs @@ -1,9 +1,9 @@ use log::LevelFilter; -#[cfg(not(debug_assertions))] -const DEFAULT_LOG_LEVEL: log::LevelFilter = log::LevelFilter::Warn; +// #[cfg(not(debug_assertions))] +// const DEFAULT_LOG_LEVEL: log::LevelFilter = log::LevelFilter::Warn; -#[cfg(debug_assertions)] +// #[cfg(debug_assertions)] const DEFAULT_LOG_LEVEL: log::LevelFilter = log::LevelFilter::Debug; #[derive(Debug)] @@ -43,8 +43,8 @@ pub fn parse(raw: impl IntoIterator>) -> Cl data: None, log_level: DEFAULT_LOG_LEVEL, background: false, - with_prompts: false, - with_notifications: false, + with_prompts: true, + with_notifications: true, }; let raw = clap_lex::RawArgs::new(raw); @@ -67,11 +67,11 @@ pub fn parse(raw: impl IntoIterator>) -> Cl Ok("background") => { cli.background = true; } - Ok("with_prompts") => { - cli.with_prompts = true; + Ok("no-prompts") => { + cli.with_prompts = false; } - Ok("with_notifications") => { - cli.with_notifications = true; + Ok("no-notifications") => { + cli.with_notifications = false; } _ => { // Ignore unexpected flags diff --git a/desktop/tauri/src-tauri/src/main.rs b/desktop/tauri/src-tauri/src/main.rs index cce1b266..411d4579 100644 --- a/desktop/tauri/src-tauri/src/main.rs +++ b/desktop/tauri/src-tauri/src/main.rs @@ -127,14 +127,14 @@ fn main() { let cli_args = cli::parse(std::env::args()); #[cfg(target_os = "linux")] - let log_target = if let Some(data_dir) = cli_args.data { - tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Folder { - path: Path::new(&format!("{}/logs/app2", data_dir)).into(), - file_name: None, - }) - } else { - tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Stdout) - }; + let log_target = tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Stdout); + // let log_target = if let Some(data_dir) = cli_args.data { + // tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Folder { + // path: Path::new(&format!("{}/logs/app2", data_dir)).into(), + // file_name: None, + // }) + // } else { + // }; // TODO(vladimir): Permission for logs/app2 folder are not guaranteed. Use the default location for now. #[cfg(target_os = "windows")] diff --git a/desktop/tauri/src-tauri/src/portmaster/notifications.rs b/desktop/tauri/src-tauri/src/portmaster/notifications.rs index 452db996..7128eda0 100644 --- a/desktop/tauri/src-tauri/src/portmaster/notifications.rs +++ b/desktop/tauri/src-tauri/src/portmaster/notifications.rs @@ -2,6 +2,7 @@ use crate::portapi::client::*; use crate::portapi::message::*; use crate::portapi::models::notification::*; use crate::portapi::types::*; +use log::debug; use log::error; use serde_json::json; use tauri::async_runtime; @@ -25,12 +26,12 @@ pub async fn notification_handler(cli: PortAPI) { Ok(n) => { // Skip if this one should not be shown using the system notifications if !n.show_on_system { - return; + continue; } // Skip if this action has already been acted on - if n.selected_action_id.is_empty() { - return; + if !n.selected_action_id.is_empty() { + continue; } show_notification(&cli, key, n).await; } diff --git a/desktop/tauri/src-tauri/tauri.conf.json5 b/desktop/tauri/src-tauri/tauri.conf.json5 index 464b1071..00a9cced 100644 --- a/desktop/tauri/src-tauri/tauri.conf.json5 +++ b/desktop/tauri/src-tauri/tauri.conf.json5 @@ -28,12 +28,12 @@ "takesValue": true }, { - "name": "with-notifications", - "description": "Enable experimental notifications via Tauri. Replaces the notifier app." + "name": "no-notifications", + "description": "Disable notifications via Tauri." }, { - "name": "with-prompts", - "description": "Enable experimental prompt support via Tauri. Replaces the notifier app." + "name": "no-prompts", + "description": "Disable prompt support via Tauri." }, ] } diff --git a/service/integration/integration_windows.go b/service/integration/integration_windows.go index cfb0cd9b..40d063f4 100644 --- a/service/integration/integration_windows.go +++ b/service/integration/integration_windows.go @@ -37,7 +37,7 @@ func (i *OSIntegration) Initialize() error { return nil } -// CleanUp releases any resourses allocated during initializaion. +// CleanUp releases any resources allocated during initialization. func (i *OSIntegration) CleanUp() error { if i.os.dll != nil { return i.os.dll.Release() diff --git a/service/intel/filterlists/index.go b/service/intel/filterlists/index.go index 9ba0ec17..15055e3b 100644 --- a/service/intel/filterlists/index.go +++ b/service/intel/filterlists/index.go @@ -238,14 +238,14 @@ func updateListIndex() error { func ResolveListIDs(ids []string) ([]string, error) { index, err := getListIndexFromCache() if err != nil { - if errors.Is(err, database.ErrNotFound) { - if err := updateListIndex(); err != nil { - return nil, err - } + // if errors.Is(err, database.ErrNotFound) { + // if err := updateListIndex(); err != nil { + // return nil, err + // } - // retry resolving IDs - return ResolveListIDs(ids) - } + // // retry resolving IDs + // return ResolveListIDs(ids) + // } log.Errorf("failed to resolved ids %v: %s", ids, err) return nil, err From 22253c4e9e53918d9675dff5ffed67b3baa2304f Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Fri, 6 Dec 2024 12:00:20 +0200 Subject: [PATCH 35/63] [service] Fix windows permissions --- base/config/main.go | 4 +-- base/database/main.go | 6 ++-- base/database/storage/fstree/fstree.go | 7 ++-- base/dataroot/root.go | 3 +- base/updater/fetch.go | 17 +++------- base/updater/registry.go | 2 +- base/utils/fs.go | 19 +++++------ base/utils/permissions.go | 20 ++++++++++++ base/utils/permissions_windows.go | 35 ++++++++++++++++++++ base/utils/structure.go | 44 +++++++++++++++++++++++--- cmds/portmaster-start/dirs.go | 3 +- cmds/portmaster-start/main.go | 6 ++-- service/core/base/global.go | 3 +- service/netquery/database.go | 5 +-- service/profile/module.go | 3 +- service/ui/module.go | 3 +- service/updates/main.go | 3 +- service/updates/upgrader.go | 12 +++---- 18 files changed, 138 insertions(+), 57 deletions(-) create mode 100644 base/utils/permissions.go create mode 100644 base/utils/permissions_windows.go diff --git a/base/config/main.go b/base/config/main.go index 0ed0b7e6..c737dc2f 100644 --- a/base/config/main.go +++ b/base/config/main.go @@ -144,9 +144,9 @@ func InitializeUnitTestDataroot(testName string) (string, error) { return "", fmt.Errorf("failed to make tmp dir: %w", err) } - ds := utils.NewDirStructure(basePath, 0o0755) + ds := utils.NewDirStructure(basePath, utils.PublicReadPermission) SetDataRoot(ds) - err = dataroot.Initialize(basePath, 0o0755) + err = dataroot.Initialize(basePath, utils.PublicReadPermission) if err != nil { return "", fmt.Errorf("failed to initialize dataroot: %w", err) } diff --git a/base/database/main.go b/base/database/main.go index f84a0108..9c9aa1ed 100644 --- a/base/database/main.go +++ b/base/database/main.go @@ -25,7 +25,7 @@ var ( // InitializeWithPath initializes the database at the specified location using a path. func InitializeWithPath(dirPath string) error { - return Initialize(utils.NewDirStructure(dirPath, 0o0755)) + return Initialize(utils.NewDirStructure(dirPath, utils.PublicReadPermission)) } // Initialize initializes the database at the specified location using a dir structure. @@ -34,7 +34,7 @@ func Initialize(dirStructureRoot *utils.DirStructure) error { rootStructure = dirStructureRoot // ensure root and databases dirs - databasesStructure = rootStructure.ChildDir(databasesSubDir, 0o0700) + databasesStructure = rootStructure.ChildDir(databasesSubDir, utils.AdminOnlyPermission) err := databasesStructure.Ensure() if err != nil { return fmt.Errorf("could not create/open database directory (%s): %w", rootStructure.Path, err) @@ -67,7 +67,7 @@ func Shutdown() (err error) { // getLocation returns the storage location for the given name and type. func getLocation(name, storageType string) (string, error) { - location := databasesStructure.ChildDir(name, 0o0700).ChildDir(storageType, 0o0700) + location := databasesStructure.ChildDir(name, utils.AdminOnlyPermission).ChildDir(storageType, utils.AdminOnlyPermission) // check location err := location.Ensure() if err != nil { diff --git a/base/database/storage/fstree/fstree.go b/base/database/storage/fstree/fstree.go index 7965439a..0b4f175c 100644 --- a/base/database/storage/fstree/fstree.go +++ b/base/database/storage/fstree/fstree.go @@ -289,11 +289,8 @@ func writeFile(filename string, data []byte, perm os.FileMode) error { defer t.Cleanup() //nolint:errcheck // Set permissions before writing data, in case the data is sensitive. - if onWindows { - err = acl.Chmod(filename, perm) - } else { - err = t.Chmod(perm) - } + // TODO(vladimir): to set permissions on windows we need the full path of the file. + err = t.Chmod(perm) if err != nil { return err } diff --git a/base/dataroot/root.go b/base/dataroot/root.go index 296b342f..75805255 100644 --- a/base/dataroot/root.go +++ b/base/dataroot/root.go @@ -2,7 +2,6 @@ package dataroot import ( "errors" - "os" "github.com/safing/portmaster/base/utils" ) @@ -10,7 +9,7 @@ import ( var root *utils.DirStructure // Initialize initializes the data root directory. -func Initialize(rootDir string, perm os.FileMode) error { +func Initialize(rootDir string, perm utils.FSPermission) error { if root != nil { return errors.New("already initialized") } diff --git a/base/updater/fetch.go b/base/updater/fetch.go index 150037ed..f7f373dc 100644 --- a/base/updater/fetch.go +++ b/base/updater/fetch.go @@ -14,10 +14,10 @@ import ( "path/filepath" "time" - "github.com/hectane/go-acl" "github.com/safing/jess/filesig" "github.com/safing/jess/lhash" "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/base/utils/renameio" ) @@ -137,17 +137,10 @@ func (reg *ResourceRegistry) fetchFile(ctx context.Context, client *http.Client, return fmt.Errorf("%s: failed to finalize file %s: %w", reg.Name, rv.storagePath(), err) } // set permissions - if onWindows { - err = acl.Chmod(rv.storagePath(), 0o0755) - if err != nil { - log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err) - } - } else { - // TODO: only set executable files to 0755, set other to 0644 - err = os.Chmod(rv.storagePath(), 0o0755) //nolint:gosec // See TODO above. - if err != nil { - log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err) - } + // TODO: distinguish between executable and non executable files. + err = utils.SetExecPermission(rv.storagePath(), utils.PublicReadPermission) + if err != nil { + log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err) } log.Debugf("%s: fetched %s and stored to %s", reg.Name, downloadURL, rv.storagePath()) diff --git a/base/updater/registry.go b/base/updater/registry.go index 8deda74e..4450fe98 100644 --- a/base/updater/registry.go +++ b/base/updater/registry.go @@ -98,7 +98,7 @@ func (reg *ResourceRegistry) Initialize(storageDir *utils.DirStructure) error { // initialize private attributes reg.storageDir = storageDir - reg.tmpDir = storageDir.ChildDir("tmp", 0o0700) + reg.tmpDir = storageDir.ChildDir("tmp", utils.AdminOnlyPermission) reg.resources = make(map[string]*Resource) if reg.state == nil { reg.state = &RegistryState{} diff --git a/base/utils/fs.go b/base/utils/fs.go index bb59960f..6ede989d 100644 --- a/base/utils/fs.go +++ b/base/utils/fs.go @@ -6,15 +6,13 @@ import ( "io/fs" "os" "runtime" - - "github.com/hectane/go-acl" ) const isWindows = runtime.GOOS == "windows" // EnsureDirectory ensures that the given directory exists and that is has the given permissions set. // If path is a file, it is deleted and a directory created. -func EnsureDirectory(path string, perm os.FileMode) error { +func EnsureDirectory(path string, perm FSPermission) error { // open path f, err := os.Stat(path) if err == nil { @@ -23,10 +21,10 @@ func EnsureDirectory(path string, perm os.FileMode) error { // directory exists, check permissions if isWindows { // Ignore windows permission error. For none admin users it will always fail. - acl.Chmod(path, perm) + SetDirPermission(path, perm) return nil - } else if f.Mode().Perm() != perm { - return os.Chmod(path, perm) + } else if f.Mode().Perm() != perm.AsUnixDirExecPermission() { + return SetDirPermission(path, perm) } return nil } @@ -37,17 +35,16 @@ func EnsureDirectory(path string, perm os.FileMode) error { } // file does not exist (or has been deleted) if err == nil || errors.Is(err, fs.ErrNotExist) { - err = os.Mkdir(path, perm) + err = os.Mkdir(path, perm.AsUnixDirExecPermission()) if err != nil { return fmt.Errorf("could not create dir %s: %w", path, err) } + // Set windows permissions. Linux permission where already set with creation. if isWindows { // Ignore windows permission error. For none admin users it will always fail. - acl.Chmod(path, perm) - return nil - } else { - return os.Chmod(path, perm) + SetDirPermission(path, perm) } + return nil } // other error opening path return fmt.Errorf("failed to access %s: %w", path, err) diff --git a/base/utils/permissions.go b/base/utils/permissions.go new file mode 100644 index 00000000..d7690724 --- /dev/null +++ b/base/utils/permissions.go @@ -0,0 +1,20 @@ +//go:build !windows + +package utils + +import "os" + +// SetDirPermission sets the permission of a directory. +func SetDirPermission(path string, perm FSPermission) error { + return os.Chmod(path, perm.AsUnixDirExecPermission()) +} + +// SetExecPermission sets the permission of an executable file. +func SetExecPermission(path string, perm FSPermission) error { + return SetDirPermission(path, perm) +} + +// SetFilePermission sets the permission of a non executable file. +func SetFilePermission(path string, perm FSPermission) error { + return os.Chmod(path, perm.AsUnixFilePermission()) +} diff --git a/base/utils/permissions_windows.go b/base/utils/permissions_windows.go new file mode 100644 index 00000000..ac48c21a --- /dev/null +++ b/base/utils/permissions_windows.go @@ -0,0 +1,35 @@ +//go:build windows + +package utils + +import ( + "github.com/hectane/go-acl" + "golang.org/x/sys/windows" +) + +func SetDirPermission(path string, perm FSPermission) error { + setWindowsFilePermissions(path, perm) + return nil +} + +// SetExecPermission sets the permission of an executable file. +func SetExecPermission(path string, perm FSPermission) error { + return SetDirPermission(path, perm) +} + +func setWindowsFilePermissions(path string, perm FSPermission) { + switch perm { + case AdminOnlyPermission: + // Set only admin rights, remove all others. + acl.Apply(path, true, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Administrators")) + case PublicReadPermission: + // Set admin rights and read/execute rights for users, remove all others. + acl.Apply(path, true, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Administrators")) + acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_EXECUTE, "Users")) + acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_READ, "Users")) + case PublicWritePermission: + // Set full control to admin and regular users. Guest users will not have access. + acl.Apply(path, true, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Administrators")) + acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Users")) + } +} diff --git a/base/utils/structure.go b/base/utils/structure.go index 5a50d97e..e33a920f 100644 --- a/base/utils/structure.go +++ b/base/utils/structure.go @@ -2,25 +2,61 @@ package utils import ( "fmt" - "os" + "io/fs" "path/filepath" "strings" "sync" ) +type FSPermission uint8 + +const ( + AdminOnlyPermission FSPermission = iota + PublicReadPermission + PublicWritePermission +) + +// AsUnixDirPermission return the corresponding unix permission for a directory or executable. +func (perm FSPermission) AsUnixDirExecPermission() fs.FileMode { + switch perm { + case AdminOnlyPermission: + return 0o700 + case PublicReadPermission: + return 0o755 + case PublicWritePermission: + return 0o777 + } + + return 0 +} + +// AsUnixDirPermission return the corresponding unix permission for a regular file. +func (perm FSPermission) AsUnixFilePermission() fs.FileMode { + switch perm { + case AdminOnlyPermission: + return 0o600 + case PublicReadPermission: + return 0o655 + case PublicWritePermission: + return 0o666 + } + + return 0 +} + // DirStructure represents a directory structure with permissions that should be enforced. type DirStructure struct { sync.Mutex Path string Dir string - Perm os.FileMode + Perm FSPermission Parent *DirStructure Children map[string]*DirStructure } // NewDirStructure returns a new DirStructure. -func NewDirStructure(path string, perm os.FileMode) *DirStructure { +func NewDirStructure(path string, perm FSPermission) *DirStructure { return &DirStructure{ Path: path, Perm: perm, @@ -29,7 +65,7 @@ func NewDirStructure(path string, perm os.FileMode) *DirStructure { } // ChildDir adds a new child DirStructure and returns it. Should the child already exist, the existing child is returned and the permissions are updated. -func (ds *DirStructure) ChildDir(dirName string, perm os.FileMode) (child *DirStructure) { +func (ds *DirStructure) ChildDir(dirName string, perm FSPermission) (child *DirStructure) { ds.Lock() defer ds.Unlock() diff --git a/cmds/portmaster-start/dirs.go b/cmds/portmaster-start/dirs.go index e327963f..a95c500b 100644 --- a/cmds/portmaster-start/dirs.go +++ b/cmds/portmaster-start/dirs.go @@ -5,6 +5,7 @@ import ( "log" "os" + "github.com/safing/portmaster/base/utils" "github.com/spf13/cobra" ) @@ -24,7 +25,7 @@ var cleanStructureCmd = &cobra.Command{ } func cleanAndEnsureExecDir() error { - execDir := dataRoot.ChildDir("exec", 0o777) + execDir := dataRoot.ChildDir("exec", utils.PublicWritePermission) // Clean up and remove exec dir. err := os.RemoveAll(execDir.Path) diff --git a/cmds/portmaster-start/main.go b/cmds/portmaster-start/main.go index f764dfbf..d13a4bd6 100644 --- a/cmds/portmaster-start/main.go +++ b/cmds/portmaster-start/main.go @@ -179,14 +179,14 @@ func configureRegistry(mustLoadIndex bool) error { // Remove left over quotes. dataDir = strings.Trim(dataDir, `\"`) // Initialize data root. - err := dataroot.Initialize(dataDir, 0o0755) + err := dataroot.Initialize(dataDir, utils.PublicReadPermission) if err != nil { return fmt.Errorf("failed to initialize data root: %w", err) } dataRoot = dataroot.Root() // Initialize registry. - err = registry.Initialize(dataRoot.ChildDir("updates", 0o0755)) + err = registry.Initialize(dataRoot.ChildDir("updates", utils.PublicReadPermission)) if err != nil { return err } @@ -196,7 +196,7 @@ func configureRegistry(mustLoadIndex bool) error { func ensureLoggingDir() error { // set up logs root - logsRoot = dataRoot.ChildDir("logs", 0o0777) + logsRoot = dataRoot.ChildDir("logs", utils.PublicWritePermission) err := logsRoot.Ensure() if err != nil { return fmt.Errorf("failed to initialize logs root (%q): %w", logsRoot.Path, err) diff --git a/service/core/base/global.go b/service/core/base/global.go index 3b1cc82f..fa67048f 100644 --- a/service/core/base/global.go +++ b/service/core/base/global.go @@ -8,6 +8,7 @@ import ( "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/dataroot" "github.com/safing/portmaster/base/info" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/service/mgr" ) @@ -54,7 +55,7 @@ func prep(instance instance) error { } // initialize structure - err := dataroot.Initialize(dataDir, 0o0755) + err := dataroot.Initialize(dataDir, utils.PublicReadPermission) if err != nil { return err } diff --git a/service/netquery/database.go b/service/netquery/database.go index a1cd6aea..912fe3cc 100644 --- a/service/netquery/database.go +++ b/service/netquery/database.go @@ -19,6 +19,7 @@ import ( "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/dataroot" "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/service/netquery/orm" "github.com/safing/portmaster/service/network" "github.com/safing/portmaster/service/network/netutils" @@ -127,7 +128,7 @@ type ( // Note that write connections are serialized by the Database object before being // handed over to SQLite. func New(dbPath string) (*Database, error) { - historyParentDir := dataroot.Root().ChildDir("databases", 0o700) + historyParentDir := dataroot.Root().ChildDir("databases", utils.AdminOnlyPermission) if err := historyParentDir.Ensure(); err != nil { return nil, fmt.Errorf("failed to ensure database directory exists: %w", err) } @@ -225,7 +226,7 @@ func (db *Database) Close() error { // VacuumHistory rewrites the history database in order to purge deleted records. func VacuumHistory(ctx context.Context) (err error) { - historyParentDir := dataroot.Root().ChildDir("databases", 0o700) + historyParentDir := dataroot.Root().ChildDir("databases", utils.AdminOnlyPermission) if err := historyParentDir.Ensure(); err != nil { return fmt.Errorf("failed to ensure database directory exists: %w", err) } diff --git a/service/profile/module.go b/service/profile/module.go index 911ef99c..652fcd52 100644 --- a/service/profile/module.go +++ b/service/profile/module.go @@ -11,6 +11,7 @@ import ( "github.com/safing/portmaster/base/database/migration" "github.com/safing/portmaster/base/dataroot" "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/base/utils" _ "github.com/safing/portmaster/service/core/base" "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/profile/binmeta" @@ -70,7 +71,7 @@ func prep() error { } // Setup icon storage location. - iconsDir := dataroot.Root().ChildDir("databases", 0o0700).ChildDir("icons", 0o0700) + iconsDir := dataroot.Root().ChildDir("databases", utils.AdminOnlyPermission).ChildDir("icons", utils.AdminOnlyPermission) if err := iconsDir.Ensure(); err != nil { return fmt.Errorf("failed to create/check icons directory: %w", err) } diff --git a/service/ui/module.go b/service/ui/module.go index 630808e5..b9f7220f 100644 --- a/service/ui/module.go +++ b/service/ui/module.go @@ -7,6 +7,7 @@ import ( "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/dataroot" "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/service/mgr" ) @@ -27,7 +28,7 @@ func start() error { // may seem dangerous, but proper permission on the parent directory provide // (some) protection. // Processes must _never_ read from this directory. - err := dataroot.Root().ChildDir("exec", 0o0777).Ensure() + err := dataroot.Root().ChildDir("exec", utils.PublicWritePermission).Ensure() if err != nil { log.Warningf("ui: failed to create safe exec dir: %s", err) } diff --git a/service/updates/main.go b/service/updates/main.go index bb942993..c5a41d43 100644 --- a/service/updates/main.go +++ b/service/updates/main.go @@ -13,6 +13,7 @@ import ( "github.com/safing/portmaster/base/dataroot" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/updater" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/updates/helper" ) @@ -138,7 +139,7 @@ func start() error { } // initialize - err = registry.Initialize(dataroot.Root().ChildDir(updatesDirName, 0o0755)) + err = registry.Initialize(dataroot.Root().ChildDir(updatesDirName, utils.PublicReadPermission)) if err != nil { return err } diff --git a/service/updates/upgrader.go b/service/updates/upgrader.go index 4963bced..f1d3c297 100644 --- a/service/updates/upgrader.go +++ b/service/updates/upgrader.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/hectane/go-acl" processInfo "github.com/shirou/gopsutil/process" "github.com/tevino/abool" @@ -21,6 +20,7 @@ import ( "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/base/rng" "github.com/safing/portmaster/base/updater" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/base/utils/renameio" "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/updates/helper" @@ -351,17 +351,15 @@ func upgradeBinary(fileToUpgrade string, file *updater.File) error { // check permissions if onWindows { - err = acl.Chmod(fileToUpgrade, 0o0755) - if err != nil { - return fmt.Errorf("failed to set permissions on %s: %w", fileToUpgrade, err) - } + utils.SetExecPermission(fileToUpgrade, utils.PublicReadPermission) } else { + perm := utils.PublicReadPermission info, err := os.Stat(fileToUpgrade) if err != nil { return fmt.Errorf("failed to get file info on %s: %w", fileToUpgrade, err) } - if info.Mode() != 0o0755 { - err := os.Chmod(fileToUpgrade, 0o0755) //nolint:gosec // Set execute permissions. + if info.Mode() != perm.AsUnixDirExecPermission() { + err = utils.SetExecPermission(fileToUpgrade, perm) if err != nil { return fmt.Errorf("failed to set permissions on %s: %w", fileToUpgrade, err) } From 05a5d5e350c57b2a047a2d5c1db5d1a8c90eef82 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Fri, 6 Dec 2024 13:28:24 +0200 Subject: [PATCH 36/63] [service] Fix unit tests --- base/database/storage/fstree/fstree.go | 1 - base/updater/registry.go | 5 ----- base/updater/registry_test.go | 2 +- base/utils/fs.go | 11 ++++++----- base/utils/permissions_windows.go | 3 +++ base/utils/structure.go | 6 +++--- base/utils/structure_test.go | 26 +++++++++++++------------- cmds/notifier/main.go | 4 ++-- cmds/updatemgr/main.go | 2 +- cmds/updatemgr/release.go | 3 ++- service/updates/upgrader.go | 2 +- 11 files changed, 32 insertions(+), 33 deletions(-) diff --git a/base/database/storage/fstree/fstree.go b/base/database/storage/fstree/fstree.go index 0b4f175c..4b04f41d 100644 --- a/base/database/storage/fstree/fstree.go +++ b/base/database/storage/fstree/fstree.go @@ -15,7 +15,6 @@ import ( "strings" "time" - "github.com/hectane/go-acl" "github.com/safing/portmaster/base/database/iterator" "github.com/safing/portmaster/base/database/query" "github.com/safing/portmaster/base/database/record" diff --git a/base/updater/registry.go b/base/updater/registry.go index 4450fe98..a2bf5fcd 100644 --- a/base/updater/registry.go +++ b/base/updater/registry.go @@ -5,7 +5,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "strings" "sync" @@ -13,10 +12,6 @@ import ( "github.com/safing/portmaster/base/utils" ) -const ( - onWindows = runtime.GOOS == "windows" -) - // ResourceRegistry is a registry for managing update resources. type ResourceRegistry struct { sync.RWMutex diff --git a/base/updater/registry_test.go b/base/updater/registry_test.go index a8978f68..1b409b25 100644 --- a/base/updater/registry_test.go +++ b/base/updater/registry_test.go @@ -20,7 +20,7 @@ func TestMain(m *testing.M) { DevMode: true, Online: true, } - err = registry.Initialize(utils.NewDirStructure(tmpDir, 0o0777)) + err = registry.Initialize(utils.NewDirStructure(tmpDir, utils.PublicWritePermission)) if err != nil { panic(err) } diff --git a/base/utils/fs.go b/base/utils/fs.go index 6ede989d..5eb456b1 100644 --- a/base/utils/fs.go +++ b/base/utils/fs.go @@ -21,7 +21,7 @@ func EnsureDirectory(path string, perm FSPermission) error { // directory exists, check permissions if isWindows { // Ignore windows permission error. For none admin users it will always fail. - SetDirPermission(path, perm) + _ = SetDirPermission(path, perm) return nil } else if f.Mode().Perm() != perm.AsUnixDirExecPermission() { return SetDirPermission(path, perm) @@ -39,10 +39,11 @@ func EnsureDirectory(path string, perm FSPermission) error { if err != nil { return fmt.Errorf("could not create dir %s: %w", path, err) } - // Set windows permissions. Linux permission where already set with creation. - if isWindows { - // Ignore windows permission error. For none admin users it will always fail. - SetDirPermission(path, perm) + // Set permissions. + err = SetDirPermission(path, perm) + // Ignore windows permission error. For none admin users it will always fail. + if !isWindows { + return err } return nil } diff --git a/base/utils/permissions_windows.go b/base/utils/permissions_windows.go index ac48c21a..5f36ebb9 100644 --- a/base/utils/permissions_windows.go +++ b/base/utils/permissions_windows.go @@ -32,4 +32,7 @@ func setWindowsFilePermissions(path string, perm FSPermission) { acl.Apply(path, true, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Administrators")) acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Users")) } + + // For completeness + acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "SYSTEM")) } diff --git a/base/utils/structure.go b/base/utils/structure.go index e33a920f..8e1f0786 100644 --- a/base/utils/structure.go +++ b/base/utils/structure.go @@ -16,7 +16,7 @@ const ( PublicWritePermission ) -// AsUnixDirPermission return the corresponding unix permission for a directory or executable. +// AsUnixDirExecPermission return the corresponding unix permission for a directory or executable. func (perm FSPermission) AsUnixDirExecPermission() fs.FileMode { switch perm { case AdminOnlyPermission: @@ -30,13 +30,13 @@ func (perm FSPermission) AsUnixDirExecPermission() fs.FileMode { return 0 } -// AsUnixDirPermission return the corresponding unix permission for a regular file. +// AsUnixFilePermission return the corresponding unix permission for a regular file. func (perm FSPermission) AsUnixFilePermission() fs.FileMode { switch perm { case AdminOnlyPermission: return 0o600 case PublicReadPermission: - return 0o655 + return 0o644 case PublicWritePermission: return 0o666 } diff --git a/base/utils/structure_test.go b/base/utils/structure_test.go index 2acfebd2..d3debcf7 100644 --- a/base/utils/structure_test.go +++ b/base/utils/structure_test.go @@ -13,13 +13,13 @@ func ExampleDirStructure() { // output: // / [755] // /repo [777] - // /repo/b [707] - // /repo/b/c [750] - // /repo/b/d [707] - // /repo/b/d/e [707] - // /repo/b/d/f [707] - // /repo/b/d/f/g [707] - // /repo/b/d/f/g/h [707] + // /repo/b [755] + // /repo/b/c [777] + // /repo/b/d [755] + // /repo/b/d/e [755] + // /repo/b/d/f [755] + // /repo/b/d/f/g [755] + // /repo/b/d/f/g/h [755] // /secret [700] basePath, err := os.MkdirTemp("", "") @@ -28,12 +28,12 @@ func ExampleDirStructure() { return } - ds := NewDirStructure(basePath, 0o0755) - secret := ds.ChildDir("secret", 0o0700) - repo := ds.ChildDir("repo", 0o0777) - _ = repo.ChildDir("a", 0o0700) - b := repo.ChildDir("b", 0o0707) - c := b.ChildDir("c", 0o0750) + ds := NewDirStructure(basePath, PublicReadPermission) + secret := ds.ChildDir("secret", AdminOnlyPermission) + repo := ds.ChildDir("repo", PublicWritePermission) + _ = repo.ChildDir("a", AdminOnlyPermission) + b := repo.ChildDir("b", PublicReadPermission) + c := b.ChildDir("c", PublicWritePermission) err = ds.Ensure() if err != nil { diff --git a/cmds/notifier/main.go b/cmds/notifier/main.go index e40487bb..a11bea2a 100644 --- a/cmds/notifier/main.go +++ b/cmds/notifier/main.go @@ -225,14 +225,14 @@ func configureRegistry(mustLoadIndex bool) error { // Remove left over quotes. dataDir = strings.Trim(dataDir, `\"`) // Initialize data root. - err := dataroot.Initialize(dataDir, 0o0755) + err := dataroot.Initialize(dataDir, utils.PublicReadPermission) if err != nil { return fmt.Errorf("failed to initialize data root: %w", err) } dataRoot = dataroot.Root() // Initialize registry. - err = registry.Initialize(dataRoot.ChildDir("updates", 0o0755)) + err = registry.Initialize(dataRoot.ChildDir("updates", utils.PublicReadPermission)) if err != nil { return err } diff --git a/cmds/updatemgr/main.go b/cmds/updatemgr/main.go index acd9a0d4..4a999f49 100644 --- a/cmds/updatemgr/main.go +++ b/cmds/updatemgr/main.go @@ -31,7 +31,7 @@ var rootCmd = &cobra.Command{ } registry = &updater.ResourceRegistry{} - err = registry.Initialize(utils.NewDirStructure(absDistPath, 0o0755)) + err = registry.Initialize(utils.NewDirStructure(absDistPath, utils.PublicReadPermission)) if err != nil { return err } diff --git a/cmds/updatemgr/release.go b/cmds/updatemgr/release.go index 0f5d596e..e6642a63 100644 --- a/cmds/updatemgr/release.go +++ b/cmds/updatemgr/release.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/cobra" "github.com/safing/portmaster/base/updater" + "github.com/safing/portmaster/base/utils" ) var ( @@ -63,7 +64,7 @@ func release(cmd *cobra.Command, args []string) error { fmt.Println("aborted...") return nil } - symlinksDir := registry.StorageDir().ChildDir("latest", 0o755) + symlinksDir := registry.StorageDir().ChildDir("latest", utils.PublicReadPermission) err = registry.CreateSymlinks(symlinksDir) if err != nil { return err diff --git a/service/updates/upgrader.go b/service/updates/upgrader.go index f1d3c297..b07d649e 100644 --- a/service/updates/upgrader.go +++ b/service/updates/upgrader.go @@ -351,7 +351,7 @@ func upgradeBinary(fileToUpgrade string, file *updater.File) error { // check permissions if onWindows { - utils.SetExecPermission(fileToUpgrade, utils.PublicReadPermission) + _ = utils.SetExecPermission(fileToUpgrade, utils.PublicReadPermission) } else { perm := utils.PublicReadPermission info, err := os.Stat(fileToUpgrade) From 9d874daed2ff360e016821fc4da0a09ae5eef536 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 6 Dec 2024 14:34:54 +0100 Subject: [PATCH 37/63] Simplify windows acl calls and switch to using SIDs --- base/utils/permissions_windows.go | 63 +++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/base/utils/permissions_windows.go b/base/utils/permissions_windows.go index 5f36ebb9..47aa0c26 100644 --- a/base/utils/permissions_windows.go +++ b/base/utils/permissions_windows.go @@ -7,32 +7,71 @@ import ( "golang.org/x/sys/windows" ) +var ( + systemSID *windows.SID + adminsSID *windows.SID + usersSID *windows.SID +) + +func init() { + var err error + systemSID, err = windows.StringToSid("S-1-5") // NT Authority / SYSTEM + if err != nil { + panic(err) + } + adminsSID, err = windows.StringToSid("S-1-5-32-544") // Administrators + if err != nil { + panic(err) + } + usersSID, err = windows.StringToSid("S-1-5-32-545") // Users + if err != nil { + panic(err) + } +} + +// SetDirPermission sets the permission of a directory. func SetDirPermission(path string, perm FSPermission) error { - setWindowsFilePermissions(path, perm) + SetFilePermission(path, perm) return nil } // SetExecPermission sets the permission of an executable file. func SetExecPermission(path string, perm FSPermission) error { - return SetDirPermission(path, perm) + SetFilePermission(path, perm) + return nil } -func setWindowsFilePermissions(path string, perm FSPermission) { +// SetFilePermission sets the permission of a non executable file. +func SetFilePermission(path string, perm FSPermission) { switch perm { case AdminOnlyPermission: // Set only admin rights, remove all others. - acl.Apply(path, true, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Administrators")) + acl.Apply( + path, + true, + false, + acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID), + acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID), + ) case PublicReadPermission: // Set admin rights and read/execute rights for users, remove all others. - acl.Apply(path, true, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Administrators")) - acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_EXECUTE, "Users")) - acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_READ, "Users")) + acl.Apply( + path, + true, + false, + acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID), + acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID), + acl.GrantSid(windows.GENERIC_READ|windows.GENERIC_EXECUTE, usersSID), + ) case PublicWritePermission: // Set full control to admin and regular users. Guest users will not have access. - acl.Apply(path, true, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Administrators")) - acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "Users")) + acl.Apply( + path, + true, + false, + acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID), + acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID), + acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, usersSID), + ) } - - // For completeness - acl.Apply(path, false, false, acl.GrantName(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, "SYSTEM")) } From 475d69f8a241f52e3c082a4a6f98a3fcabf89d19 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Fri, 6 Dec 2024 16:45:37 +0200 Subject: [PATCH 38/63] [service] Fix windows system SID --- base/utils/permissions_windows.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/utils/permissions_windows.go b/base/utils/permissions_windows.go index 47aa0c26..13cbf583 100644 --- a/base/utils/permissions_windows.go +++ b/base/utils/permissions_windows.go @@ -14,8 +14,10 @@ var ( ) func init() { + // Initialize Security ID for all need groups. + // Reference: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers var err error - systemSID, err = windows.StringToSid("S-1-5") // NT Authority / SYSTEM + systemSID, err = windows.StringToSid("S-1-5-18") // SYSTEM (Local System) if err != nil { panic(err) } From 5713d7d3c6e443298dda40417fa5e7fc00785f15 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 9 Dec 2024 18:11:00 +0200 Subject: [PATCH 39/63] Make eartly local only build --- .earthlyignore | 6 +++--- Earthfile | 40 ++++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/.earthlyignore b/.earthlyignore index 8953460f..d1dc7512 100644 --- a/.earthlyignore +++ b/.earthlyignore @@ -12,11 +12,11 @@ desktop/tauri/src-tauri/target # Copy from .gitignore: # Compiled binaries -*.exe -dist/ +# *.exe +# dist/ # Dist dir -dist +# dist # Custom dev deops go.mod.* diff --git a/Earthfile b/Earthfile index aaa60d87..977c0837 100644 --- a/Earthfile +++ b/Earthfile @@ -512,6 +512,9 @@ tauri-lint: release-prep: FROM +rust-base + WORKDIR /app + COPY ./dist ./dist + # Linux specific COPY (+tauri-build/output/portmaster --target="x86_64-unknown-linux-gnu") ./output/binary/linux_amd64/portmaster COPY (+go-build/output/portmaster-core --GOARCH=amd64 --GOOS=linux --CMDS=portmaster-core) ./output/binary/linux_amd64/portmaster-core @@ -520,44 +523,45 @@ release-prep: COPY (+tauri-build/output/portmaster.exe --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/portmaster.exe COPY (+tauri-build/output/WebView2Loader.dll --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/WebView2Loader.dll COPY (+go-build/output/portmaster-core.exe --GOARCH=amd64 --GOOS=windows --CMDS=portmaster-core) ./output/binary/windows_amd64/portmaster-core.exe - # TODO(vladimir): figure out a way to get the lastest release of the kext and dll. - RUN wget -O ./output/binary/windows_amd64/portmaster-kext.sys https://updates.safing.io/windows_amd64/kext/portmaster-kext_v2-0-4.sys - RUN touch ./output/binary/windows_amd64/portmaster-core.dll + # TODO(vladimir): figure out a way to get the lastest release of the kext and the dll. + RUN cp "${outputDir}/windows_amd64/portmaster-kext.sys" ./output/binary/windows_amd64/portmaster-kext.sys + RUN cp "${outputDir}/windows_amd64/portmaster-core.dll" ./output/binary/windows_amd64/portmaster-core.dll # All platforms COPY (+assets/assets.zip) ./output/binary/all/assets.zip COPY (+angular-project/output/portmaster.zip --project=portmaster --dist=./dist --configuration=production --baseHref=/ui/modules/portmaster/) ./output/binary/all/portmaster.zip # Intel - # TODO(vladimir): figure out a way to download all latest intel data. + # TODO(vladimir): figure out a way to download all the latest intel data. RUN mkdir -p ./output/intel - RUN wget -O ./output/intel/geoipv4.mmdb.gz "https://updates.safing.io/all/intel/geoip/geoipv4_v20240820-0-1.mmdb.gz" && \ - wget -O ./output/intel/geoipv6.mmdb.gz "https://updates.safing.io/all/intel/geoip/geoipv6_v20240820-0-1.mmdb.gz" && \ - wget -O ./output/intel/index.dsd "https://updates.safing.io/all/intel/lists/index_v2023-6-13.dsd" && \ - wget -O ./output/intel/base.dsdl "https://updates.safing.io/all/intel/lists/base_v20241001-0-9.dsdl" && \ - wget -O ./output/intel/intermediate.dsdl "https://updates.safing.io/all/intel/lists/intermediate_v20240929-0-0.dsdl" && \ - wget -O ./output/intel/urgent.dsdl "https://updates.safing.io/all/intel/lists/urgent_v20241002-2-14.dsdl" + RUN cp "${outputDir}/intel/geoipv4.mmdb.gz" ./output/intel/geoipv4.mmdb.gz + RUN cp "${outputDir}/intel/geoipv6.mmdb.gz" ./output/intel/geoipv6.mmdb.gz + RUN cp "${outputDir}/intel/index.dsd" ./output/intel/index.dsd + RUN cp "${outputDir}/intel/base.dsdl" ./output/intel/base.dsdl + RUN cp "${outputDir}/intel/intermediate.dsdl" ./output/intel/intermediate.dsdl + RUN cp "${outputDir}/intel/urgent.dsdl" ./output/intel/urgent.dsdl + # Genereate index files COPY (+go-build/output/updatemgr --GOARCH=amd64 --GOOS=linux --CMDS=updatemgr) ./updatemgr RUN ./updatemgr scan --dir "./output/binary" > ./output/binary/index.json RUN ./updatemgr scan --dir "./output/intel" > ./output/intel/index.json # Intel Extracted (needed for the installers) RUN mkdir -p ./output/intel_decompressed - RUN cp ./output/intel/index.json ./output/intel_decompressed/index.json - RUN gzip -dc ./output/intel/geoipv4.mmdb.gz > ./output/intel_decompressed/geoipv4.mmdb - RUN gzip -dc ./output/intel/geoipv6.mmdb.gz > ./output/intel_decompressed/geoipv6.mmdb - RUN cp ./output/intel/index.dsd ./output/intel_decompressed/index.dsd - RUN cp ./output/intel/base.dsdl ./output/intel_decompressed/base.dsdl - RUN cp ./output/intel/intermediate.dsdl ./output/intel_decompressed/intermediate.dsdl - RUN cp ./output/intel/urgent.dsdl ./output/intel_decompressed/urgent.dsdl + RUN cp ${outputDir}/intel/index.json ./output/intel_decompressed/index.json + RUN gzip -dc ${outputDir}/intel/geoipv4.mmdb.gz > ./output/intel_decompressed/geoipv4.mmdb + RUN gzip -dc ./${outputDir}/intel/geoipv6.mmdb.gz > ./output/intel_decompressed/geoipv6.mmdb + RUN cp ${outputDir}/intel/index.dsd ./output/intel_decompressed/index.dsd + RUN cp ${outputDir}/intel/base.dsdl ./output/intel_decompressed/base.dsdl + RUN cp ${outputDir}/intel/intermediate.dsdl ./output/intel_decompressed/intermediate.dsdl + RUN cp ${outputDir}/intel/urgent.dsdl ./output/intel_decompressed/urgent.dsdl # Save all artifacts to output folder SAVE ARTIFACT --if-exists --keep-ts "output/binary/index.json" AS LOCAL "${outputDir}/binary/index.json" SAVE ARTIFACT --if-exists --keep-ts "output/binary/all/*" AS LOCAL "${outputDir}/binary/all/" SAVE ARTIFACT --if-exists --keep-ts "output/binary/linux_amd64/*" AS LOCAL "${outputDir}/binary/linux_amd64/" SAVE ARTIFACT --if-exists --keep-ts "output/binary/windows_amd64/*" AS LOCAL "${outputDir}/binary/windows_amd64/" - SAVE ARTIFACT --if-exists --keep-ts "output/intel/*" AS LOCAL "${outputDir}/intel/" + # SAVE ARTIFACT --if-exists --keep-ts "output/intel/*" AS LOCAL "${outputDir}/intel/" SAVE ARTIFACT --if-exists --keep-ts "output/intel_decompressed/*" AS LOCAL "${outputDir}/intel_decompressed/" # Save all artifacts to the container output folder so other containers can access it. From 3101d0a7aa072803773decba582bdbc2d3b20892 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 10 Dec 2024 13:46:31 +0200 Subject: [PATCH 40/63] Fix windows installers --- .golangci.yml | 1 - desktop/tauri/src-tauri/templates/files.wxs | 2 ++ desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh | 2 ++ service/profile/config-update.go | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 12967f60..3d333669 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -24,7 +24,6 @@ linters: - interfacer - ireturn - lll - - mnd - musttag - nestif - nilnil diff --git a/desktop/tauri/src-tauri/templates/files.wxs b/desktop/tauri/src-tauri/templates/files.wxs index 8623e435..14159aa8 100644 --- a/desktop/tauri/src-tauri/templates/files.wxs +++ b/desktop/tauri/src-tauri/templates/files.wxs @@ -14,7 +14,9 @@ + + diff --git a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh index 79bc1218..5d08c799 100644 --- a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh +++ b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh @@ -6,6 +6,8 @@ File "..\..\..\..\binary\index.json" File "..\..\..\..\binary\portmaster-core.exe" File "..\..\..\..\binary\portmaster-kext.sys" + File "..\..\..\..\binary\portmaster-core.dll" + File "..\..\..\..\binary\WebView2Loader.dll" File "..\..\..\..\binary\portmaster.zip" File "..\..\..\..\binary\assets.zip" diff --git a/service/profile/config-update.go b/service/profile/config-update.go index f3e8161c..d958e307 100644 --- a/service/profile/config-update.go +++ b/service/profile/config-update.go @@ -143,7 +143,7 @@ func updateGlobalConfigProfile(_ context.Context) error { module.states.Add(mgr.State{ ID: globalConfigProfileErrorID, Name: "Internal Settings Failure", - Message: fmt.Sprintf("Some global settings might not be applied correctly. You can try restarting the Portmaster to resolve this problem. Error: %s", err), + Message: fmt.Sprintf("Some global settings might not be applied correctly. You can try restarting the Portmaster to resolve this problem. Error: %s", lastErr), Type: mgr.StateTypeWarning, }) } From be62c788de323fe65fe28a41486b32b1da5c502a Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 10 Dec 2024 14:20:48 +0200 Subject: [PATCH 41/63] Improve earthfile --- .golangci.yml | 1 + Earthfile | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 3d333669..12967f60 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -24,6 +24,7 @@ linters: - interfacer - ireturn - lll + - mnd - musttag - nestif - nilnil diff --git a/Earthfile b/Earthfile index 977c0837..e2de6900 100644 --- a/Earthfile +++ b/Earthfile @@ -513,7 +513,8 @@ release-prep: FROM +rust-base WORKDIR /app - COPY ./dist ./dist + COPY ./dist/intel ./dist/intel + COPY ./dist/windows_amd64 ./dist/windows_amd64 # Linux specific COPY (+tauri-build/output/portmaster --target="x86_64-unknown-linux-gnu") ./output/binary/linux_amd64/portmaster @@ -523,23 +524,21 @@ release-prep: COPY (+tauri-build/output/portmaster.exe --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/portmaster.exe COPY (+tauri-build/output/WebView2Loader.dll --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/WebView2Loader.dll COPY (+go-build/output/portmaster-core.exe --GOARCH=amd64 --GOOS=windows --CMDS=portmaster-core) ./output/binary/windows_amd64/portmaster-core.exe - # TODO(vladimir): figure out a way to get the lastest release of the kext and the dll. - RUN cp "${outputDir}/windows_amd64/portmaster-kext.sys" ./output/binary/windows_amd64/portmaster-kext.sys - RUN cp "${outputDir}/windows_amd64/portmaster-core.dll" ./output/binary/windows_amd64/portmaster-core.dll + RUN cp dist/windows_amd64/portmaster-kext.sys ./output/binary/windows_amd64/portmaster-kext.sys + RUN cp dist/windows_amd64/portmaster-core.dll ./output/binary/windows_amd64/portmaster-core.dll # All platforms COPY (+assets/assets.zip) ./output/binary/all/assets.zip COPY (+angular-project/output/portmaster.zip --project=portmaster --dist=./dist --configuration=production --baseHref=/ui/modules/portmaster/) ./output/binary/all/portmaster.zip # Intel - # TODO(vladimir): figure out a way to download all the latest intel data. RUN mkdir -p ./output/intel - RUN cp "${outputDir}/intel/geoipv4.mmdb.gz" ./output/intel/geoipv4.mmdb.gz - RUN cp "${outputDir}/intel/geoipv6.mmdb.gz" ./output/intel/geoipv6.mmdb.gz - RUN cp "${outputDir}/intel/index.dsd" ./output/intel/index.dsd - RUN cp "${outputDir}/intel/base.dsdl" ./output/intel/base.dsdl - RUN cp "${outputDir}/intel/intermediate.dsdl" ./output/intel/intermediate.dsdl - RUN cp "${outputDir}/intel/urgent.dsdl" ./output/intel/urgent.dsdl + RUN cp "dist/intel/geoipv4.mmdb.gz" ./output/intel/geoipv4.mmdb.gz + RUN cp "dist/intel/geoipv6.mmdb.gz" ./output/intel/geoipv6.mmdb.gz + RUN cp "dist/intel/index.dsd" ./output/intel/index.dsd + RUN cp "dist/intel/base.dsdl" ./output/intel/base.dsdl + RUN cp "dist/intel/intermediate.dsdl" ./output/intel/intermediate.dsdl + RUN cp "dist/intel/urgent.dsdl" ./output/intel/urgent.dsdl # Genereate index files COPY (+go-build/output/updatemgr --GOARCH=amd64 --GOOS=linux --CMDS=updatemgr) ./updatemgr @@ -548,13 +547,14 @@ release-prep: # Intel Extracted (needed for the installers) RUN mkdir -p ./output/intel_decompressed - RUN cp ${outputDir}/intel/index.json ./output/intel_decompressed/index.json - RUN gzip -dc ${outputDir}/intel/geoipv4.mmdb.gz > ./output/intel_decompressed/geoipv4.mmdb - RUN gzip -dc ./${outputDir}/intel/geoipv6.mmdb.gz > ./output/intel_decompressed/geoipv6.mmdb - RUN cp ${outputDir}/intel/index.dsd ./output/intel_decompressed/index.dsd - RUN cp ${outputDir}/intel/base.dsdl ./output/intel_decompressed/base.dsdl - RUN cp ${outputDir}/intel/intermediate.dsdl ./output/intel_decompressed/intermediate.dsdl - RUN cp ${outputDir}/intel/urgent.dsdl ./output/intel_decompressed/urgent.dsdl + RUN cp output/intel/index.json ./output/intel_decompressed/index.json + + RUN gzip -dc dist/intel/geoipv4.mmdb.gz > ./output/intel_decompressed/geoipv4.mmdb + RUN gzip -dc dist/intel/geoipv6.mmdb.gz > ./output/intel_decompressed/geoipv6.mmdb + RUN cp dist/intel/index.dsd ./output/intel_decompressed/index.dsd + RUN cp dist/intel/base.dsdl ./output/intel_decompressed/base.dsdl + RUN cp dist/intel/intermediate.dsdl ./output/intel_decompressed/intermediate.dsdl + RUN cp dist/intel/urgent.dsdl ./output/intel_decompressed/urgent.dsdl # Save all artifacts to output folder SAVE ARTIFACT --if-exists --keep-ts "output/binary/index.json" AS LOCAL "${outputDir}/binary/index.json" From c21a93a4d6589225fc8ed71b7b7cf84c1dca7c39 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 10 Dec 2024 14:21:34 +0200 Subject: [PATCH 42/63] Add missing TODOs --- desktop/tauri/src-tauri/src/main.rs | 1 + service/intel/filterlists/index.go | 3 +++ 2 files changed, 4 insertions(+) diff --git a/desktop/tauri/src-tauri/src/main.rs b/desktop/tauri/src-tauri/src/main.rs index 411d4579..360aee63 100644 --- a/desktop/tauri/src-tauri/src/main.rs +++ b/desktop/tauri/src-tauri/src/main.rs @@ -126,6 +126,7 @@ fn main() { let cli_args = cli::parse(std::env::args()); + // TODO(vladimir): Support for other log targets? #[cfg(target_os = "linux")] let log_target = tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Stdout); // let log_target = if let Some(data_dir) = cli_args.data { diff --git a/service/intel/filterlists/index.go b/service/intel/filterlists/index.go index 15055e3b..8b18254b 100644 --- a/service/intel/filterlists/index.go +++ b/service/intel/filterlists/index.go @@ -182,11 +182,13 @@ func updateListIndex() error { // Check if the version in the cache is current. _, err = getListIndexFromCache() + // index, err = getListIndexFromCache() switch { case errors.Is(err, database.ErrNotFound): log.Info("filterlists: index not in cache, starting update") case err != nil: log.Warningf("filterlists: failed to load index from cache, starting update: %s", err) + // TODO(vladimir): Change so it fits the new updater // case !listIndexUpdate.EqualsVersion(strings.TrimPrefix(index.Version, "v")): // log.Infof( // "filterlists: index from cache is outdated, starting update (%s != %s)", @@ -238,6 +240,7 @@ func updateListIndex() error { func ResolveListIDs(ids []string) ([]string, error) { index, err := getListIndexFromCache() if err != nil { + // FIXME(vladimir): Fix the stack overflow bug // if errors.Is(err, database.ErrNotFound) { // if err := updateListIndex(); err != nil { // return nil, err From b3c867efc6855b99db561fe995a9737804e0cb62 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Wed, 11 Dec 2024 16:12:31 +0200 Subject: [PATCH 43/63] Fix stack overflow bug --- service/intel/filterlists/index.go | 45 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/service/intel/filterlists/index.go b/service/intel/filterlists/index.go index 8b18254b..8293f84c 100644 --- a/service/intel/filterlists/index.go +++ b/service/intel/filterlists/index.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "strings" "sync" "github.com/safing/portmaster/base/database" @@ -181,20 +182,18 @@ func updateListIndex() error { } // Check if the version in the cache is current. - _, err = getListIndexFromCache() - // index, err = getListIndexFromCache() + index, err := getListIndexFromCache() switch { case errors.Is(err, database.ErrNotFound): log.Info("filterlists: index not in cache, starting update") case err != nil: log.Warningf("filterlists: failed to load index from cache, starting update: %s", err) - // TODO(vladimir): Change so it fits the new updater - // case !listIndexUpdate.EqualsVersion(strings.TrimPrefix(index.Version, "v")): - // log.Infof( - // "filterlists: index from cache is outdated, starting update (%s != %s)", - // strings.TrimPrefix(index.Version, "v"), - // listIndexUpdate.Version(), - // ) + case listIndexUpdate.Version != strings.TrimPrefix(index.Version, "v"): + log.Infof( + "filterlists: index from cache is outdated, starting update (%s != %s)", + strings.TrimPrefix(index.Version, "v"), + listIndexUpdate.Version, + ) default: // List is in cache and current, there is nothing to do. log.Debug("filterlists: index is up to date") @@ -204,8 +203,6 @@ func updateListIndex() error { return nil } - // case listIndexUpdate.UpgradeAvailable(): - // log.Info("filterlists: index update available, starting update") default: // Index is loaded and no update is available, there is nothing to do. return nil @@ -238,20 +235,22 @@ func updateListIndex() error { // ResolveListIDs resolves a slice of source or category IDs into // a slice of distinct source IDs. func ResolveListIDs(ids []string) ([]string, error) { + // Try get the list index, err := getListIndexFromCache() if err != nil { - // FIXME(vladimir): Fix the stack overflow bug - // if errors.Is(err, database.ErrNotFound) { - // if err := updateListIndex(); err != nil { - // return nil, err - // } - - // // retry resolving IDs - // return ResolveListIDs(ids) - // } - - log.Errorf("failed to resolved ids %v: %s", ids, err) - return nil, err + if errors.Is(err, database.ErrNotFound) { + // Update the list index + if err = updateListIndex(); err != nil { + return nil, err + } + // Retry getting the list. + if index, err = getListIndexFromCache(); err != nil { + return nil, err + } + } else { + log.Errorf("failed to resolved ids %v: %s", ids, err) + return nil, err + } } resolved := index.getDistictSourceIDs(ids...) From 0997f1ce262dee7e3fca590f33445ec5049f429d Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Wed, 11 Dec 2024 16:13:06 +0200 Subject: [PATCH 44/63] Fix broadcast notifications --- service/broadcasts/data.go | 24 ++++++++++++------------ service/broadcasts/module.go | 4 ---- service/core/core.go | 1 - service/network/api.go | 1 - 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/service/broadcasts/data.go b/service/broadcasts/data.go index e92ce84f..b9a1a453 100644 --- a/service/broadcasts/data.go +++ b/service/broadcasts/data.go @@ -5,6 +5,7 @@ import ( "time" "github.com/safing/portmaster/base/config" + "github.com/safing/portmaster/service/core" "github.com/safing/portmaster/service/intel/geoip" "github.com/safing/portmaster/service/netenv" "github.com/safing/portmaster/spn/access" @@ -17,19 +18,18 @@ var portmasterStarted = time.Now() func collectData() interface{} { data := make(map[string]interface{}) - // TODO(vladimir) // Get data about versions. - // versions := updates.GetSimpleVersions() - // data["Updates"] = versions - // data["Version"] = versions.Build.Version - // numericVersion, err := MakeNumericVersion(versions.Build.Version) - // if err != nil { - // data["NumericVersion"] = &DataError{ - // Error: err, - // } - // } else { - // data["NumericVersion"] = numericVersion - // } + versions := core.GetSimpleVersions() + data["Updates"] = versions + data["Version"] = versions.Build.Version + numericVersion, err := MakeNumericVersion(versions.Build.Version) + if err != nil { + data["NumericVersion"] = &DataError{ + Error: err, + } + } else { + data["NumericVersion"] = numericVersion + } // Get data about install. installInfo, err := GetInstallInfo() diff --git a/service/broadcasts/module.go b/service/broadcasts/module.go index a9a87074..08324ef6 100644 --- a/service/broadcasts/module.go +++ b/service/broadcasts/module.go @@ -43,10 +43,6 @@ var ( startOnce sync.Once ) -func init() { - // module = modules.Register("broadcasts", prep, start, nil, "updates", "netenv", "notifications") -} - func prep() error { // Register API endpoints. if err := registerAPIEndpoints(); err != nil { diff --git a/service/core/core.go b/service/core/core.go index 48f262a1..3b433491 100644 --- a/service/core/core.go +++ b/service/core/core.go @@ -11,7 +11,6 @@ import ( "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/metrics" "github.com/safing/portmaster/base/utils/debug" - _ "github.com/safing/portmaster/service/broadcasts" "github.com/safing/portmaster/service/mgr" _ "github.com/safing/portmaster/service/netenv" _ "github.com/safing/portmaster/service/netquery" diff --git a/service/network/api.go b/service/network/api.go index 8af6eb26..5c18bcfd 100644 --- a/service/network/api.go +++ b/service/network/api.go @@ -93,7 +93,6 @@ func debugInfo(ar *api.Request) (data []byte, err error) { config.AddToDebugInfo(di) // Detailed information. - // TODO(vladimir): updates.AddToDebugInfo(di) // compat.AddToDebugInfo(di) // TODO: Cannot use due to interception import requirement which we don't want for SPN Hubs. di.AddGoroutineStack() From fed64e6fbd141ee1fd8a3db046de8034cf793c38 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Thu, 12 Dec 2024 16:33:02 +0200 Subject: [PATCH 45/63] Fix loggin dir --- cmds/portmaster-core/main.go | 2 +- desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh | 2 +- desktop/tauri/src-tauri/templates/service.wxs | 2 +- packaging/linux/portmaster.service | 2 +- service/core/base/module.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmds/portmaster-core/main.go b/cmds/portmaster-core/main.go index 12456f58..88f187a0 100644 --- a/cmds/portmaster-core/main.go +++ b/cmds/portmaster-core/main.go @@ -34,7 +34,7 @@ var ( ) func init() { - // Add persisent flags for all commands. + // Add persistent flags for all commands. rootCmd.PersistentFlags().StringVar(&binDir, "bin-dir", "", "set directory for executable binaries (rw/ro)") rootCmd.PersistentFlags().StringVar(&dataDir, "data-dir", "", "set directory for variable data (rw)") diff --git a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh index 5d08c799..cc6ea2f2 100644 --- a/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh +++ b/desktop/tauri/src-tauri/templates/nsis_install_hooks.nsh @@ -27,7 +27,7 @@ !macroend !macro NSIS_HOOK_POSTINSTALL - ExecWait 'sc.exe create PortmasterCore binPath= "$INSTDIR\portmaster-core.exe"' + ExecWait 'sc.exe create PortmasterCore binPath= "$INSTDIR\portmaster-core.exe --log-dir=%PROGRAMDATA%\Portmaster\logs"' !macroend !macro NSIS_HOOK_PREUNINSTALL diff --git a/desktop/tauri/src-tauri/templates/service.wxs b/desktop/tauri/src-tauri/templates/service.wxs index 28a035d5..3e829bd7 100644 --- a/desktop/tauri/src-tauri/templates/service.wxs +++ b/desktop/tauri/src-tauri/templates/service.wxs @@ -3,7 +3,7 @@ Date: Fri, 13 Dec 2024 17:02:38 +0200 Subject: [PATCH 46/63] [fix] Logical mistake while determining local resolvers --- service/resolver/resolvers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/resolver/resolvers.go b/service/resolver/resolvers.go index 45876b4e..6510036b 100644 --- a/service/resolver/resolvers.go +++ b/service/resolver/resolvers.go @@ -510,7 +510,7 @@ func setScopedResolvers(resolvers []*Resolver) { for _, resolver := range resolvers { if resolver.Info.IPScope.IsLAN() { localResolvers = append(localResolvers, resolver) - } else if _, err := netenv.GetLocalNetwork(resolver.Info.IP); err != nil { + } else if net, _ := netenv.GetLocalNetwork(resolver.Info.IP); net != nil { localResolvers = append(localResolvers, resolver) } From df70c70ab5b97081a34934881e5af50b49e3971c Mon Sep 17 00:00:00 2001 From: Alexandr Stelnykovych Date: Mon, 16 Dec 2024 16:01:42 +0200 Subject: [PATCH 47/63] [improvement] Small cache size (2 ^ 8) = (2 XOR 8) = 10. Was it intended to be 256? --- service/intel/filterlists/database.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/intel/filterlists/database.go b/service/intel/filterlists/database.go index 5f55323c..6de070bb 100644 --- a/service/intel/filterlists/database.go +++ b/service/intel/filterlists/database.go @@ -50,7 +50,7 @@ var ( var cache = database.NewInterface(&database.Options{ Local: true, Internal: true, - CacheSize: 2 ^ 8, + CacheSize: 256, }) // getFileFunc is the function used to get a file from From 6c014d227c0cbaea5fe1333b31ba5e9d57229f5e Mon Sep 17 00:00:00 2001 From: Alexandr Stelnykovych Date: Tue, 17 Dec 2024 15:49:52 +0200 Subject: [PATCH 48/63] [fix] Panic while accessing SleepyTicker methods Stop()/SetSleep() The time.Ticker object was stored as a value type, but it is expected to be a pointer according to its implementation: ``` func (t *Ticker) Stop() func (t *Ticker) Reset(d Duration) ``` This was leading to an application crash. STR 1: Run `portmaster-core` without privileged rights. It will not be able to start the kernel driver (Windows). During unloading of already initialized modules, the process crashes because of stopping SleepyTicker instances in workers of the "network" module. STR 2: Run tests from `service\mgr\sleepyticker_test.go` --- service/mgr/sleepyticker.go | 4 +-- service/mgr/sleepyticker_test.go | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 service/mgr/sleepyticker_test.go diff --git a/service/mgr/sleepyticker.go b/service/mgr/sleepyticker.go index 075912a1..ce0b20b4 100644 --- a/service/mgr/sleepyticker.go +++ b/service/mgr/sleepyticker.go @@ -4,7 +4,7 @@ import "time" // SleepyTicker is wrapper over time.Ticker that respects the sleep mode of the module. type SleepyTicker struct { - ticker time.Ticker + ticker *time.Ticker normalDuration time.Duration sleepDuration time.Duration sleepMode bool @@ -16,7 +16,7 @@ type SleepyTicker struct { // If sleepDuration is set to 0 ticker will not tick during sleep. func NewSleepyTicker(normalDuration time.Duration, sleepDuration time.Duration) *SleepyTicker { st := &SleepyTicker{ - ticker: *time.NewTicker(normalDuration), + ticker: time.NewTicker(normalDuration), normalDuration: normalDuration, sleepDuration: sleepDuration, sleepMode: false, diff --git a/service/mgr/sleepyticker_test.go b/service/mgr/sleepyticker_test.go new file mode 100644 index 00000000..9e2175c7 --- /dev/null +++ b/service/mgr/sleepyticker_test.go @@ -0,0 +1,57 @@ +package mgr + +import ( + "testing" + "time" +) + +func TestSleepyTickerStop(t *testing.T) { + normalDuration := 100 * time.Millisecond + sleepDuration := 200 * time.Millisecond + + st := NewSleepyTicker(normalDuration, sleepDuration) + st.Stop() // no panic expected here +} + +func TestSleepyTicker(t *testing.T) { + normalDuration := 100 * time.Millisecond + sleepDuration := 200 * time.Millisecond + + st := NewSleepyTicker(normalDuration, sleepDuration) + + // Test normal mode + select { + case <-st.Wait(): + // Expected tick + case <-time.After(normalDuration + 50*time.Millisecond): + t.Error("expected tick in normal mode") + } + + // Test sleep mode + st.SetSleep(true) + select { + case <-st.Wait(): + // Expected tick + case <-time.After(sleepDuration + 50*time.Millisecond): + t.Error("expected tick in sleep mode") + } + + // Test sleep mode with sleepDuration == 0 + st = NewSleepyTicker(normalDuration, 0) + st.SetSleep(true) + select { + case <-st.Wait(): + t.Error("did not expect tick when sleepDuration is 0") + case <-time.After(normalDuration): + // Expected no tick + } + + // Test stopping the ticker + st.Stop() + select { + case <-st.Wait(): + t.Error("did not expect tick after stopping the ticker") + case <-time.After(normalDuration): + // Expected no tick + } +} From c7f3475382e36e7daa353b5c9a4cde2f209c8497 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 20 Dec 2024 13:31:52 +0100 Subject: [PATCH 49/63] Add spn testing setup --- .gitignore | 3 +- spn/testing/README.md | 25 +++++ spn/testing/simple/README.md | 48 ++++++++ spn/testing/simple/clientsim.sh | 41 +++++++ spn/testing/simple/config-template.json | 19 ++++ spn/testing/simple/docker-compose.yml | 139 ++++++++++++++++++++++++ spn/testing/simple/entrypoint.sh | 17 +++ spn/testing/simple/inject-intel.sh | 35 ++++++ spn/testing/simple/intel-client.yaml | 25 +++++ spn/testing/simple/intel-testnet.json | 17 +++ spn/testing/simple/join.sh | 42 +++++++ spn/testing/simple/reset-databases.sh | 7 ++ spn/testing/simple/run.sh | 52 +++++++++ spn/testing/simple/stop.sh | 15 +++ 14 files changed, 483 insertions(+), 2 deletions(-) create mode 100644 spn/testing/README.md create mode 100644 spn/testing/simple/README.md create mode 100755 spn/testing/simple/clientsim.sh create mode 100644 spn/testing/simple/config-template.json create mode 100644 spn/testing/simple/docker-compose.yml create mode 100755 spn/testing/simple/entrypoint.sh create mode 100755 spn/testing/simple/inject-intel.sh create mode 100644 spn/testing/simple/intel-client.yaml create mode 100644 spn/testing/simple/intel-testnet.json create mode 100755 spn/testing/simple/join.sh create mode 100755 spn/testing/simple/reset-databases.sh create mode 100755 spn/testing/simple/run.sh create mode 100755 spn/testing/simple/stop.sh diff --git a/.gitignore b/.gitignore index 03d8b25f..0b8e5e9b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,7 @@ go.mod.* vendor # testing -testing -spn/testing/simple/testdata +testdata # Compiled Object files, Static and Dynamic libs (Shared Objects) *.a diff --git a/spn/testing/README.md b/spn/testing/README.md new file mode 100644 index 00000000..72c7ff74 --- /dev/null +++ b/spn/testing/README.md @@ -0,0 +1,25 @@ +# Testing Port17 + +## Simple Docker Setup + +Run `run.sh` to start the docker compose test network. +Then, connect to the test network, by starting the core with the "test" spn map and the correct bootstrap file. + +Run `stop.sh` to remove all docker resources again. + +Setup Guide can be found in the directory. + +## Advanced Setup with Shadow + +For advanced testing we use [shadow](https://github.com/shadow/shadow). +The following section will help you set up shadow and will guide you how to test Port17 in a local Shadow environment. + +### Setting up + +Download the docker version from here: [https://security.cs.georgetown.edu/shadow-docker-images/shadow-standalone.tar.gz](https://security.cs.georgetown.edu/shadow-docker-images/shadow-standalone.tar.gz) + +Then import the image into docker with `gunzip -c shadow-standalone.tar.gz | sudo docker load`. + +### Running + +Execute `sudo docker run -t -i -u shadow shadow-standalone /bin/bash` to start an interactive container with shadow. diff --git a/spn/testing/simple/README.md b/spn/testing/simple/README.md new file mode 100644 index 00000000..678e4e96 --- /dev/null +++ b/spn/testing/simple/README.md @@ -0,0 +1,48 @@ +# Setup Guide + +1. Build SPN Hub + +``` +cd ../../../cmds/hub/ +./build +``` + +2. Reset any previous state (for a fresh test) + +``` +./reset-databases.sh +``` + +3. Change compose file and config template as required + +Files: +- `docker-compose.yml` +- `config-template.json` + +4. Start test network + +``` +./run.sh +``` + +5. Option 1: Join as Hub + +For testing just one Hub with a different build or config, you can simply use `./join.sh` to join the network with the most recently build hub binary. + +6. Option 2: Join as Portmaster + +For connecting to the SPN test network with Portmaster, execute portmaster like this: + +sudo ../../../cmds/portmaster-core/portmaster-core --disable-shutdown-event --devmode --log debug --data /opt/safing/portmaster + +Note: +This uses the same portmaster data and config as your installed version. +As the SPN Test net operates under a different ID ("test" instead of "main"), this will not pollute the SPN state of your installed Portmaster. + +7. Stop the test net + +This is important, as just stopping the `./run.sh` script will leave you with interfaces with public IPs! + +``` +./stop.sh +``` diff --git a/spn/testing/simple/clientsim.sh b/spn/testing/simple/clientsim.sh new file mode 100755 index 00000000..a25cf3c4 --- /dev/null +++ b/spn/testing/simple/clientsim.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" + +realpath() { + path=`eval echo "$1"` + folder=$(dirname "$path") + echo $(cd "$folder"; pwd)/$(basename "$path"); +} + +if [[ ! -f "../../client" ]]; then + echo "please compile client.go in main directory (output: client)" + exit 1 +fi + +bin_path="$(realpath ../../client)" +data_path="$(realpath ./testdata)" +if [[ ! -d "$data_path" ]]; then + mkdir "$data_path" +fi +shared_path="$(realpath ./testdata/shared)" +if [[ ! -d "$shared_path" ]]; then + mkdir "$shared_path" +fi + +docker network ls | grep spn-simpletest-network >/dev/null 2>&1 +if [[ $? -ne 0 ]]; then + docker network create spn-simpletest-network --subnet 6.0.0.0/24 +fi + +docker run -ti --rm \ +--name spn-simpletest-clientsim \ +--network spn-simpletest-network \ +-v $bin_path:/opt/client:ro \ +-v $data_path/clientsim:/opt/data \ +-v $shared_path:/opt/shared \ +--entrypoint /opt/client \ +toolset.safing.network/dev \ +--data /opt/data \ +--bootstrap-file /opt/shared/bootstrap.dsd \ +--log trace $* \ No newline at end of file diff --git a/spn/testing/simple/config-template.json b/spn/testing/simple/config-template.json new file mode 100644 index 00000000..c9baca7e --- /dev/null +++ b/spn/testing/simple/config-template.json @@ -0,0 +1,19 @@ +{ + "core": { + "log": { + "level": "trace" + }, + "metrics": { + "instance": "test_$HUBNAME", + "push": "" + } + }, + "spn": { + "publicHub": { + "name": "test-$HUBNAME", + "transports": ["http:80", "http:8080", "tcp:17"], + "allowUnencrypted": true, + "bindToAdvertised": true + } + } +} diff --git a/spn/testing/simple/docker-compose.yml b/spn/testing/simple/docker-compose.yml new file mode 100644 index 00000000..3d48eb10 --- /dev/null +++ b/spn/testing/simple/docker-compose.yml @@ -0,0 +1,139 @@ +version: "2.4" + +networks: + default: + ipam: + driver: default + config: + - subnet: 6.0.0.0/24 + +services: + hub1: + container_name: spn-test-simple-hub1 + hostname: hub1 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_BIN}:/opt/hub1:ro + - ${SPN_TEST_DATA_DIR}/hub1:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.11 + + hub2: + container_name: spn-test-simple-hub2 + hostname: hub2 + image: alpine + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_BIN}:/opt/hub2:ro + - ${SPN_TEST_DATA_DIR}/hub2:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.12 + + hub3: + container_name: spn-test-simple-hub3 + hostname: hub3 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_BIN}:/opt/hub3:ro + - ${SPN_TEST_DATA_DIR}/hub3:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.13 + + hub4: + container_name: spn-test-simple-hub4 + hostname: hub4 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_BIN}:/opt/hub4:ro + - ${SPN_TEST_DATA_DIR}/hub4:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.14 + + hub5: + container_name: spn-test-simple-hub5 + hostname: hub5 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_BIN}:/opt/hub5:ro + - ${SPN_TEST_DATA_DIR}/hub5:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.15 + + hub6: + container_name: spn-test-simple-hub6 + hostname: hub6 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_OLD_BIN}:/opt/hub6:ro + - ${SPN_TEST_DATA_DIR}/hub6:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.16 + + hub7: + container_name: spn-test-simple-hub7 + hostname: hub7 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_OLD_BIN}:/opt/hub7:ro + - ${SPN_TEST_DATA_DIR}/hub7:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.17 + + hub8: + container_name: spn-test-simple-hub8 + hostname: hub8 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_OLD_BIN}:/opt/hub8:ro + - ${SPN_TEST_DATA_DIR}/hub8:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.18 + + hub9: + container_name: spn-test-simple-hub9 + hostname: hub9 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_OLD_BIN}:/opt/hub9:ro + - ${SPN_TEST_DATA_DIR}/hub9:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.19 + + hub10: + container_name: spn-test-simple-hub10 + hostname: hub10 + image: toolset.safing.network/dev + entrypoint: "/opt/shared/entrypoint.sh" + volumes: + - ${SPN_TEST_OLD_BIN}:/opt/hub10:ro + - ${SPN_TEST_DATA_DIR}/hub10:/opt/data + - ${SPN_TEST_SHARED_DATA_DIR}:/opt/shared + networks: + default: + ipv4_address: 6.0.0.20 diff --git a/spn/testing/simple/entrypoint.sh b/spn/testing/simple/entrypoint.sh new file mode 100755 index 00000000..5fe516e0 --- /dev/null +++ b/spn/testing/simple/entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# Get hostname. +HUBNAME=$HOSTNAME +if [ "$HUBNAME" = "" ]; then + HUBNAME=$(cat /etc/hostname) +fi +export HUBNAME + +# Read, process and write config. +cat /opt/shared/config-template.json | sed "s/\$HUBNAME/$HUBNAME/g" > /opt/data/config.json + +# Get binary to start. +BIN=$(ls /opt/ | grep hub) + +# Start Hub. +/opt/$BIN --data /opt/data --log trace --spn-map test --bootstrap-file /opt/shared/bootstrap.dsd --api-address 0.0.0.0:817 --devmode diff --git a/spn/testing/simple/inject-intel.sh b/spn/testing/simple/inject-intel.sh new file mode 100755 index 00000000..a57cd72b --- /dev/null +++ b/spn/testing/simple/inject-intel.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" + +MAIN_INTEL_FILE="intel-testnet.json" + +if [[ ! -f $MAIN_INTEL_FILE ]]; then + echo "missing $MAIN_INTEL_FILE" + exit 1 +fi + +echo "if the containing directory cannot be created, you might need to adjust permissions, as nodes are run with root in test containers..." +echo "$ sudo chmod -R 777 data/hub*/updates" +echo "starting to update..." + +for hubDir in data/hub*; do + # Build destination path + hubIntelFile="${hubDir}/updates/all/intel/spn/main-intel_v0-0-0.dsd" + + # Copy file + mkdir -p "${hubDir}/updates/all/intel/spn" + echo -n "J" > "$hubIntelFile" + cat $MAIN_INTEL_FILE >> "$hubIntelFile" + + echo "updated $hubIntelFile" +done + +if [[ -d /var/lib/portmaster ]]; then + echo "updating intel for local portmaster installation..." + + portmasterSPNIntelFile="/var/lib/portmaster/updates/all/intel/spn/main-intel_v0-0-0.dsd" + echo -n "J" > "$portmasterSPNIntelFile" + cat $MAIN_INTEL_FILE >> "$portmasterSPNIntelFile" + echo "updated $portmasterSPNIntelFile" +fi diff --git a/spn/testing/simple/intel-client.yaml b/spn/testing/simple/intel-client.yaml new file mode 100644 index 00000000..28f0a685 --- /dev/null +++ b/spn/testing/simple/intel-client.yaml @@ -0,0 +1,25 @@ +# Get current list of IDs from test net: +# curl http://127.0.0.1:817/api/v1/spn/map/test/pins | jq ".[] | .ID" +# Then import into test client with: +# curl -X POST --upload-file intel-client.yaml http://127.0.0.1:817/api/v1/spn/map/test/intel/update +Hubs: + Zwm48YWWFGdwXjhE1MyEkWfqxPr9DiUBoXpusTZ1FMQnuK: + Trusted: true + Zwu5LkkbfCbAcYxWG3vtWF1VvWjgWpc1GJfkwRdLFNtytV: + Trusted: true + ZwuQpz5CqYmYoLnt9KXQ8oxnmosBzfrCYwCGhxT4fsG1Dz: + Trusted: true + ZwwmC3dHzr7J6XW9mc2KD6FDNuXwPVJUFi9dLnDSNMyjLk: + Trusted: true + ZwxSBdvqtJyz8zRWKZe6QyK51KH9av6VFay2GQvpFrWKHq: + Trusted: true + ZwxnuL6zMLj4AxJX8Bj369w2tNrVtYxzffVcXZuMxdxbGj: + Trusted: true + ZwyXdnC8JkC7m796skGD7QWGoYycByR3KVntkXMY8CxRZQ: + Trusted: true + Zwz7AHiH1EevD9eYFqvQQPbVWyBBcksTRxxafbRx5Cvc4F: + Trusted: true + ZwzMtc65t9XBMwmLm2xNSL69FvqHGPLiqeNBZ3eEN5a9sS: + Trusted: true + ZwzjnCUNGsuWnkYmN3QEj8JPLxU6V1QQFk9b47AigmPKiH: + Trusted: true diff --git a/spn/testing/simple/intel-testnet.json b/spn/testing/simple/intel-testnet.json new file mode 100644 index 00000000..388fa0e1 --- /dev/null +++ b/spn/testing/simple/intel-testnet.json @@ -0,0 +1,17 @@ +{ + "BootstrapHubs": [ + ], + "TrustedHubs": [ + "ZwrY9G9HDo1J3qQrrQs8VF2KD99bj7KyWesJ5kWFUDBU6r", + "Zwj56ZFXrsud8gc1Rw3zuxRwMLhGkwvtvnTxCVtJ8EWLhQ", + "ZwpdW87ityD9i3N9x8oweCJnbZEqo346VBg4mCsCvTr1Zo", + "ZwpJ6ebddk1sccUVpo92JUqicBfKzBN2w4pEGoEY7UsNhX", + "Zwte3Jffp9PWmeWfrn8RyGuvZZFCg3v7XR3tpQjdo9TpVt", + "ZwrTcdiPF5zR5h9q9EdjHCrrXzYVBdQe5HmEYUWXdLkke3", + "Zwv7tSn5iU6bYKn53NaGCxPtL8vSxSK7F9VdQezDaDCLBt", + "Zwvtdq3K9knP9iNaRS1Ju8CETWTqy7oRwbScjBtJGBpqhB" + ], + "AdviseOnlyTrustedHubs": true, + "AdviseOnlyTrustedHomeHubs": true, + "AdviseOnlyTrustedDestinationHubs": true +} diff --git a/spn/testing/simple/join.sh b/spn/testing/simple/join.sh new file mode 100755 index 00000000..b5ddf912 --- /dev/null +++ b/spn/testing/simple/join.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" + +realpath() { + path=`eval echo "$1"` + folder=$(dirname "$path") + echo $(cd "$folder"; pwd)/$(basename "$path"); +} + +leftover=$(docker ps -a | grep spn-test-simple-me | cut -d" " -f1) +if [[ $leftover != "" ]]; then + docker stop $leftover + docker rm $leftover +fi + +if [[ ! -f "../../../cmds/hub/hub" ]]; then + echo "please build the hub cmd using cmds/hub/build" + exit 1 +fi + +SPN_TEST_BIN="$(realpath ../../../cmds/hub/hub)" +SPN_TEST_DATA_DIR="$(realpath ./testdata)" +if [[ ! -d "$SPN_TEST_DATA_DIR" ]]; then + mkdir "$SPN_TEST_DATA_DIR" +fi +SPN_TEST_SHARED_DATA_DIR="$(realpath ./testdata/shared)" +if [[ ! -d "$SPN_TEST_SHARED_DATA_DIR" ]]; then + mkdir "$SPN_TEST_SHARED_DATA_DIR" +fi + +docker run -ti \ +--name spn-test-simple-me \ +--hostname me \ +--network spn-test-simple_default \ +-v $SPN_TEST_BIN:/opt/hub_me:ro \ +-v $SPN_TEST_DATA_DIR/me:/opt/data \ +-v $SPN_TEST_SHARED_DATA_DIR:/opt/shared \ +--entrypoint /opt/hub_me \ +toolset.safing.network/dev \ +--devmode --api-address 0.0.0.0:8081 \ +--data /opt/data -log trace --spn-map test --bootstrap-file /opt/shared/bootstrap.dsd diff --git a/spn/testing/simple/reset-databases.sh b/spn/testing/simple/reset-databases.sh new file mode 100755 index 00000000..79be6890 --- /dev/null +++ b/spn/testing/simple/reset-databases.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" + +rm -rf data/me/* +rm -rf data/shared/* +rm -rf data/hub*/databases diff --git a/spn/testing/simple/run.sh b/spn/testing/simple/run.sh new file mode 100755 index 00000000..728cad3f --- /dev/null +++ b/spn/testing/simple/run.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" + +realpath() { + path=`eval echo "$1"` + folder=$(dirname "$path") + echo $(cd "$folder"; pwd)/$(basename "$path"); +} + +leftovers=$(docker ps -a | grep spn-test-simple | cut -d" " -f1) +if [[ $leftovers != "" ]]; then + docker stop $leftovers + docker rm $leftovers +fi + +if [[ ! -f "../../../cmds/hub/hub" ]]; then + echo "please build the hub cmd using cmds/hub/build" + exit 1 +fi + +# Create variables. +SPN_TEST_BIN="$(realpath ../../../cmds/hub/hub)" +SPN_TEST_DATA_DIR="$(realpath ./testdata)" +if [[ ! -d "$SPN_TEST_DATA_DIR" ]]; then + mkdir "$SPN_TEST_DATA_DIR" +fi +SPN_TEST_SHARED_DATA_DIR="$(realpath ./testdata/shared)" +if [[ ! -d "$SPN_TEST_SHARED_DATA_DIR" ]]; then + mkdir "$SPN_TEST_SHARED_DATA_DIR" +fi + +# Check if there is an old binary for testing. +SPN_TEST_OLD_BIN=$SPN_TEST_BIN +if [[ -f "./testdata/old-hub" ]]; then + SPN_TEST_OLD_BIN="$(realpath ./testdata/old-hub)" + echo "WARNING: running in hybrid mode with old version at $SPN_TEST_OLD_BIN" +fi + +# Export variables +export SPN_TEST_BIN +export SPN_TEST_OLD_BIN +export SPN_TEST_DATA_DIR +export SPN_TEST_SHARED_DATA_DIR + +# Copy files. +cp config-template.json ./testdata/shared/config-template.json +cp entrypoint.sh ./testdata/shared/entrypoint.sh +chmod 555 ./testdata/shared/entrypoint.sh + +# Run! +docker compose -p spn-test-simple up --remove-orphans diff --git a/spn/testing/simple/stop.sh b/spn/testing/simple/stop.sh new file mode 100755 index 00000000..f5af89a4 --- /dev/null +++ b/spn/testing/simple/stop.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" + +docker compose -p spn-test-simple stop +docker compose -p spn-test-simple rm + +oldnet=$(docker network ls | grep spn-test-simple | cut -d" " -f1) +if [[ $oldnet != "" ]]; then + docker network rm $oldnet +fi + +if [[ -d "data/shared" ]]; then + rm -r "data/shared" +fi From 1e9e6263d4caf88d6e700bc02d93eb001272da0b Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 20 Dec 2024 13:36:15 +0100 Subject: [PATCH 50/63] Fix SPN testnet portmaster args --- spn/testing/simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spn/testing/simple/README.md b/spn/testing/simple/README.md index 678e4e96..f5df45b5 100644 --- a/spn/testing/simple/README.md +++ b/spn/testing/simple/README.md @@ -33,7 +33,7 @@ For testing just one Hub with a different build or config, you can simply use `. For connecting to the SPN test network with Portmaster, execute portmaster like this: -sudo ../../../cmds/portmaster-core/portmaster-core --disable-shutdown-event --devmode --log debug --data /opt/safing/portmaster +sudo ../../../cmds/portmaster-core/portmaster-core --disable-shutdown-event --devmode --log debug --data /opt/safing/portmaster --spn-map test --bootstrap-file ./testdata/shared/bootstrap.dsd Note: This uses the same portmaster data and config as your installed version. From ef7b129cedaef935af010ed087da1ecfbf5c6d08 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 20 Dec 2024 13:37:01 +0100 Subject: [PATCH 51/63] Use code quotes for cmds in docs --- spn/testing/simple/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spn/testing/simple/README.md b/spn/testing/simple/README.md index f5df45b5..bec39dfb 100644 --- a/spn/testing/simple/README.md +++ b/spn/testing/simple/README.md @@ -33,7 +33,9 @@ For testing just one Hub with a different build or config, you can simply use `. For connecting to the SPN test network with Portmaster, execute portmaster like this: +``` sudo ../../../cmds/portmaster-core/portmaster-core --disable-shutdown-event --devmode --log debug --data /opt/safing/portmaster --spn-map test --bootstrap-file ./testdata/shared/bootstrap.dsd +``` Note: This uses the same portmaster data and config as your installed version. From 96209c28cfedfb5023c81eebddc3eb546be2d13b Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 13 Jan 2025 10:09:11 +0100 Subject: [PATCH 52/63] Fix SPN build --- Earthfile | 5 +++++ base/info/version.go | 1 + cmds/hub/main.go | 10 +++++----- spn/testing/simple/reset-databases.sh | 6 +++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Earthfile b/Earthfile index de711d17..bc0bc6c0 100644 --- a/Earthfile +++ b/Earthfile @@ -70,6 +70,11 @@ build: # ./dist/all/assets.zip BUILD +assets +build-spn: + BUILD +go-build --CMDS="hub" --GOOS="linux" --GOARCH="amd64" + BUILD +go-build --CMDS="hub" --GOOS="linux" --GOARCH="arm64" + # TODO: Add other platforms + go-ci: BUILD +go-build --GOOS="linux" --GOARCH="amd64" BUILD +go-build --GOOS="linux" --GOARCH="arm64" diff --git a/base/info/version.go b/base/info/version.go index 91bad092..6c27096e 100644 --- a/base/info/version.go +++ b/base/info/version.go @@ -74,6 +74,7 @@ func Set(setName string, setVersion string, setLicenseName string) { if setVersion != "" { version = setVersion + versionNumber = setVersion } } diff --git a/cmds/hub/main.go b/cmds/hub/main.go index 3db002b3..74390f27 100644 --- a/cmds/hub/main.go +++ b/cmds/hub/main.go @@ -33,7 +33,7 @@ func main() { flag.Parse() // Set name and license. - info.Set("SPN Hub", "", "GPLv3") + info.Set("SPN Hub", "0.7.8", "GPLv3") // Configure metrics. _ = metrics.SetNamespace("hub") @@ -45,10 +45,6 @@ func main() { // Set SPN public hub mode. conf.EnablePublicHub(true) - // Set default log level. - log.SetLogLevel(log.WarningLevel) - _ = log.Start() - // Create instance. var execCmdLine bool instance, err := spn.New() @@ -79,6 +75,10 @@ func main() { os.Exit(0) } + // Set default log level. + log.SetLogLevel(log.WarningLevel) + _ = log.Start() + // Start go func() { err = instance.Start() diff --git a/spn/testing/simple/reset-databases.sh b/spn/testing/simple/reset-databases.sh index 79be6890..3c8a2d19 100755 --- a/spn/testing/simple/reset-databases.sh +++ b/spn/testing/simple/reset-databases.sh @@ -2,6 +2,6 @@ cd "$( dirname "${BASH_SOURCE[0]}" )" -rm -rf data/me/* -rm -rf data/shared/* -rm -rf data/hub*/databases +rm -rf testdata/me/* +rm -rf testdata/shared/* +rm -rf testdata/hub*/databases From 3478622eb861eef4b2770f5c264d84d5964e98d5 Mon Sep 17 00:00:00 2001 From: Alexandr Stelnykovych Date: Mon, 13 Jan 2025 14:15:48 +0000 Subject: [PATCH 53/63] update deps --- go.mod | 43 ++++++++++---------- go.sum | 123 ++++++++++++++++++++++++++------------------------------- 2 files changed, 77 insertions(+), 89 deletions(-) diff --git a/go.mod b/go.mod index 27dc3f2b..49103f19 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/awalterschulze/gographviz v2.0.3+incompatible github.com/bluele/gcache v0.0.2 github.com/brianvoe/gofakeit v3.18.0+incompatible - github.com/cilium/ebpf v0.16.0 + github.com/cilium/ebpf v0.17.1 github.com/coreos/go-iptables v0.8.0 github.com/davecgh/go-spew v1.1.1 github.com/dgraph-io/badger v1.6.2 @@ -34,10 +34,10 @@ require ( github.com/hashicorp/go-version v1.7.0 github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb github.com/jackc/puddle/v2 v2.2.2 - github.com/lmittmann/tint v1.0.5 - github.com/maruel/panicparse/v2 v2.3.1 + github.com/lmittmann/tint v1.0.6 + github.com/maruel/panicparse/v2 v2.4.0 github.com/mat/besticon v3.12.0+incompatible - github.com/mattn/go-colorable v0.1.13 + github.com/mattn/go-colorable v0.1.14 github.com/mattn/go-isatty v0.0.20 github.com/miekg/dns v1.1.62 github.com/mitchellh/copystructure v1.2.0 @@ -62,22 +62,22 @@ require ( github.com/varlink/go v0.4.0 github.com/vincent-petithory/dataurl v1.0.0 go.etcd.io/bbolt v1.3.11 - golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f - golang.org/x/image v0.22.0 - golang.org/x/net v0.31.0 - golang.org/x/sync v0.9.0 - golang.org/x/sys v0.27.0 + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 + golang.org/x/image v0.23.0 + golang.org/x/net v0.34.0 + golang.org/x/sync v0.10.0 + golang.org/x/sys v0.29.0 gopkg.in/yaml.v3 v3.0.1 zombiezen.com/go/sqlite v1.4.0 ) require ( + al.essio.dev/pkg/shellescape v1.5.1 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/aead/ecdh v0.2.0 // indirect - github.com/alessio/shellescape v1.4.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/danieljoos/wincred v1.2.1 // indirect - github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/danieljoos/wincred v1.2.2 // indirect + github.com/dgraph-io/ristretto v0.2.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect @@ -85,7 +85,6 @@ require ( github.com/godbus/dbus v4.1.0+incompatible // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f // indirect - github.com/golang/glog v1.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -114,16 +113,16 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zalando/go-keyring v0.2.5 // indirect + github.com/zalando/go-keyring v0.2.6 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - golang.org/x/crypto v0.29.0 // indirect + golang.org/x/crypto v0.32.0 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.27.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/tools v0.29.0 // indirect + google.golang.org/protobuf v1.36.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - modernc.org/libc v1.61.2 // indirect - modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.34.1 // indirect + modernc.org/libc v1.61.7 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.8.1 // indirect + modernc.org/sqlite v1.34.4 // indirect ) diff --git a/go.sum b/go.sum index e75afa2b..1a291410 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho= +al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg= fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs= @@ -16,8 +18,6 @@ github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 h1:5L8Mj9Co9sJVgW3TpY github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6/go.mod h1:3HgLJ9d18kXMLQlJvIY3+FszZYMxCz8WfE2MQ7hDY0w= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0= -github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -29,13 +29,12 @@ github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6 github.com/brianvoe/gofakeit v3.18.0+incompatible h1:wDOmHc9DLG4nRjUVVaxA+CEglKOW72Y5+4WNxUIkjM8= github.com/brianvoe/gofakeit v3.18.0+incompatible/go.mod h1:kfwdRA90vvNhPutZWfH7WPaDzUjz+CZFqG+rPkOjGOc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= -github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= +github.com/cilium/ebpf v0.17.1 h1:G8mzU81R2JA1nE5/8SRubzqvBMmAmri2VL8BIZPWvV0= +github.com/cilium/ebpf v0.17.1/go.mod h1:vay2FaYSmIlv3r8dNACd4mW/OCaZLJKJOo+IHBvCIO8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= @@ -43,18 +42,19 @@ github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFE github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs= -github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps= +github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= +github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= +github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dhaavi/go-notify v0.0.0-20190209221809-c404b1f22435 h1:AnwbdEI8eV3GzLM3SlrJlYmYa6OB5X8RwY4A8QJOCP0= github.com/dhaavi/go-notify v0.0.0-20190209221809-c404b1f22435/go.mod h1:EMJ8XWTopp8OLRBMUm9vHE8Wn48CNpU21HM817OKNrc= github.com/dhaavi/winres v0.2.2 h1:SUago7FwhgLSMyDdeuV6enBZ+ZQSl0KwcnbWzvlfBls= @@ -96,9 +96,6 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw github.com/golang/gddo v0.0.0-20180823221919-9d8ff1c67be5/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f h1:16RtHeWGkJMc80Etb8RPCcKevXGldr57+LOyZt8zOlg= github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f/go.mod h1:ijRvpgDJDI262hYq/IQVYgf8hd8IHUs93Ol0kvMBAx4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/lint v0.0.0-20170918230701-e5d664eb928e/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -171,21 +168,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lmittmann/tint v1.0.5 h1:NQclAutOfYsqs2F1Lenue6OoWCajs5wJcP3DfWVpePw= -github.com/lmittmann/tint v1.0.5/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/lmittmann/tint v1.0.6 h1:vkkuDAZXc0EFGNzYjWcV0h7eEX+uujH48f/ifSkJWgc= +github.com/lmittmann/tint v1.0.6/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/maruel/panicparse/v2 v2.3.1 h1:NtJavmbMn0DyzmmSStE8yUsmPZrZmudPH7kplxBinOA= -github.com/maruel/panicparse/v2 v2.3.1/go.mod h1:s3UmQB9Fm/n7n/prcD2xBGDkwXD6y2LeZnhbEXvs9Dg= +github.com/maruel/panicparse/v2 v2.4.0 h1:yQKMIbQ0DKfinzVkTkcUzQyQ60UCiNnYfR7PWwTs2VI= +github.com/maruel/panicparse/v2 v2.4.0/go.mod h1:nOY2OKe8csO3F3SA5+hsxot05JLgukrF54B9x88fVp4= github.com/mat/besticon v3.12.0+incompatible h1:1KTD6wisfjfnX+fk9Kx/6VEZL+MAW1LhCkL9Q47H9Bg= github.com/mat/besticon v3.12.0+incompatible/go.mod h1:mA1auQYHt6CW5e7L9HJLmqVQC8SzNk2gVwouO0AbiEU= github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= @@ -211,7 +205,6 @@ github.com/mdlayher/socket v0.1.0/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5A github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs= github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= -github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -329,8 +322,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= -github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= +github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= +github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= @@ -344,12 +337,12 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= -golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g= -golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= +golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -378,15 +371,15 @@ golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -412,7 +405,6 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -420,13 +412,10 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -434,16 +423,16 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -452,8 +441,8 @@ google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= +google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -465,28 +454,28 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= -modernc.org/cc/v4 v4.23.1 h1:WqJoPL3x4cUufQVHkXpXX7ThFJ1C4ik80i2eXEXbhD8= -modernc.org/cc/v4 v4.23.1/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.22.3 h1:C7AW89Zw3kygesTQWBzApwIn9ldM+cb/plrTIKq41Os= -modernc.org/ccgo/v4 v4.22.3/go.mod h1:Dz7n0/UkBbH3pnYaxgi1mFSfF4REqUOZNziphZASx6k= +modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0= +modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.23.10 h1:DnDZT/H6TtoJvQmVf7d8W+lVqEZpIJY/+0ENFh1LIHE= +modernc.org/ccgo/v4 v4.23.10/go.mod h1:vdN4h2WR5aEoNondUx26K7G8X+nuBscYnAEWSRmN2/0= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= -modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/libc v1.61.2 h1:dkO4DlowfClcJYsvf/RiK6fUwvzCQTmB34bJLt0CAGQ= -modernc.org/libc v1.61.2/go.mod h1:4QGjNyX3h+rn7V5oHpJY2yH0QN6frt1X+5BkXzwLPCo= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= -modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= -modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.34.1 h1:u3Yi6M0N8t9yKRDwhXcyp1eS5/ErhPTBggxWFuR6Hfk= -modernc.org/sqlite v1.34.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= -modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/gc/v2 v2.6.1 h1:+Qf6xdG8l7B27TQ8D8lw/iFMUj1RXRBOuMUWziJOsk8= +modernc.org/gc/v2 v2.6.1/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/libc v1.61.7 h1:exz8rasFniviSgh3dH7QBnQHqYh9lolA5hVYfsiwkfo= +modernc.org/libc v1.61.7/go.mod h1:xspSrXRNVSfWfcfqgvZDVe/Hw5kv4FVC6IRfoms5v/0= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.8.1 h1:HS1HRg1jEohnuONobEq2WrLEhLyw8+J42yLFTnllm2A= +modernc.org/memory v1.8.1/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= +modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8= +modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= zombiezen.com/go/sqlite v1.4.0 h1:N1s3RIljwtp4541Y8rM880qgGIgq3fTD2yks1xftnKU= From 88b92dcc932f7a1f88b94ac7f0aec077d28ff559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=A5=C3=A5vi?= Date: Tue, 14 Jan 2025 14:28:56 +0100 Subject: [PATCH 54/63] Fix rust-base build Sometimes rust attempts to upgrade crates. This stops it from doing that. --- Earthfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Earthfile b/Earthfile index bc0bc6c0..1bfa233e 100644 --- a/Earthfile +++ b/Earthfile @@ -425,7 +425,7 @@ rust-base: DO rust+INIT --keep_fingerprints=true # For now we need tauri-cli 2.0.0 for bulding - DO rust+CARGO --args="install tauri-cli --version 2.1.0" + DO rust+CARGO --args="install tauri-cli --version 2.1.0 --locked" # Explicitly cache here. SAVE IMAGE --cache-hint From 9829136b8c689bc06f76f827765cff1d1e9687ef Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Tue, 14 Jan 2025 18:13:31 +0200 Subject: [PATCH 55/63] [service] Fix file permission in the updates --- base/database/main.go | 15 +++------------ base/utils/fs.go | 15 ++++++++++----- base/utils/permissions.go | 14 ++------------ base/utils/permissions_windows.go | 23 ++++++----------------- base/utils/structure.go | 25 ++++++++++++++----------- service/netquery/database.go | 15 ++++----------- service/profile/module.go | 19 +++++++------------ service/ui/module.go | 2 +- service/updates/downloader.go | 9 +++++---- service/updates/index.go | 18 +++++++----------- service/updates/upgrade.go | 24 +++++++++--------------- 11 files changed, 68 insertions(+), 111 deletions(-) diff --git a/base/database/main.go b/base/database/main.go index 91cf02da..e11a73f8 100644 --- a/base/database/main.go +++ b/base/database/main.go @@ -3,7 +3,6 @@ package database import ( "errors" "fmt" - "os" "path/filepath" "github.com/safing/portmaster/base/utils" @@ -24,15 +23,11 @@ func Initialize(databasesRootDir string) error { if initialized.SetToIf(false, true) { rootDir = databasesRootDir - err := os.MkdirAll(rootDir, 0o0700) + // ensure root and databases dirs + err := utils.EnsureDirectory(rootDir, utils.AdminOnlyExecPermission) if err != nil { return fmt.Errorf("failed to create/check database dir %q: %w", rootDir, err) } - // ensure root and databases dirs - err = utils.EnsureDirectory(rootDir, utils.AdminOnlyPermission) - if err != nil { - return fmt.Errorf("could not set permissions to database directory (%s): %w", rootDir, err) - } return nil } @@ -64,13 +59,9 @@ func getLocation(name, storageType string) (string, error) { location := filepath.Join(rootDir, name, storageType) // Make sure location exists. - err := os.MkdirAll(location, 0o0700) + err := utils.EnsureDirectory(location, utils.AdminOnlyExecPermission) if err != nil { return "", fmt.Errorf("failed to create/check database dir %q: %w", location, err) } - err = utils.EnsureDirectory(location, utils.AdminOnlyPermission) - if err != nil { - return "", fmt.Errorf("could not set permissions to directory (%s): %w", location, err) - } return location, nil } diff --git a/base/utils/fs.go b/base/utils/fs.go index d32715af..edb42108 100644 --- a/base/utils/fs.go +++ b/base/utils/fs.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io/fs" + "log/slog" "os" "runtime" ) @@ -13,6 +14,10 @@ const isWindows = runtime.GOOS == "windows" // EnsureDirectory ensures that the given directory exists and that is has the given permissions set. // If path is a file, it is deleted and a directory created. func EnsureDirectory(path string, perm FSPermission) error { + if !perm.IsExecPermission() { + slog.Warn("utils: setting not executable permission for directory", "dir", path) + } + // open path f, err := os.Stat(path) if err == nil { @@ -21,10 +26,10 @@ func EnsureDirectory(path string, perm FSPermission) error { // directory exists, check permissions if isWindows { // Ignore windows permission error. For none admin users it will always fail. - _ = SetDirPermission(path, perm) + _ = SetFilePermission(path, perm) return nil - } else if f.Mode().Perm() != perm.AsUnixDirExecPermission() { - return SetDirPermission(path, perm) + } else if f.Mode().Perm() != perm.AsUnixPermission() { + return SetFilePermission(path, perm) } return nil } @@ -35,12 +40,12 @@ func EnsureDirectory(path string, perm FSPermission) error { } // file does not exist (or has been deleted) if err == nil || errors.Is(err, fs.ErrNotExist) { - err = os.MkdirAll(path, perm.AsUnixDirExecPermission()) + err = os.MkdirAll(path, perm.AsUnixPermission()) if err != nil { return fmt.Errorf("could not create dir %s: %w", path, err) } // Set permissions. - err = SetDirPermission(path, perm) + err = SetFilePermission(path, perm) // Ignore windows permission error. For none admin users it will always fail. if !isWindows { return err diff --git a/base/utils/permissions.go b/base/utils/permissions.go index d7690724..328ac884 100644 --- a/base/utils/permissions.go +++ b/base/utils/permissions.go @@ -4,17 +4,7 @@ package utils import "os" -// SetDirPermission sets the permission of a directory. -func SetDirPermission(path string, perm FSPermission) error { - return os.Chmod(path, perm.AsUnixDirExecPermission()) -} - -// SetExecPermission sets the permission of an executable file. -func SetExecPermission(path string, perm FSPermission) error { - return SetDirPermission(path, perm) -} - -// SetFilePermission sets the permission of a non executable file. +// SetFilePermission sets the permission of a file or directory. func SetFilePermission(path string, perm FSPermission) error { - return os.Chmod(path, perm.AsUnixFilePermission()) + return os.Chmod(path, perm.AsUnixPermission()) } diff --git a/base/utils/permissions_windows.go b/base/utils/permissions_windows.go index 13cbf583..8a65016d 100644 --- a/base/utils/permissions_windows.go +++ b/base/utils/permissions_windows.go @@ -31,22 +31,10 @@ func init() { } } -// SetDirPermission sets the permission of a directory. -func SetDirPermission(path string, perm FSPermission) error { - SetFilePermission(path, perm) - return nil -} - -// SetExecPermission sets the permission of an executable file. -func SetExecPermission(path string, perm FSPermission) error { - SetFilePermission(path, perm) - return nil -} - -// SetFilePermission sets the permission of a non executable file. -func SetFilePermission(path string, perm FSPermission) { +// SetFilePermission sets the permission of a file or directory. +func SetFilePermission(path string, perm FSPermission) error { switch perm { - case AdminOnlyPermission: + case AdminOnlyPermission, AdminOnlyExecPermission: // Set only admin rights, remove all others. acl.Apply( path, @@ -55,7 +43,7 @@ func SetFilePermission(path string, perm FSPermission) { acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID), acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID), ) - case PublicReadPermission: + case PublicReadPermission, PublicReadExecPermission: // Set admin rights and read/execute rights for users, remove all others. acl.Apply( path, @@ -65,7 +53,7 @@ func SetFilePermission(path string, perm FSPermission) { acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID), acl.GrantSid(windows.GENERIC_READ|windows.GENERIC_EXECUTE, usersSID), ) - case PublicWritePermission: + case PublicWritePermission, PublicWriteExecPermission: // Set full control to admin and regular users. Guest users will not have access. acl.Apply( path, @@ -76,4 +64,5 @@ func SetFilePermission(path string, perm FSPermission) { acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, usersSID), ) } + return nil } diff --git a/base/utils/structure.go b/base/utils/structure.go index 8e1f0786..3209b27b 100644 --- a/base/utils/structure.go +++ b/base/utils/structure.go @@ -12,36 +12,39 @@ type FSPermission uint8 const ( AdminOnlyPermission FSPermission = iota + AdminOnlyExecPermission PublicReadPermission + PublicReadExecPermission PublicWritePermission + PublicWriteExecPermission ) // AsUnixDirExecPermission return the corresponding unix permission for a directory or executable. -func (perm FSPermission) AsUnixDirExecPermission() fs.FileMode { +func (perm FSPermission) AsUnixPermission() fs.FileMode { switch perm { case AdminOnlyPermission: + return 0o600 + case AdminOnlyExecPermission: return 0o700 case PublicReadPermission: + return 0o644 + case PublicReadExecPermission: return 0o755 case PublicWritePermission: + return 0o666 + case PublicWriteExecPermission: return 0o777 } return 0 } -// AsUnixFilePermission return the corresponding unix permission for a regular file. -func (perm FSPermission) AsUnixFilePermission() fs.FileMode { +func (perm FSPermission) IsExecPermission() bool { switch perm { - case AdminOnlyPermission: - return 0o600 - case PublicReadPermission: - return 0o644 - case PublicWritePermission: - return 0o666 + case AdminOnlyExecPermission, PublicReadExecPermission, PublicWriteExecPermission: + return true } - - return 0 + return false } // DirStructure represents a directory structure with permissions that should be enforced. diff --git a/service/netquery/database.go b/service/netquery/database.go index 4bf28b0b..81eedf2d 100644 --- a/service/netquery/database.go +++ b/service/netquery/database.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "os" "path/filepath" "sort" "strings" @@ -129,12 +128,9 @@ type ( // handed over to SQLite. func New(dbPath string) (*Database, error) { historyParentDir := filepath.Join(module.instance.DataDir(), "databases") - if err := os.MkdirAll(historyParentDir, 0o0700); err != nil { - return nil, fmt.Errorf("failed to ensure database directory exists: %w", err) - } - err := utils.EnsureDirectory(historyParentDir, utils.AdminOnlyPermission) + err := utils.EnsureDirectory(historyParentDir, utils.AdminOnlyExecPermission) if err != nil { - return nil, fmt.Errorf("failed to set permission to folder %s: %w", historyParentDir, err) + return nil, fmt.Errorf("failed to ensure database directory exists: %w", err) } // Get file location of history database. @@ -231,12 +227,9 @@ func (db *Database) Close() error { // VacuumHistory rewrites the history database in order to purge deleted records. func VacuumHistory(ctx context.Context) (err error) { historyParentDir := filepath.Join(module.instance.DataDir(), "databases") - if err := os.MkdirAll(historyParentDir, 0o0700); err != nil { - return fmt.Errorf("failed to ensure database directory exists: %w", err) - } - err = utils.EnsureDirectory(historyParentDir, utils.AdminOnlyPermission) + err = utils.EnsureDirectory(historyParentDir, utils.AdminOnlyExecPermission) if err != nil { - return fmt.Errorf("failed to set permission to folder %s: %w", historyParentDir, err) + return fmt.Errorf("failed to ensure database directory exists: %w", err) } // Get file location of history database. diff --git a/service/profile/module.go b/service/profile/module.go index 6124d090..06dffecd 100644 --- a/service/profile/module.go +++ b/service/profile/module.go @@ -3,7 +3,6 @@ package profile import ( "errors" "fmt" - "os" "path/filepath" "sync/atomic" @@ -68,19 +67,15 @@ func prep() error { // Setup icon storage location. databaseDir := filepath.Join(module.instance.DataDir(), "databases") + // Ensure folder existents and permission + err := utils.EnsureDirectory(databaseDir, utils.AdminOnlyExecPermission) + if err != nil { + return fmt.Errorf("failed to ensure directory existence %s: %w", databaseDir, err) + } iconsDir := filepath.Join(databaseDir, "icons") - if err := os.MkdirAll(iconsDir, 0o0700); err != nil { - return fmt.Errorf("failed to create/check icons directory: %w", err) - } - - // Ensure folder permissions - err := utils.EnsureDirectory(databaseDir, utils.AdminOnlyPermission) + err = utils.EnsureDirectory(iconsDir, utils.AdminOnlyExecPermission) if err != nil { - return fmt.Errorf("failed to set permission to folder %s: %w", databaseDir, err) - } - err = utils.EnsureDirectory(iconsDir, utils.AdminOnlyPermission) - if err != nil { - return fmt.Errorf("failed to set permission to folder %s: %w", iconsDir, err) + return fmt.Errorf("failed to ensure directory existence %s: %w", iconsDir, err) } binmeta.ProfileIconStoragePath = iconsDir diff --git a/service/ui/module.go b/service/ui/module.go index dbc6b47e..a058c508 100644 --- a/service/ui/module.go +++ b/service/ui/module.go @@ -37,7 +37,7 @@ func start() error { } // Ensure directory permission - err = utils.EnsureDirectory(execDir, utils.PublicWritePermission) + err = utils.EnsureDirectory(execDir, utils.PublicWriteExecPermission) if err != nil { log.Warningf("ui: failed to set permissions to directory %s: %s", execDir, err) } diff --git a/service/updates/downloader.go b/service/updates/downloader.go index 27836cac..c87d92d9 100644 --- a/service/updates/downloader.go +++ b/service/updates/downloader.go @@ -16,6 +16,7 @@ import ( "path/filepath" "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/base/utils" ) type Downloader struct { @@ -37,7 +38,7 @@ func NewDownloader(u *Updater, indexURLs []string) *Downloader { func (d *Downloader) updateIndex(ctx context.Context) error { // Make sure dir exists. - err := os.MkdirAll(d.u.cfg.DownloadDirectory, defaultDirMode) + err := os.MkdirAll(d.u.cfg.DownloadDirectory, utils.PublicReadExecPermission.AsUnixPermission()) if err != nil { return fmt.Errorf("create download directory: %s", d.u.cfg.DownloadDirectory) } @@ -65,7 +66,7 @@ func (d *Downloader) updateIndex(ctx context.Context) error { // Write the index into a file. indexFilepath := filepath.Join(d.u.cfg.DownloadDirectory, d.u.cfg.IndexFile) - err = os.WriteFile(indexFilepath, indexData, defaultFileMode) + err = os.WriteFile(indexFilepath, indexData, utils.PublicReadExecPermission.AsUnixPermission()) if err != nil { return fmt.Errorf("write index file: %w", err) } @@ -130,7 +131,7 @@ func (d *Downloader) gatherExistingFiles(dir string) error { func (d *Downloader) downloadArtifacts(ctx context.Context) error { // Make sure dir exists. - err := os.MkdirAll(d.u.cfg.DownloadDirectory, defaultDirMode) + err := os.MkdirAll(d.u.cfg.DownloadDirectory, utils.PublicReadExecPermission.AsUnixPermission()) if err != nil { return fmt.Errorf("create download directory: %s", d.u.cfg.DownloadDirectory) } @@ -176,7 +177,7 @@ artifacts: // Write artifact to temporary file. tmpFilename := dstFilePath + ".download" - err = os.WriteFile(tmpFilename, artifactData, artifact.GetFileMode()) + err = os.WriteFile(tmpFilename, artifactData, artifact.GetFileMode().AsUnixPermission()) if err != nil { return fmt.Errorf("write %s to temp file: %w", artifact.Filename, err) } diff --git a/service/updates/index.go b/service/updates/index.go index baa76329..cba07c14 100644 --- a/service/updates/index.go +++ b/service/updates/index.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/fs" "os" "path/filepath" "runtime" @@ -18,6 +17,7 @@ import ( "github.com/safing/jess" "github.com/safing/jess/filesig" + "github.com/safing/portmaster/base/utils" ) // MaxUnpackSize defines the maximum size that is allowed to be unpacked. @@ -41,17 +41,12 @@ type Artifact struct { } // GetFileMode returns the required filesystem permission for the artifact. -func (a *Artifact) GetFileMode() os.FileMode { - // Special case for portmaster ui. Should be able to be executed from the regular user - if a.Platform == currentPlatform && a.Filename == "portmaster" { - return executableUIFileMode - } - +func (a *Artifact) GetFileMode() utils.FSPermission { if a.Platform == currentPlatform { - return executableFileMode + return utils.PublicReadExecPermission } - return defaultFileMode + return utils.PublicReadPermission } // Path returns the absolute path to the local file. @@ -338,7 +333,7 @@ func checkSHA256Sum(fileData []byte, sha256sum string) error { // copyAndCheckSHA256Sum copies the file from src to dst and check the sha256 sum. // As a special case, if the sha256sum is not given, it is not checked. -func copyAndCheckSHA256Sum(src, dst, sha256sum string, fileMode fs.FileMode) error { +func copyAndCheckSHA256Sum(src, dst, sha256sum string, filePermission utils.FSPermission) error { // Check expected hash. var expectedDigest []byte if sha256sum != "" { @@ -367,7 +362,7 @@ func copyAndCheckSHA256Sum(src, dst, sha256sum string, fileMode fs.FileMode) err // Write to temporary file. tmpDst := dst + ".copy" - err = os.WriteFile(tmpDst, fileData, fileMode) + err = os.WriteFile(tmpDst, fileData, filePermission.AsUnixPermission()) if err != nil { return fmt.Errorf("write temp dst file: %w", err) } @@ -377,6 +372,7 @@ func copyAndCheckSHA256Sum(src, dst, sha256sum string, fileMode fs.FileMode) err if err != nil { return fmt.Errorf("rename dst file after write: %w", err) } + utils.SetFilePermission(dst, filePermission) return nil } diff --git a/service/updates/upgrade.go b/service/updates/upgrade.go index 1008dcdd..9d18de98 100644 --- a/service/updates/upgrade.go +++ b/service/updates/upgrade.go @@ -3,20 +3,13 @@ package updates import ( "errors" "fmt" - "io/fs" "os" "path/filepath" "slices" "strings" "github.com/safing/portmaster/base/log" -) - -const ( - defaultFileMode = os.FileMode(0o0644) - executableFileMode = os.FileMode(0o0744) - executableUIFileMode = os.FileMode(0o0755) - defaultDirMode = os.FileMode(0o0755) + "github.com/safing/portmaster/base/utils" ) func (u *Updater) upgrade(downloader *Downloader, ignoreVersion bool) error { @@ -55,7 +48,7 @@ func (u *Updater) upgradeMoveFiles(downloader *Downloader) error { // Reset purge directory, so that we can do a clean rollback later. _ = os.RemoveAll(u.cfg.PurgeDirectory) - err := os.MkdirAll(u.cfg.PurgeDirectory, defaultDirMode) + err := utils.EnsureDirectory(u.cfg.PurgeDirectory, utils.PublicReadExecPermission) if err != nil { return fmt.Errorf("failed to create purge directory: %w", err) } @@ -69,7 +62,7 @@ func (u *Updater) upgradeMoveFiles(downloader *Downloader) error { if !errors.Is(err, os.ErrNotExist) { return fmt.Errorf("read current directory: %w", err) } - err = os.MkdirAll(u.cfg.Directory, defaultDirMode) + err := utils.EnsureDirectory(u.cfg.PurgeDirectory, utils.PublicReadExecPermission) if err != nil { return fmt.Errorf("create current directory: %w", err) } @@ -84,7 +77,7 @@ func (u *Updater) upgradeMoveFiles(downloader *Downloader) error { // Otherwise, move file to purge dir. src := filepath.Join(u.cfg.Directory, file.Name()) dst := filepath.Join(u.cfg.PurgeDirectory, file.Name()) - err := u.moveFile(src, dst, "", file.Type().Perm()) + err := u.moveFile(src, dst, "", utils.PublicReadPermission) if err != nil { return fmt.Errorf("failed to move current file %s to purge dir: %w", file.Name(), err) } @@ -95,7 +88,7 @@ func (u *Updater) upgradeMoveFiles(downloader *Downloader) error { log.Debugf("updates/%s: installing the new version (v%s from %s)", u.cfg.Name, downloader.index.Version, downloader.index.Published) src := filepath.Join(u.cfg.DownloadDirectory, u.cfg.IndexFile) dst := filepath.Join(u.cfg.Directory, u.cfg.IndexFile) - err = u.moveFile(src, dst, "", defaultFileMode) + err = u.moveFile(src, dst, "", utils.PublicReadPermission) if err != nil { return fmt.Errorf("failed to move index file to %s: %w", dst, err) } @@ -120,17 +113,18 @@ func (u *Updater) upgradeMoveFiles(downloader *Downloader) error { } // moveFile moves a file and falls back to copying if it fails. -func (u *Updater) moveFile(currentPath, newPath string, sha256sum string, fileMode fs.FileMode) error { +func (u *Updater) moveFile(currentPath, newPath string, sha256sum string, filePermission utils.FSPermission) error { // Try to simply move file. err := os.Rename(currentPath, newPath) if err == nil { // Moving was successful, return. + utils.SetFilePermission(newPath, filePermission) return nil } log.Tracef("updates/%s: failed to move to %q, falling back to copy+delete: %s", u.cfg.Name, newPath, err) // Copy and check the checksum while we are at it. - err = copyAndCheckSHA256Sum(currentPath, newPath, sha256sum, fileMode) + err = copyAndCheckSHA256Sum(currentPath, newPath, sha256sum, filePermission) if err != nil { return fmt.Errorf("move failed, copy+delete fallback failed: %w", err) } @@ -150,7 +144,7 @@ func (u *Updater) recoverFromFailedUpgrade() error { for _, file := range files { purgedFile := filepath.Join(u.cfg.PurgeDirectory, file.Name()) activeFile := filepath.Join(u.cfg.Directory, file.Name()) - err := u.moveFile(purgedFile, activeFile, "", file.Type().Perm()) + err := u.moveFile(purgedFile, activeFile, "", utils.PublicReadPermission) if err != nil { // Only warn and continue to recover as many files as possible. log.Warningf("updates/%s: failed to roll back file %s: %s", u.cfg.Name, file.Name(), err) From 49e1fc8c31458387c5f29a70c08c7b75924a312c Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Wed, 15 Jan 2025 11:43:14 +0200 Subject: [PATCH 56/63] [service] Ensure pemission for all directories --- service/instance.go | 4 ++-- service/updates/downloader.go | 6 ++++-- spn/instance.go | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/service/instance.go b/service/instance.go index 4f3967e5..c71f6388 100644 --- a/service/instance.go +++ b/service/instance.go @@ -3,7 +3,6 @@ package service import ( "context" "fmt" - "os" "sync/atomic" "time" @@ -14,6 +13,7 @@ import ( "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/base/rng" "github.com/safing/portmaster/base/runtime" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/service/broadcasts" "github.com/safing/portmaster/service/compat" "github.com/safing/portmaster/service/core" @@ -123,7 +123,7 @@ func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx } // Make sure data dir exists, so that child directories don't dictate the permissions. - err = os.MkdirAll(svcCfg.DataDir, 0o0755) + err = utils.EnsureDirectory(svcCfg.DataDir, utils.PublicReadExecPermission) if err != nil { return nil, fmt.Errorf("data directory %s is not accessible: %w", svcCfg.DataDir, err) } diff --git a/service/updates/downloader.go b/service/updates/downloader.go index c87d92d9..acc94292 100644 --- a/service/updates/downloader.go +++ b/service/updates/downloader.go @@ -38,7 +38,7 @@ func NewDownloader(u *Updater, indexURLs []string) *Downloader { func (d *Downloader) updateIndex(ctx context.Context) error { // Make sure dir exists. - err := os.MkdirAll(d.u.cfg.DownloadDirectory, utils.PublicReadExecPermission.AsUnixPermission()) + err := utils.EnsureDirectory(d.u.cfg.DownloadDirectory, utils.PublicReadExecPermission) if err != nil { return fmt.Errorf("create download directory: %s", d.u.cfg.DownloadDirectory) } @@ -131,7 +131,7 @@ func (d *Downloader) gatherExistingFiles(dir string) error { func (d *Downloader) downloadArtifacts(ctx context.Context) error { // Make sure dir exists. - err := os.MkdirAll(d.u.cfg.DownloadDirectory, utils.PublicReadExecPermission.AsUnixPermission()) + err := utils.EnsureDirectory(d.u.cfg.DownloadDirectory, utils.PublicReadExecPermission) if err != nil { return fmt.Errorf("create download directory: %s", d.u.cfg.DownloadDirectory) } @@ -182,6 +182,8 @@ artifacts: return fmt.Errorf("write %s to temp file: %w", artifact.Filename, err) } + _ = utils.SetFilePermission(tmpFilename, artifact.GetFileMode()) + // Rename/Move to actual location. err = os.Rename(tmpFilename, dstFilePath) if err != nil { diff --git a/spn/instance.go b/spn/instance.go index 33af8ea5..e8fa1789 100644 --- a/spn/instance.go +++ b/spn/instance.go @@ -3,7 +3,6 @@ package spn import ( "context" "fmt" - "os" "sync/atomic" "time" @@ -14,6 +13,7 @@ import ( "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/base/rng" "github.com/safing/portmaster/base/runtime" + "github.com/safing/portmaster/base/utils" "github.com/safing/portmaster/service" "github.com/safing/portmaster/service/core" "github.com/safing/portmaster/service/core/base" @@ -88,7 +88,7 @@ func New(svcCfg *service.ServiceConfig) (*Instance, error) { } // Make sure data dir exists, so that child directories don't dictate the permissions. - err = os.MkdirAll(svcCfg.DataDir, 0o0755) + err = utils.EnsureDirectory(svcCfg.DataDir, utils.PublicReadExecPermission) if err != nil { return nil, fmt.Errorf("data directory %s is not accessible: %w", svcCfg.DataDir, err) } From aa1bd0679cc5a02a217b05c701c8cea62f169298 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Jan 2025 09:19:18 +0100 Subject: [PATCH 57/63] Improve updatemgr and updates module --- cmds/updatemgr/convert.go | 123 ++++++++++++++++++ cmds/updatemgr/download.go | 88 +++++++++++++ cmds/updatemgr/mirror.go | 215 ++++++++++++++++++++++++++++++++ cmds/updatemgr/sign.go | 4 +- go.mod | 63 +++++----- go.sum | 169 +++++++++++++------------ service/updates/downloader.go | 9 +- service/updates/index.go | 29 +++-- service/updates/index_scan.go | 7 +- service/updates/module.go | 17 ++- service/updates/updates_test.go | 4 +- 11 files changed, 589 insertions(+), 139 deletions(-) create mode 100644 cmds/updatemgr/convert.go create mode 100644 cmds/updatemgr/download.go create mode 100644 cmds/updatemgr/mirror.go diff --git a/cmds/updatemgr/convert.go b/cmds/updatemgr/convert.go new file mode 100644 index 00000000..1db8d658 --- /dev/null +++ b/cmds/updatemgr/convert.go @@ -0,0 +1,123 @@ +package main + +import ( + "encoding/json" + "fmt" + "path" + "strings" + "time" + + "github.com/safing/portmaster/service/updates" +) + +func convertV1(indexData []byte, baseURL string, lastUpdate time.Time) (*updates.Index, error) { + // Parse old index. + oldIndex := make(map[string]string) + err := json.Unmarshal(indexData, &oldIndex) + if err != nil { + return nil, fmt.Errorf("failed to parse old v1 index: %w", err) + } + + // Create new index. + newIndex := &updates.Index{ + Published: lastUpdate, + Artifacts: make([]*updates.Artifact, 0, len(oldIndex)), + } + + // Convert all entries. + if err := convertEntries(newIndex, baseURL, oldIndex); err != nil { + return nil, err + } + + return newIndex, nil +} + +type IndexV2 struct { + Channel string + Published time.Time + Releases map[string]string +} + +func convertV2(indexData []byte, baseURL string) (*updates.Index, error) { + // Parse old index. + oldIndex := &IndexV2{} + err := json.Unmarshal(indexData, oldIndex) + if err != nil { + return nil, fmt.Errorf("failed to parse old v2 index: %w", err) + } + + // Create new index. + newIndex := &updates.Index{ + Published: oldIndex.Published, + Artifacts: make([]*updates.Artifact, 0, len(oldIndex.Releases)), + } + + // Convert all entries. + if err := convertEntries(newIndex, baseURL, oldIndex.Releases); err != nil { + return nil, err + } + + return newIndex, nil +} + +func convertEntries(index *updates.Index, baseURL string, entries map[string]string) error { +entries: + for identifier, version := range entries { + dir, filename := path.Split(identifier) + artifactPath := GetVersionedPath(identifier, version) + + // Check if file is to be ignored. + if scanConfig.IsIgnored(artifactPath) { + continue entries + } + + // Get the platform. + var platform string + splittedPath := strings.Split(dir, "/") + if len(splittedPath) >= 1 { + platform = splittedPath[0] + if platform == "all" { + platform = "" + } + } else { + continue entries + } + + // Create new artifact. + newArtifact := &updates.Artifact{ + Filename: filename, + URLs: []string{baseURL + artifactPath}, + Platform: platform, + Version: version, + } + + // Derive unpack setting. + unpack, err := scanConfig.UnpackSetting(filename) + if err != nil { + return fmt.Errorf("failed to get unpack setting for %s: %w", filename, err) + } + newArtifact.Unpack = unpack + + // Add to new index. + index.Artifacts = append(index.Artifacts, newArtifact) + } + + return nil +} + +// GetVersionedPath combines the identifier and version and returns it as a file path. +func GetVersionedPath(identifier, version string) (versionedPath string) { + identifierPath, filename := path.Split(identifier) + + // Split the filename where the version should go. + splittedFilename := strings.SplitN(filename, ".", 2) + // Replace `.` with `-` for the filename format. + transformedVersion := strings.Replace(version, ".", "-", 2) + + // Put everything back together and return it. + versionedPath = identifierPath + splittedFilename[0] + "_v" + transformedVersion + if len(splittedFilename) > 1 { + versionedPath += "." + splittedFilename[1] + } + return versionedPath +} diff --git a/cmds/updatemgr/download.go b/cmds/updatemgr/download.go new file mode 100644 index 00000000..9c6bc58a --- /dev/null +++ b/cmds/updatemgr/download.go @@ -0,0 +1,88 @@ +package main + +import ( + "errors" + "fmt" + "os" + "runtime" + + "github.com/spf13/cobra" + + "github.com/safing/portmaster/base/log" + "github.com/safing/portmaster/service/updates" +) + +const currentPlatform = runtime.GOOS + "_" + runtime.GOARCH + +var ( + downloadCmd = &cobra.Command{ + Use: "download [index URL] [download dir]", + Short: "Download all artifacts by an index to a directory", + RunE: download, + Args: cobra.ExactArgs(2), + } + + downloadPlatform string +) + +func init() { + rootCmd.AddCommand(downloadCmd) + downloadCmd.Flags().StringVarP(&downloadPlatform, "platform", "p", currentPlatform, "Define platform to download artifacts for") +} + +func download(cmd *cobra.Command, args []string) error { + // Args. + indexURL := args[0] + targetDir := args[1] + + // Check target dir. + stat, err := os.Stat(targetDir) + if err != nil { + return fmt.Errorf("failed to access target dir: %w", err) + } + if !stat.IsDir() { + return errors.New("target is not a directory") + } + + // Create temporary directories. + tmpDownload, err := os.MkdirTemp("", "portmaster-updatemgr-download-") + if err != nil { + return err + } + tmpPurge, err := os.MkdirTemp("", "portmaster-updatemgr-purge-") + if err != nil { + return err + } + + // Create updater. + u, err := updates.New(nil, "", updates.Config{ + Name: "Downloader", + Directory: targetDir, + DownloadDirectory: tmpDownload, + PurgeDirectory: tmpPurge, + IndexURLs: []string{indexURL}, + IndexFile: "index.json", + Platform: downloadPlatform, + }) + if err != nil { + return err + } + + // Start logging. + err = log.Start(log.InfoLevel.Name(), true, "") + if err != nil { + return err + } + + // Download artifacts. + err = u.ForceUpdate() + + // Stop logging. + log.Shutdown() + + // Remove tmp dirs + os.RemoveAll(tmpDownload) + os.RemoveAll(tmpPurge) + + return err +} diff --git a/cmds/updatemgr/mirror.go b/cmds/updatemgr/mirror.go new file mode 100644 index 00000000..1e6f049c --- /dev/null +++ b/cmds/updatemgr/mirror.go @@ -0,0 +1,215 @@ +package main + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path" + "path/filepath" + "runtime" + "strings" + "time" + + "github.com/spf13/cobra" + + "github.com/safing/portmaster/service/updates" +) + +var ( + // UserAgent is an HTTP User-Agent that is used to add + // more context to requests made by the registry when + // fetching resources from the update server. + UserAgent = fmt.Sprintf("Portmaster Update Mgr (%s %s)", runtime.GOOS, runtime.GOARCH) + + client http.Client +) + +func init() { + rootCmd.AddCommand(mirrorCmd) +} + +var ( + mirrorCmd = &cobra.Command{ + Use: "mirror [index URL] [mirror dir]", + Short: "Mirror all artifacts by an index to a directory, keeping the directory structure and file names intact", + RunE: mirror, + Args: cobra.ExactArgs(2), + } +) + +func mirror(cmd *cobra.Command, args []string) error { + // Args. + indexURL := args[0] + targetDir := args[1] + + // Check target dir. + stat, err := os.Stat(targetDir) + if err != nil { + return fmt.Errorf("failed to access target dir: %w", err) + } + if !stat.IsDir() { + return errors.New("target is not a directory") + } + + // Calculate Base URL. + u, err := url.Parse(indexURL) + if err != nil { + return fmt.Errorf("invalid index URL: %w", err) + } + indexPath := u.Path + u.RawQuery = "" + u.RawFragment = "" + u.Path = "" + u.RawPath = "" + baseURL := u.String() + "/" + + // Download Index. + fmt.Println("downloading index...") + indexData, err := downloadData(cmd.Context(), indexURL) + if err != nil { + return fmt.Errorf("download index: %w", err) + } + + // Parse (and convert) index. + var index *updates.Index + _, newIndexName := path.Split(indexPath) + switch { + case strings.HasSuffix(indexPath, ".v3.json"): + index = &updates.Index{} + err := json.Unmarshal(indexData, index) + if err != nil { + return fmt.Errorf("parse v3 index: %w", err) + } + case strings.HasSuffix(indexPath, ".v2.json"): + index, err = convertV2(indexData, baseURL) + if err != nil { + return fmt.Errorf("convert v2 index: %w", err) + } + newIndexName = strings.TrimSuffix(newIndexName, ".v2.json") + ".v3.json" + case strings.HasSuffix(indexPath, ".json"): + index, err = convertV1(indexData, baseURL, time.Now()) + if err != nil { + return fmt.Errorf("convert v1 index: %w", err) + } + newIndexName = strings.TrimSuffix(newIndexName, ".json") + ".v3.json" + default: + return errors.New("invalid index file extension") + } + + // Download and save artifacts. + for _, artifact := range index.Artifacts { + fmt.Printf("downloading %s...\n", artifact.Filename) + + // Download artifact and add any missing checksums. + artifactData, artifactLocation, err := getArtifact(cmd.Context(), artifact) + if err != nil { + return fmt.Errorf("get artifact %s: %w", artifact.Filename, err) + } + + // Write artifact to correct location. + artifactDst := filepath.Join(targetDir, filepath.FromSlash(artifactLocation)) + artifactDir, _ := filepath.Split(artifactDst) + err = os.MkdirAll(artifactDir, 0o0755) + if err != nil { + return fmt.Errorf("create artifact dir %s: %w", artifactDir, err) + } + err = os.WriteFile(artifactDst, artifactData, 0o0644) + if err != nil { + return fmt.Errorf("save artifact %s: %w", artifact.Filename, err) + } + } + + // Save index. + indexJson, err := json.MarshalIndent(index, "", " ") + if err != nil { + return fmt.Errorf("marshal index: %w", err) + } + indexDst := filepath.Join(targetDir, newIndexName) + err = os.WriteFile(indexDst, indexJson, 0o0644) + if err != nil { + return fmt.Errorf("write index to %s: %w", indexDst, err) + } + + return err +} + +func getArtifact(ctx context.Context, artifact *updates.Artifact) (artifactData []byte, artifactLocation string, err error) { + // Check URL. + if len(artifact.URLs) == 0 { + return nil, "", errors.New("no URLs defined") + } + u, err := url.Parse(artifact.URLs[0]) + if err != nil { + return nil, "", fmt.Errorf("invalid URL: %w", err) + } + + // Download data from URL. + artifactData, err = downloadData(ctx, artifact.URLs[0]) + if err != nil { + return nil, "", fmt.Errorf("GET artifact: %w", err) + } + + // Decompress artifact data, if configured. + var finalArtifactData []byte + if artifact.Unpack != "" { + finalArtifactData, err = updates.Decompress(artifact.Unpack, artifactData) + if err != nil { + return nil, "", fmt.Errorf("decompress: %w", err) + } + } else { + finalArtifactData = artifactData + } + + // Verify or generate checksum. + if artifact.SHA256 != "" { + if err := updates.CheckSHA256Sum(finalArtifactData, artifact.SHA256); err != nil { + return nil, "", err + } + } else { + fileHash := sha256.New() + if _, err := io.Copy(fileHash, bytes.NewReader(finalArtifactData)); err != nil { + return nil, "", fmt.Errorf("digest file: %w", err) + } + artifact.SHA256 = hex.EncodeToString(fileHash.Sum(nil)) + } + + return artifactData, u.Path, nil +} + +func downloadData(ctx context.Context, url string) ([]byte, error) { + // Setup request. + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody) + if err != nil { + return nil, fmt.Errorf("failed to create GET request to %s: %w", url, err) + } + if UserAgent != "" { + req.Header.Set("User-Agent", UserAgent) + } + + // Start request with shared http client. + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("failed a get file request to: %w", err) + } + defer func() { _ = resp.Body.Close() }() + + // Check for HTTP status errors. + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("server returned non-OK status: %d %s", resp.StatusCode, resp.Status) + } + + // Read the full body and return it. + content, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read body of response: %w", err) + } + return content, nil +} diff --git a/cmds/updatemgr/sign.go b/cmds/updatemgr/sign.go index 5f6d8b31..8bed7fed 100644 --- a/cmds/updatemgr/sign.go +++ b/cmds/updatemgr/sign.go @@ -69,7 +69,7 @@ func sign(cmd *cobra.Command, args []string) error { } // Parse index and check if it is valid. - index, err := updates.ParseIndex(unsignedIndexData, nil) + index, err := updates.ParseIndex(unsignedIndexData, "", nil) if err != nil { return fmt.Errorf("invalid index: %w", err) } @@ -85,7 +85,7 @@ func sign(cmd *cobra.Command, args []string) error { } // Check by parsing again. - index, err = updates.ParseIndex(signedIndexData, nil) + index, err = updates.ParseIndex(signedIndexData, "", nil) if err != nil { return fmt.Errorf("invalid index after signing: %w", err) } diff --git a/go.mod b/go.mod index ae834415..6dc63b3b 100644 --- a/go.mod +++ b/go.mod @@ -7,15 +7,15 @@ replace github.com/tc-hib/winres => github.com/dhaavi/winres v0.2.2 require ( github.com/VictoriaMetrics/metrics v1.35.1 - github.com/Xuanwo/go-locale v1.1.2 + github.com/Xuanwo/go-locale v1.1.1 github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 github.com/agext/levenshtein v1.2.3 github.com/armon/go-radix v1.0.0 github.com/awalterschulze/gographviz v2.0.3+incompatible github.com/bluele/gcache v0.0.2 github.com/brianvoe/gofakeit v3.18.0+incompatible - github.com/cilium/ebpf v0.17.1 - github.com/coreos/go-iptables v0.8.0 + github.com/cilium/ebpf v0.16.0 + github.com/coreos/go-iptables v0.7.0 github.com/davecgh/go-spew v1.1.1 github.com/dgraph-io/badger v1.6.2 github.com/florianl/go-conntrack v0.4.0 @@ -31,12 +31,11 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.7.0 - github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb - github.com/jackc/puddle/v2 v2.2.2 - github.com/lmittmann/tint v1.0.6 - github.com/maruel/panicparse/v2 v2.4.0 + github.com/jackc/puddle/v2 v2.2.1 + github.com/lmittmann/tint v1.0.5 + github.com/maruel/panicparse/v2 v2.3.1 github.com/mat/besticon v3.12.0+incompatible - github.com/mattn/go-colorable v0.1.14 + github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-isatty v0.0.20 github.com/miekg/dns v1.1.62 github.com/mitchellh/copystructure v1.2.0 @@ -55,41 +54,41 @@ require ( github.com/tannerryan/ring v1.1.2 github.com/tc-hib/winres v0.3.1 github.com/tevino/abool v1.2.0 - github.com/tidwall/gjson v1.18.0 + github.com/tidwall/gjson v1.17.3 github.com/tidwall/sjson v1.2.5 github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 - github.com/varlink/go v0.4.0 github.com/vincent-petithory/dataurl v1.0.0 - go.etcd.io/bbolt v1.3.11 - golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 - golang.org/x/image v0.23.0 - golang.org/x/net v0.34.0 - golang.org/x/sync v0.10.0 - golang.org/x/sys v0.29.0 + go.etcd.io/bbolt v1.3.10 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/image v0.19.0 + golang.org/x/net v0.28.0 + golang.org/x/sync v0.8.0 + golang.org/x/sys v0.24.0 gopkg.in/yaml.v3 v3.0.1 - zombiezen.com/go/sqlite v1.4.0 + zombiezen.com/go/sqlite v1.3.0 ) require ( - al.essio.dev/pkg/shellescape v1.5.1 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/aead/ecdh v0.2.0 // indirect + github.com/alessio/shellescape v1.4.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/danieljoos/wincred v1.2.2 // indirect - github.com/dgraph-io/ristretto v0.2.0 // indirect + github.com/danieljoos/wincred v1.2.1 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f // indirect + github.com/golang/glog v1.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -104,23 +103,23 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.9.0 // indirect + github.com/tklauser/numcpus v0.8.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zalando/go-keyring v0.2.6 // indirect + github.com/zalando/go-keyring v0.2.5 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/mod v0.22.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/tools v0.29.0 // indirect - google.golang.org/protobuf v1.36.2 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - modernc.org/libc v1.61.7 // indirect - modernc.org/mathutil v1.7.1 // indirect - modernc.org/memory v1.8.1 // indirect - modernc.org/sqlite v1.34.4 // indirect + modernc.org/libc v1.59.9 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/sqlite v1.32.0 // indirect ) diff --git a/go.sum b/go.sum index 9c99a07f..891e78b9 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho= -al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= @@ -8,14 +6,16 @@ github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/VictoriaMetrics/metrics v1.35.1 h1:o84wtBKQbzLdDy14XeskkCZih6anG+veZ1SwJHFGwrU= github.com/VictoriaMetrics/metrics v1.35.1/go.mod h1:r7hveu6xMdUACXvB8TYdAj8WEsKzWB0EkpJN+RDtOf8= -github.com/Xuanwo/go-locale v1.1.2 h1:6H+olvrQcyVOZ+GAC2rXu4armacTT4ZrFCA0mB24XVo= -github.com/Xuanwo/go-locale v1.1.2/go.mod h1:1JBER4QV7Ji39GJ4AvVlfvqmTUqopzxQxdg2mXYOw94= +github.com/Xuanwo/go-locale v1.1.1 h1:nhvzo1phY4LRwdrwVwKWXn5iZ0pMwwsa3o29yiDRuZc= +github.com/Xuanwo/go-locale v1.1.1/go.mod h1:ldC3FzZeMYALkL3YYpwhr4iVYdOIUx42kORcnAHdKUo= github.com/aead/ecdh v0.2.0 h1:pYop54xVaq/CEREFEcukHRZfTdjiWvYIsZDXXrBapQQ= github.com/aead/ecdh v0.2.0/go.mod h1:a9HHtXuSo8J1Js1MwLQx2mBhkXMT6YwUmVVEY4tTB8U= github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 h1:5L8Mj9Co9sJVgW3TpYk2gxGJnDjsYuboNTcRmbtGKGs= github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6/go.mod h1:3HgLJ9d18kXMLQlJvIY3+FszZYMxCz8WfE2MQ7hDY0w= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0= +github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -27,32 +27,32 @@ github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6 github.com/brianvoe/gofakeit v3.18.0+incompatible h1:wDOmHc9DLG4nRjUVVaxA+CEglKOW72Y5+4WNxUIkjM8= github.com/brianvoe/gofakeit v3.18.0+incompatible/go.mod h1:kfwdRA90vvNhPutZWfH7WPaDzUjz+CZFqG+rPkOjGOc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/cilium/ebpf v0.17.1 h1:G8mzU81R2JA1nE5/8SRubzqvBMmAmri2VL8BIZPWvV0= -github.com/cilium/ebpf v0.17.1/go.mod h1:vay2FaYSmIlv3r8dNACd4mW/OCaZLJKJOo+IHBvCIO8= +github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= +github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= -github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= +github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= -github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs= +github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= -github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dhaavi/winres v0.2.2 h1:SUago7FwhgLSMyDdeuV6enBZ+ZQSl0KwcnbWzvlfBls= github.com/dhaavi/winres v0.2.2/go.mod h1:1NTs+/DtKP1BplIL1+XQSoq4X1PUfLczexS7gf3x9T4= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -92,6 +92,9 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw github.com/golang/gddo v0.0.0-20180823221919-9d8ff1c67be5/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f h1:16RtHeWGkJMc80Etb8RPCcKevXGldr57+LOyZt8zOlg= github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f/go.mod h1:ijRvpgDJDI262hYq/IQVYgf8hd8IHUs93Ol0kvMBAx4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/lint v0.0.0-20170918230701-e5d664eb928e/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -130,14 +133,12 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= -github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= -github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= @@ -154,8 +155,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786 h1:N527AHMa79 github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786/go.mod h1:v4hqbTdfQngbVSZJVWUhGE/lbTFf9jb+ygmNUDQMuOs= github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM= github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= -github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= -github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -164,18 +165,21 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lmittmann/tint v1.0.6 h1:vkkuDAZXc0EFGNzYjWcV0h7eEX+uujH48f/ifSkJWgc= -github.com/lmittmann/tint v1.0.6/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/lmittmann/tint v1.0.5 h1:NQclAutOfYsqs2F1Lenue6OoWCajs5wJcP3DfWVpePw= +github.com/lmittmann/tint v1.0.5/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/maruel/panicparse/v2 v2.4.0 h1:yQKMIbQ0DKfinzVkTkcUzQyQ60UCiNnYfR7PWwTs2VI= -github.com/maruel/panicparse/v2 v2.4.0/go.mod h1:nOY2OKe8csO3F3SA5+hsxot05JLgukrF54B9x88fVp4= +github.com/maruel/panicparse/v2 v2.3.1 h1:NtJavmbMn0DyzmmSStE8yUsmPZrZmudPH7kplxBinOA= +github.com/maruel/panicparse/v2 v2.3.1/go.mod h1:s3UmQB9Fm/n7n/prcD2xBGDkwXD6y2LeZnhbEXvs9Dg= github.com/mat/besticon v3.12.0+incompatible h1:1KTD6wisfjfnX+fk9Kx/6VEZL+MAW1LhCkL9Q47H9Bg= github.com/mat/besticon v3.12.0+incompatible/go.mod h1:mA1auQYHt6CW5e7L9HJLmqVQC8SzNk2gVwouO0AbiEU= github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= @@ -201,6 +205,7 @@ github.com/mdlayher/socket v0.1.0/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5A github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs= github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -237,6 +242,8 @@ github.com/rot256/pblind v0.0.0-20240730113005-f3275049ead5 h1:R/qQ2Hw5/BgVQS87p github.com/rot256/pblind v0.0.0-20240730113005-f3275049ead5/go.mod h1:NTdpGnZ/E2cKXTiAz824w1p6OIm0mBbXcyuiYPCi/Ps= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/safing/jess v0.3.4 h1:/p6ensqEUn2jI/z1EB9JUdwH4MJQirh/C9jEwNBzxw8= +github.com/safing/jess v0.3.4/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= github.com/safing/jess v0.3.5 h1:KS5elTKfWcDUow8SUoCj5QdyyGJNoExJNySerNkbxUU= github.com/safing/jess v0.3.5/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= github.com/safing/structures v1.1.0 h1:QzHBQBjaZSLzw2f6PM4ibSmPcfBHAOB5CKJ+k4FYkhQ= @@ -269,8 +276,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spkg/zipfs v0.7.1 h1:+2X5lvNHTybnDMQZAIHgedRXZK1WXdc+94R/P5v2XWE= github.com/spkg/zipfs v0.7.1/go.mod h1:48LW+/Rh1G7aAav1ew1PdlYn52T+LM+ARmSHfDNJvg8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -282,8 +287,8 @@ github.com/tannerryan/ring v1.1.2/go.mod h1:DkELJEjbZhJBtFKR9Xziwj3HKZnb/knRgljN github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= +github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -293,8 +298,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= -github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= +github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= +github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 h1:UFHFmFfixpmfRBcxuu+LA9l8MdURWVdVNUHxO5n1d2w= github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26/go.mod h1:IGhd0qMDsUa9acVjsbsT7bu3ktadtGOHI79+idTew/M= @@ -302,8 +307,6 @@ github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= -github.com/varlink/go v0.4.0 h1:+/BQoUO9eJK/+MTSHwFcJch7TMsb6N6Dqp6g0qaXXRo= -github.com/varlink/go v0.4.0/go.mod h1:DKg9Y2ctoNkesREGAEak58l+jOC6JU2aqZvUYs5DynU= github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= @@ -318,34 +321,34 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= -github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= +github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= +github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= -go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= +go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= -golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= -golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= +golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -367,21 +370,20 @@ golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -401,6 +403,7 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -408,10 +411,14 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -419,16 +426,16 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= -golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -437,8 +444,8 @@ google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -450,29 +457,29 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= -modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0= -modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.23.10 h1:DnDZT/H6TtoJvQmVf7d8W+lVqEZpIJY/+0ENFh1LIHE= -modernc.org/ccgo/v4 v4.23.10/go.mod h1:vdN4h2WR5aEoNondUx26K7G8X+nuBscYnAEWSRmN2/0= +modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= +modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.20.7 h1:skrinQsjxWfvj6nbC3ztZPJy+NuwmB3hV9zX/pthNYQ= +modernc.org/ccgo/v4 v4.20.7/go.mod h1:UOkI3JSG2zT4E2ioHlncSOZsXbuDCZLvPi3uMlZT5GY= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.6.1 h1:+Qf6xdG8l7B27TQ8D8lw/iFMUj1RXRBOuMUWziJOsk8= -modernc.org/gc/v2 v2.6.1/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.61.7 h1:exz8rasFniviSgh3dH7QBnQHqYh9lolA5hVYfsiwkfo= -modernc.org/libc v1.61.7/go.mod h1:xspSrXRNVSfWfcfqgvZDVe/Hw5kv4FVC6IRfoms5v/0= -modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= -modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= -modernc.org/memory v1.8.1 h1:HS1HRg1jEohnuONobEq2WrLEhLyw8+J42yLFTnllm2A= -modernc.org/memory v1.8.1/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU= -modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= -modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= -modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= -modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8= -modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk= -modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= -modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= +modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/libc v1.59.9 h1:k+nNDDakwipimgmJ1D9H466LhFeSkaPPycAs1OZiDmY= +modernc.org/libc v1.59.9/go.mod h1:EY/egGEU7Ju66eU6SBqCNYaFUDuc4npICkMWnU5EE3A= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -zombiezen.com/go/sqlite v1.4.0 h1:N1s3RIljwtp4541Y8rM880qgGIgq3fTD2yks1xftnKU= -zombiezen.com/go/sqlite v1.4.0/go.mod h1:0w9F1DN9IZj9AcLS9YDKMboubCACkwYCGkzoy3eG5ik= +zombiezen.com/go/sqlite v1.3.0 h1:98g1gnCm+CNz6AuQHu0gqyw7gR2WU3O3PJufDOStpUs= +zombiezen.com/go/sqlite v1.3.0/go.mod h1:yRl27//s/9aXU3RWs8uFQwjkTG9gYNGEls6+6SvrclY= diff --git a/service/updates/downloader.go b/service/updates/downloader.go index acc94292..af51bbad 100644 --- a/service/updates/downloader.go +++ b/service/updates/downloader.go @@ -82,7 +82,7 @@ func (d *Downloader) getIndex(ctx context.Context, url string) (indexData []byte } // Verify and parse index. - bundle, err = ParseIndex(indexData, d.u.cfg.Verify) + bundle, err = ParseIndex(indexData, d.u.cfg.Platform, d.u.cfg.Verify) if err != nil { return nil, nil, fmt.Errorf("parse index: %w", err) } @@ -206,14 +206,14 @@ func (d *Downloader) getArtifact(ctx context.Context, artifact *Artifact, url st // TODO: Normally we should do operations on "untrusted" data _after_ verification, // but we really want the checksum to be for the unpacked data. Should we add another checksum, or is HTTPS enough? if artifact.Unpack != "" { - artifactData, err = decompress(artifact.Unpack, artifactData) + artifactData, err = Decompress(artifact.Unpack, artifactData) if err != nil { return nil, fmt.Errorf("decompress: %w", err) } } // Verify checksum. - if err := checkSHA256Sum(artifactData, artifact.SHA256); err != nil { + if err := CheckSHA256Sum(artifactData, artifact.SHA256); err != nil { return nil, err } @@ -250,7 +250,8 @@ func (d *Downloader) downloadData(ctx context.Context, url string) ([]byte, erro return content, nil } -func decompress(cType string, fileBytes []byte) ([]byte, error) { +// Decompress decompresses the given data according to the specified type. +func Decompress(cType string, fileBytes []byte) ([]byte, error) { switch cType { case "zip": return decompressZip(fileBytes) diff --git a/service/updates/index.go b/service/updates/index.go index cba07c14..d98d92d7 100644 --- a/service/updates/index.go +++ b/service/updates/index.go @@ -121,7 +121,8 @@ type Index struct { } // LoadIndex loads and parses an index from the given filename. -func LoadIndex(filename string, trustStore jess.TrustStore) (*Index, error) { +// Leave platform empty to use current platform. +func LoadIndex(filename string, platform string, trustStore jess.TrustStore) (*Index, error) { // Read index file from disk. content, err := os.ReadFile(filename) if err != nil { @@ -129,11 +130,12 @@ func LoadIndex(filename string, trustStore jess.TrustStore) (*Index, error) { } // Parse and return. - return ParseIndex(content, trustStore) + return ParseIndex(content, platform, trustStore) } // ParseIndex parses an index from a json string. -func ParseIndex(jsonContent []byte, trustStore jess.TrustStore) (*Index, error) { +// Leave platform empty to use current platform. +func ParseIndex(jsonContent []byte, platform string, trustStore jess.TrustStore) (*Index, error) { // Verify signature. if trustStore != nil { if err := filesig.VerifyJSONSignature(jsonContent, trustStore); err != nil { @@ -148,8 +150,13 @@ func ParseIndex(jsonContent []byte, trustStore jess.TrustStore) (*Index, error) return nil, fmt.Errorf("parse index: %w", err) } + // Check platform. + if platform == "" { + platform = currentPlatform + } + // Initialize data. - err = index.init() + err = index.init(platform) if err != nil { return nil, err } @@ -157,7 +164,7 @@ func ParseIndex(jsonContent []byte, trustStore jess.TrustStore) (*Index, error) return index, nil } -func (index *Index) init() error { +func (index *Index) init(platform string) error { // Parse version number, if set. if index.Version != "" { versionNum, err := semver.NewVersion(index.Version) @@ -167,10 +174,10 @@ func (index *Index) init() error { index.versionNum = versionNum } - // Filter artifacts by current platform. + // Filter artifacts by platform. filtered := make([]*Artifact, 0) for _, a := range index.Artifacts { - if a.Platform == "" || a.Platform == currentPlatform { + if a.Platform == "" || a.Platform == platform { filtered = append(filtered, a) } } @@ -248,7 +255,7 @@ func (index *Index) ShouldUpgradeTo(newIndex *Index) error { // VerifyArtifacts checks if all artifacts are present in the given dir and have the correct hash. func (index *Index) VerifyArtifacts(dir string) error { for _, artifact := range index.Artifacts { - err := checkSHA256SumFile(filepath.Join(dir, artifact.Filename), artifact.SHA256) + err := CheckSHA256SumFile(filepath.Join(dir, artifact.Filename), artifact.SHA256) if err != nil { return fmt.Errorf("verify %s: %w", artifact.Filename, err) } @@ -283,7 +290,8 @@ func (index *Index) Export(signingKey *jess.Signet, trustStore jess.TrustStore) return signedIndex, nil } -func checkSHA256SumFile(filename string, sha256sum string) error { +// CheckSHA256SumFile checks the sha256sum of the given file. +func CheckSHA256SumFile(filename string, sha256sum string) error { // Check expected hash. expectedDigest, err := hex.DecodeString(sha256sum) if err != nil { @@ -312,7 +320,8 @@ func checkSHA256SumFile(filename string, sha256sum string) error { return nil } -func checkSHA256Sum(fileData []byte, sha256sum string) error { +// CheckSHA256Sum checks the sha256sum of the given data. +func CheckSHA256Sum(fileData []byte, sha256sum string) error { // Check expected hash. expectedDigest, err := hex.DecodeString(sha256sum) if err != nil { diff --git a/service/updates/index_scan.go b/service/updates/index_scan.go index bc5cc0e8..1dc1a7f6 100644 --- a/service/updates/index_scan.go +++ b/service/updates/index_scan.go @@ -253,7 +253,7 @@ func GenerateIndexFromDir(sourceDir string, cfg IndexScanConfig) (*Index, error) export := make([]*Artifact, 0, len(artifacts)) for _, artifact := range artifacts { // Compute hash. - hash, err := getSHA256(artifact.localFile, artifact.Unpack) + hash, err := GetSHA256(artifact.localFile, artifact.Unpack) if err != nil { return nil, fmt.Errorf("calculate hash of file: %s %w", artifact.localFile, err) } @@ -294,7 +294,8 @@ func GenerateIndexFromDir(sourceDir string, cfg IndexScanConfig) (*Index, error) return index, nil } -func getSHA256(path string, unpackType string) (string, error) { +// GetSHA256 gets the sha256sum of the given file and unpacks it if necessary. +func GetSHA256(path string, unpackType string) (string, error) { content, err := os.ReadFile(path) if err != nil { return "", err @@ -302,7 +303,7 @@ func getSHA256(path string, unpackType string) (string, error) { // Decompress if compression was applied to the file. if unpackType != "" { - content, err = decompress(unpackType, content) + content, err = Decompress(unpackType, content) if err != nil { return "", err } diff --git a/service/updates/module.go b/service/updates/module.go index 2e008d48..fa6dc3ab 100644 --- a/service/updates/module.go +++ b/service/updates/module.go @@ -68,6 +68,8 @@ type Config struct { IndexFile string // Verify enables and specifies the trust the index signatures will be checked against. Verify jess.TrustStore + // Platform defines the platform to download artifacts for. Defaults to current platform. + Platform string // AutoCheck defines that new indexes may be downloaded automatically without outside trigger. AutoCheck bool @@ -116,6 +118,11 @@ func (cfg *Config) Check() error { } } + // Check platform. + if cfg.Platform == "" { + cfg.Platform = currentPlatform + } + return nil } @@ -168,7 +175,7 @@ func New(instance instance, name string, cfg Config) (*Updater, error) { module.upgradeWorkerMgr = m.NewWorkerMgr("upgrader", module.upgradeWorker, nil) // Load index. - index, err := LoadIndex(filepath.Join(cfg.Directory, cfg.IndexFile), cfg.Verify) + index, err := LoadIndex(filepath.Join(cfg.Directory, cfg.IndexFile), cfg.Platform, cfg.Verify) if err == nil { // Verify artifacts. if err := index.VerifyArtifacts(cfg.Directory); err != nil { @@ -186,7 +193,7 @@ func New(instance instance, name string, cfg Config) (*Updater, error) { module.corruptedInstallation = fmt.Errorf("invalid index: %w", err) } index, err = GenerateIndexFromDir(cfg.Directory, IndexScanConfig{Version: "0.0.0"}) - if err == nil && index.init() == nil { + if err == nil && index.init(currentPlatform) == nil { module.index = index return module, nil } @@ -214,7 +221,7 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV } } else { // Otherwise, load index from download dir. - downloader.index, err = LoadIndex(filepath.Join(u.cfg.DownloadDirectory, u.cfg.IndexFile), u.cfg.Verify) + downloader.index, err = LoadIndex(filepath.Join(u.cfg.DownloadDirectory, u.cfg.IndexFile), u.cfg.Platform, u.cfg.Verify) if err != nil { return fmt.Errorf("load previously downloaded index file: %w", err) } @@ -573,7 +580,7 @@ func (u *Updater) GetFiles() ([]*Artifact, error) { export := make([]*Artifact, 0, len(u.index.Artifacts)) for _, artifact := range u.index.Artifacts { switch { - case artifact.Platform != "" && artifact.Platform != currentPlatform: + case artifact.Platform != "" && artifact.Platform != u.cfg.Platform: // Platform is defined and does not match. // Platforms are usually pre-filtered, but just to be sure. default: @@ -604,7 +611,7 @@ func (u *Updater) GetFile(name string) (*Artifact, error) { switch { case artifact.Filename != name: // Name does not match. - case artifact.Platform != "" && artifact.Platform != currentPlatform: + case artifact.Platform != "" && artifact.Platform != u.cfg.Platform: // Platform is defined and does not match. // Platforms are usually pre-filtered, but just to be sure. default: diff --git a/service/updates/updates_test.go b/service/updates/updates_test.go index d79706c7..9dea5886 100644 --- a/service/updates/updates_test.go +++ b/service/updates/updates_test.go @@ -84,7 +84,7 @@ func TestPerformUpdate(t *testing.T) { } if data, err := os.ReadFile(filepath.Join(updateDir, "index.json")); err == nil { fmt.Println(string(data)) - idx, err := ParseIndex(data, nil) + idx, err := ParseIndex(data, updater.cfg.Platform, nil) if err == nil { fmt.Println(idx.Version) fmt.Println(idx.versionNum) @@ -97,7 +97,7 @@ func TestPerformUpdate(t *testing.T) { }) // Check if the current version is now the new. - newIndex, err := LoadIndex(filepath.Join(installedDir, "index.json"), nil) + newIndex, err := LoadIndex(filepath.Join(installedDir, "index.json"), updater.cfg.Platform, nil) if err != nil { t.Fatal(err) } From b3de7da9f7c94c83d01fced164f6d8b70ba4c6a9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Jan 2025 09:20:00 +0100 Subject: [PATCH 58/63] Use real assets in release CI --- .github/workflows/release.yml | 6 +++ Earthfile | 45 +++++++------------ .../windows/generate_windows_installers.ps1 | 9 ++-- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2ec7fa30..f3e44e08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,12 @@ name: Release on: workflow_dispatch: + push: + paths: + - 'desktop/angular/**' + branches: + - v2.0 + - feature/new-installer jobs: release-prep: diff --git a/Earthfile b/Earthfile index 1828867b..a0ef369a 100644 --- a/Earthfile +++ b/Earthfile @@ -529,45 +529,34 @@ release-prep: COPY (+tauri-build/output/portmaster.exe --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/portmaster.exe COPY (+tauri-build/output/WebView2Loader.dll --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/WebView2Loader.dll COPY (+go-build/output/portmaster-core.exe --GOARCH=amd64 --GOOS=windows --CMDS=portmaster-core) ./output/binary/windows_amd64/portmaster-core.exe - RUN cp dist/windows_amd64/portmaster-kext.sys ./output/binary/windows_amd64/portmaster-kext.sys - RUN cp dist/windows_amd64/portmaster-core.dll ./output/binary/windows_amd64/portmaster-core.dll # All platforms COPY (+assets/assets.zip) ./output/binary/all/assets.zip COPY (+angular-project/output/portmaster.zip --project=portmaster --dist=./dist --configuration=production --baseHref=/ui/modules/portmaster/) ./output/binary/all/portmaster.zip - # Intel - RUN mkdir -p ./output/intel - RUN cp "dist/intel/geoipv4.mmdb.gz" ./output/intel/geoipv4.mmdb.gz - RUN cp "dist/intel/geoipv6.mmdb.gz" ./output/intel/geoipv6.mmdb.gz - RUN cp "dist/intel/index.dsd" ./output/intel/index.dsd - RUN cp "dist/intel/base.dsdl" ./output/intel/base.dsdl - RUN cp "dist/intel/intermediate.dsdl" ./output/intel/intermediate.dsdl - RUN cp "dist/intel/urgent.dsdl" ./output/intel/urgent.dsdl - - # Genereate index files + # Build update manager COPY (+go-build/output/updatemgr --GOARCH=amd64 --GOOS=linux --CMDS=updatemgr) ./updatemgr + + # Get binary artifacts from current release + RUN mkdir ./output/download/windows_amd64 && ./updatemgr download https://updates.safing.io/stable.v3.json --platform windows_amd64 ./output/download/windows_amd64 + + # Copy required artifacts + RUN cp ./output/download/windows_amd64/portmaster-kext.sys ./output/binary/windows_amd64/portmaster-kext.sys + RUN cp ./output/download/windows_amd64/portmaster-kext.pdb ./output/binary/windows_amd64/portmaster-kext.pdb + RUN cp ./output/download/windows_amd64/portmaster-kext.dll ./output/binary/windows_amd64/portmaster-kext.dll + + # Create new binary index from artifacts RUN ./updatemgr scan --dir "./output/binary" > ./output/binary/index.json - RUN ./updatemgr scan --dir "./output/intel" > ./output/intel/index.json - - # Intel Extracted (needed for the installers) - RUN mkdir -p ./output/intel_decompressed - RUN cp output/intel/index.json ./output/intel_decompressed/index.json - - RUN gzip -dc dist/intel/geoipv4.mmdb.gz > ./output/intel_decompressed/geoipv4.mmdb - RUN gzip -dc dist/intel/geoipv6.mmdb.gz > ./output/intel_decompressed/geoipv6.mmdb - RUN cp dist/intel/index.dsd ./output/intel_decompressed/index.dsd - RUN cp dist/intel/base.dsdl ./output/intel_decompressed/base.dsdl - RUN cp dist/intel/intermediate.dsdl ./output/intel_decompressed/intermediate.dsdl - RUN cp dist/intel/urgent.dsdl ./output/intel_decompressed/urgent.dsdl + + # Get intel index and assets + RUN mkdir ./output/intel && ./updatemgr download https://updates.safing.io/intel.v3.json ./output/intel # Save all artifacts to output folder SAVE ARTIFACT --if-exists --keep-ts "output/binary/index.json" AS LOCAL "${outputDir}/binary/index.json" SAVE ARTIFACT --if-exists --keep-ts "output/binary/all/*" AS LOCAL "${outputDir}/binary/all/" SAVE ARTIFACT --if-exists --keep-ts "output/binary/linux_amd64/*" AS LOCAL "${outputDir}/binary/linux_amd64/" SAVE ARTIFACT --if-exists --keep-ts "output/binary/windows_amd64/*" AS LOCAL "${outputDir}/binary/windows_amd64/" - # SAVE ARTIFACT --if-exists --keep-ts "output/intel/*" AS LOCAL "${outputDir}/intel/" - SAVE ARTIFACT --if-exists --keep-ts "output/intel_decompressed/*" AS LOCAL "${outputDir}/intel_decompressed/" + SAVE ARTIFACT --if-exists --keep-ts "output/intel/*" AS LOCAL "${outputDir}/intel/" # Save all artifacts to the container output folder so other containers can access it. SAVE ARTIFACT --if-exists --keep-ts "output/binary/index.json" "output/binary/index.json" @@ -575,7 +564,7 @@ release-prep: SAVE ARTIFACT --if-exists --keep-ts "output/binary/linux_amd64/*" "output/binary/linux_amd64/" SAVE ARTIFACT --if-exists --keep-ts "output/binary/windows_amd64/*" "output/binary/windows_amd64/" SAVE ARTIFACT --if-exists --keep-ts "output/intel/*" "output/intel/" - SAVE ARTIFACT --if-exists --keep-ts "output/intel_decompressed/*" "output/intel_decompressed/" + SAVE ARTIFACT --if-exists --keep-ts "output/download/*" "output/download/" installer-linux: FROM +rust-base @@ -605,7 +594,7 @@ installer-linux: # Download the intel data RUN mkdir -p intel - COPY (+release-prep/output/intel_decompressed/*) ./intel/ + COPY (+release-prep/output/intel/*) ./intel/ # build the installers RUN cargo tauri bundle --ci --target="${target}" diff --git a/packaging/windows/generate_windows_installers.ps1 b/packaging/windows/generate_windows_installers.ps1 index 407a8cc3..6fec1212 100644 --- a/packaging/windows/generate_windows_installers.ps1 +++ b/packaging/windows/generate_windows_installers.ps1 @@ -19,11 +19,10 @@ if (-not (Test-Path -Path $binaryDir)) { New-Item -ItemType Directory -Path $binaryDir > $null } - Write-Output "Copying binary files" -Copy-Item -Force -Path "dist/binary/index.json" -Destination "$binaryDir/index.json" -Copy-Item -Force -Path "dist/binary/windows_amd64/portmaster-core.exe" -Destination "$binaryDir/portmaster-core.exe" -Copy-Item -Force -Path "dist/binary/windows_amd64/portmaster-kext.sys" -Destination "$binaryDir/portmaster-kext.sys" +Copy-Item -Force -Path "dist/download/windows_amd64/portmaster-core.exe" -Destination "$binaryDir/portmaster-core.exe" +Copy-Item -Force -Path "dist/download/windows_amd64/portmaster-kext.sys" -Destination "$binaryDir/portmaster-kext.sys" +Copy-Item -Force -Path "dist/download/windows_amd64/portmaster-kext.dll" -Destination "$binaryDir/portmaster-kext.dll" Copy-Item -Force -Path "dist/binary/all/portmaster.zip" -Destination "$binaryDir/portmaster.zip" Copy-Item -Force -Path "dist/binary/all/assets.zip" -Destination "$binaryDir/assets.zip" @@ -39,7 +38,7 @@ if (-not (Test-Path -Path $intelDir)) { } Write-Output "Copying intel files" -Copy-Item -Force -Path "dist/intel_decompressed/*" -Destination "$intelDir/" +Copy-Item -Force -Path "dist/intel/*" -Destination "$intelDir/" Set-Location $destinationDir From 73552bd9b580b6db95947d631fb50634eacc2cbf Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 27 Jan 2025 14:41:12 +0100 Subject: [PATCH 59/63] Upload installers as GitHub artifacts after build --- .github/workflows/release.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f3e44e08..d89171fc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,13 +1,13 @@ name: Release on: - workflow_dispatch: push: - paths: - - 'desktop/angular/**' branches: - v2.0 - feature/new-installer + tags: + - v* + workflow_dispatch: jobs: release-prep: @@ -32,7 +32,6 @@ jobs: - name: Upload Dist uses: actions/upload-artifact@v4 with: - name: dist path: ./dist/ if-no-files-found: error @@ -57,6 +56,12 @@ jobs: run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +installer-linux # --ci include --no-output flag + - name: Upload Installers + uses: actions/upload-artifact@v4 + with: + path: ./dist/linux_amd64/ + if-no-files-found: error + installer-windows: name: Installer windows runs-on: windows-latest @@ -68,9 +73,13 @@ jobs: - name: Download Dist uses: actions/download-artifact@v4 with: - name: dist path: dist/ - name: Build windows artifacts run: powershell -NoProfile -File ./packaging/windows/generate_windows_installers.ps1 + - name: Upload Installers + uses: actions/upload-artifact@v4 + with: + path: ./dist/windows_amd64/ + if-no-files-found: error From 30bbe2a1ea8a8f676d11aa4c2251a8a05fde7ddb Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 27 Jan 2025 14:48:58 +0100 Subject: [PATCH 60/63] Lock tauri cargo install --- Earthfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Earthfile b/Earthfile index a0ef369a..d668c06e 100644 --- a/Earthfile +++ b/Earthfile @@ -425,7 +425,7 @@ rust-base: DO rust+INIT --keep_fingerprints=true - DO rust+CARGO --args="install tauri-cli --version 2.1.0" + DO rust+CARGO --args="install tauri-cli --version 2.1.0 --locked" # Explicitly cache here. SAVE IMAGE --cache-hint From d824b17b87af3e4b4dd13bb480e76e77d4a85a40 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 27 Jan 2025 15:09:05 +0100 Subject: [PATCH 61/63] Update go.mod --- go.mod | 2 ++ go.sum | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 6dc63b3b..bdc5fa96 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.7.0 + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb github.com/jackc/puddle/v2 v2.2.1 github.com/lmittmann/tint v1.0.5 github.com/maruel/panicparse/v2 v2.3.1 @@ -57,6 +58,7 @@ require ( github.com/tidwall/gjson v1.17.3 github.com/tidwall/sjson v1.2.5 github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 + github.com/varlink/go v0.4.0 github.com/vincent-petithory/dataurl v1.0.0 go.etcd.io/bbolt v1.3.10 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa diff --git a/go.sum b/go.sum index 891e78b9..2d05e593 100644 --- a/go.sum +++ b/go.sum @@ -133,6 +133,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -242,8 +244,6 @@ github.com/rot256/pblind v0.0.0-20240730113005-f3275049ead5 h1:R/qQ2Hw5/BgVQS87p github.com/rot256/pblind v0.0.0-20240730113005-f3275049ead5/go.mod h1:NTdpGnZ/E2cKXTiAz824w1p6OIm0mBbXcyuiYPCi/Ps= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/safing/jess v0.3.4 h1:/p6ensqEUn2jI/z1EB9JUdwH4MJQirh/C9jEwNBzxw8= -github.com/safing/jess v0.3.4/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= github.com/safing/jess v0.3.5 h1:KS5elTKfWcDUow8SUoCj5QdyyGJNoExJNySerNkbxUU= github.com/safing/jess v0.3.5/go.mod h1:+B6UJnXVxi406Wk08SDnoC5NNBL7t3N0vZGokEbkVQI= github.com/safing/structures v1.1.0 h1:QzHBQBjaZSLzw2f6PM4ibSmPcfBHAOB5CKJ+k4FYkhQ= @@ -276,6 +276,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spkg/zipfs v0.7.1 h1:+2X5lvNHTybnDMQZAIHgedRXZK1WXdc+94R/P5v2XWE= github.com/spkg/zipfs v0.7.1/go.mod h1:48LW+/Rh1G7aAav1ew1PdlYn52T+LM+ARmSHfDNJvg8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -307,6 +309,8 @@ github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= +github.com/varlink/go v0.4.0 h1:+/BQoUO9eJK/+MTSHwFcJch7TMsb6N6Dqp6g0qaXXRo= +github.com/varlink/go v0.4.0/go.mod h1:DKg9Y2ctoNkesREGAEak58l+jOC6JU2aqZvUYs5DynU= github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= @@ -384,6 +388,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From 0f28af66cd3104c7e9e488f9b463f2c37075f73f Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Mon, 27 Jan 2025 17:21:54 +0200 Subject: [PATCH 62/63] Add PID in ETW DNS event in the integration dll (#1768) * [service] Add reading of PID in ETW DNS event * [service] Use PID of the ETW DNS events * [service] Fix use of nil pointer * [service] Fix compiler error --- .../interception/dnsmonitor/etwlink_windows.go | 10 +++++----- .../dnsmonitor/eventlistener_linux.go | 2 +- .../dnsmonitor/eventlistener_windows.go | 15 +++++++++++++-- .../firewall/interception/dnsmonitor/module.go | 4 ++-- service/network/connection.go | 10 +++++++++- windows_core_dll/dllmain.cpp | 8 ++++---- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/service/firewall/interception/dnsmonitor/etwlink_windows.go b/service/firewall/interception/dnsmonitor/etwlink_windows.go index cb9d8675..6f9bd16d 100644 --- a/service/firewall/interception/dnsmonitor/etwlink_windows.go +++ b/service/firewall/interception/dnsmonitor/etwlink_windows.go @@ -22,8 +22,8 @@ type ETWSession struct { state uintptr } -// NewSession creates new ETW event listener and initilizes it. This is a low level interface, make sure to call DestorySession when you are done using it. -func NewSession(etwInterface *integration.ETWFunctions, callback func(domain string, result string)) (*ETWSession, error) { +// NewSession creates new ETW event listener and initializes it. This is a low level interface, make sure to call DestroySession when you are done using it. +func NewSession(etwInterface *integration.ETWFunctions, callback func(domain string, pid uint32, result string)) (*ETWSession, error) { if etwInterface == nil { return nil, fmt.Errorf("etw interface was nil") } @@ -35,8 +35,8 @@ func NewSession(etwInterface *integration.ETWFunctions, callback func(domain str _ = etwSession.i.StopOldSession() // Initialize notification activated callback - win32Callback := windows.NewCallback(func(domain *uint16, result *uint16) uintptr { - callback(windows.UTF16PtrToString(domain), windows.UTF16PtrToString(result)) + win32Callback := windows.NewCallback(func(domain *uint16, pid uint32, result *uint16) uintptr { + callback(windows.UTF16PtrToString(domain), pid, windows.UTF16PtrToString(result)) return 0 }) // The function only allocates memory it will not fail. @@ -83,7 +83,7 @@ func (l *ETWSession) FlushTrace() error { return l.i.FlushTrace(l.state) } -// StopTrace stopes the trace. This will cause StartTrace to return. +// StopTrace stops the trace. This will cause StartTrace to return. func (l *ETWSession) StopTrace() error { return l.i.StopTrace(l.state) } diff --git a/service/firewall/interception/dnsmonitor/eventlistener_linux.go b/service/firewall/interception/dnsmonitor/eventlistener_linux.go index 6e9bb3ee..f4fc99a0 100644 --- a/service/firewall/interception/dnsmonitor/eventlistener_linux.go +++ b/service/firewall/interception/dnsmonitor/eventlistener_linux.go @@ -141,5 +141,5 @@ func (l *Listener) processAnswer(domain string, queryResult *QueryResult) { } } - saveDomain(domain, ips, cnames) + saveDomain(domain, ips, cnames, resolver.IPInfoProfileScopeGlobal) } diff --git a/service/firewall/interception/dnsmonitor/eventlistener_windows.go b/service/firewall/interception/dnsmonitor/eventlistener_windows.go index a46e8cc6..d71c3c43 100644 --- a/service/firewall/interception/dnsmonitor/eventlistener_windows.go +++ b/service/firewall/interception/dnsmonitor/eventlistener_windows.go @@ -4,6 +4,7 @@ package dnsmonitor import ( + "context" "fmt" "net" "strconv" @@ -11,6 +12,7 @@ import ( "github.com/miekg/dns" "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/process" "github.com/safing/portmaster/service/resolver" ) @@ -79,7 +81,7 @@ func (l *Listener) stop() error { return nil } -func (l *Listener) processEvent(domain string, result string) { +func (l *Listener) processEvent(domain string, pid uint32, result string) { if processIfSelfCheckDomain(dns.Fqdn(domain)) { // Not need to process result. return @@ -90,6 +92,15 @@ func (l *Listener) processEvent(domain string, result string) { return } + profileScope := resolver.IPInfoProfileScopeGlobal + // Get the profile ID if the process can be found + if proc, err := process.GetOrFindProcess(context.Background(), int(pid)); err == nil { + if profile := proc.Profile(); profile != nil { + if localProfile := profile.LocalProfile(); localProfile != nil { + profileScope = localProfile.ID + } + } + } cnames := make(map[string]string) ips := []net.IP{} @@ -115,5 +126,5 @@ func (l *Listener) processEvent(domain string, result string) { } } } - saveDomain(domain, ips, cnames) + saveDomain(domain, ips, cnames, profileScope) } diff --git a/service/firewall/interception/dnsmonitor/module.go b/service/firewall/interception/dnsmonitor/module.go index 974429f7..918d1e88 100644 --- a/service/firewall/interception/dnsmonitor/module.go +++ b/service/firewall/interception/dnsmonitor/module.go @@ -61,7 +61,7 @@ func (dl *DNSMonitor) Flush() error { return dl.listener.flush() } -func saveDomain(domain string, ips []net.IP, cnames map[string]string) { +func saveDomain(domain string, ips []net.IP, cnames map[string]string, profileScope string) { fqdn := dns.Fqdn(domain) // Create new record for this IP. record := resolver.ResolvedDomain{ @@ -75,7 +75,7 @@ func saveDomain(domain string, ips []net.IP, cnames map[string]string) { record.AddCNAMEs(cnames) // Add to cache - saveIPsInCache(ips, resolver.IPInfoProfileScopeGlobal, record) + saveIPsInCache(ips, profileScope, record) } func New(instance instance) (*DNSMonitor, error) { diff --git a/service/network/connection.go b/service/network/connection.go index 1c1bbf19..2cdf12e7 100644 --- a/service/network/connection.go +++ b/service/network/connection.go @@ -538,8 +538,9 @@ func (conn *Connection) GatherConnectionInfo(pkt packet.Packet) (err error) { // Find domain and DNS context of entity. if conn.Entity.Domain == "" && conn.process.Profile() != nil { + profileScope := conn.process.Profile().LocalProfile().ID // check if we can find a domain for that IP - ipinfo, err := resolver.GetIPInfo(conn.process.Profile().LocalProfile().ID, pkt.Info().RemoteIP().String()) + ipinfo, err := resolver.GetIPInfo(profileScope, pkt.Info().RemoteIP().String()) if err != nil { // Try again with the global scope, in case DNS went through the system resolver. ipinfo, err = resolver.GetIPInfo(resolver.IPInfoProfileScopeGlobal, pkt.Info().RemoteIP().String()) @@ -555,6 +556,13 @@ func (conn *Connection) GatherConnectionInfo(pkt packet.Packet) (err error) { // Error flushing, dont try again. break } + // Try with profile scope + ipinfo, err = resolver.GetIPInfo(profileScope, pkt.Info().RemoteIP().String()) + if err == nil { + log.Tracer(pkt.Ctx()).Debugf("network: found domain with scope (%s) from dnsmonitor after %d tries", profileScope, +1) + break + } + // Try again with the global scope ipinfo, err = resolver.GetIPInfo(resolver.IPInfoProfileScopeGlobal, pkt.Info().RemoteIP().String()) if err == nil { log.Tracer(pkt.Ctx()).Debugf("network: found domain from dnsmonitor after %d tries", i+1) diff --git a/windows_core_dll/dllmain.cpp b/windows_core_dll/dllmain.cpp index cc0efaac..7674539f 100644 --- a/windows_core_dll/dllmain.cpp +++ b/windows_core_dll/dllmain.cpp @@ -22,7 +22,7 @@ static const GUID PORTMASTER_ETW_SESSION_GUID = { #define LOGSESSION_NAME L"PortmasterDNSEventListener" // Fuction type of the callback that will be called on each event. -typedef uint64_t(*GoEventRecordCallback)(wchar_t* domain, wchar_t* result); +typedef uint64_t(*GoEventRecordCallback)(wchar_t* domain, uint32_t pid, wchar_t* result); // Holds the state of the ETW Session. struct ETWSessionState { @@ -41,7 +41,7 @@ static bool getPropertyValue(PEVENT_RECORD evt, LPWSTR prop, PBYTE* pData) { DataDescriptor.ArrayIndex = 0; DWORD PropertySize = 0; - // Check if the data is avaliable and what is the size of it. + // Check if the data is available and what is the size of it. DWORD status = TdhGetPropertySize(evt, 0, NULL, 1, &DataDescriptor, &PropertySize); if (ERROR_SUCCESS != status) { @@ -79,7 +79,7 @@ static void WINAPI EventRecordCallback(PEVENT_RECORD eventRecord) { ETWSessionState* state = (ETWSessionState*)eventRecord->UserContext; if (resultValue != NULL && domainValue != NULL) { - state->callback((wchar_t*)domainValue, (wchar_t*)resultValue); + state->callback((wchar_t*)domainValue, eventRecord->EventHeader.ProcessId, (wchar_t*)resultValue); } free(resultValue); @@ -160,7 +160,7 @@ extern "C" { EVENT_TRACE_CONTROL_STOP); } - // PM_ETWFlushTrace Closes the session and frees resourses. + // PM_ETWFlushTrace Closes the session and frees recourses. __declspec(dllexport) uint32_t PM_ETWDestroySession(ETWSessionState* state) { if (state == NULL) { return 1; From 7aeaeae61cd9290c81302184c521bb0b058f6247 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 29 Jan 2025 15:34:34 +0100 Subject: [PATCH 63/63] Fix release-prep earthly build --- Earthfile | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Earthfile b/Earthfile index 3f4033c5..dae6aa93 100644 --- a/Earthfile +++ b/Earthfile @@ -519,8 +519,6 @@ release-prep: FROM +rust-base WORKDIR /app - COPY ./dist/intel ./dist/intel - COPY ./dist/windows_amd64 ./dist/windows_amd64 # Linux specific COPY (+tauri-build/output/portmaster --target="x86_64-unknown-linux-gnu") ./output/binary/linux_amd64/portmaster @@ -539,18 +537,18 @@ release-prep: COPY (+go-build/output/updatemgr --GOARCH=amd64 --GOOS=linux --CMDS=updatemgr) ./updatemgr # Get binary artifacts from current release - RUN mkdir ./output/download/windows_amd64 && ./updatemgr download https://updates.safing.io/stable.v3.json --platform windows_amd64 ./output/download/windows_amd64 + RUN mkdir -p ./output/download/windows_amd64 && ./updatemgr download https://updates.safing.io/stable.v3.json --platform windows_amd64 ./output/download/windows_amd64 # Copy required artifacts RUN cp ./output/download/windows_amd64/portmaster-kext.sys ./output/binary/windows_amd64/portmaster-kext.sys RUN cp ./output/download/windows_amd64/portmaster-kext.pdb ./output/binary/windows_amd64/portmaster-kext.pdb - RUN cp ./output/download/windows_amd64/portmaster-kext.dll ./output/binary/windows_amd64/portmaster-kext.dll + RUN cp ./output/download/windows_amd64/portmaster-core.dll ./output/binary/windows_amd64/portmaster-core.dll # Create new binary index from artifacts RUN ./updatemgr scan --dir "./output/binary" > ./output/binary/index.json - + # Get intel index and assets - RUN mkdir ./output/intel && ./updatemgr download https://updates.safing.io/intel.v3.json ./output/intel + RUN mkdir -p ./output/intel && ./updatemgr download https://updates.safing.io/intel.v3.json ./output/intel # Save all artifacts to output folder SAVE ARTIFACT --if-exists --keep-ts "output/binary/index.json" AS LOCAL "${outputDir}/binary/index.json"