diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | gui/locales/messages.pot | 27 | ||||
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 4 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/CustomDnsSettings.tsx | 21 | ||||
| -rw-r--r-- | gui/src/renderer/components/Preferences.tsx | 58 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/reducers.ts | 2 | ||||
| -rw-r--r-- | gui/src/shared/daemon-rpc-types.ts | 2 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/dns.rs | 23 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 14 | ||||
| -rw-r--r-- | mullvad-management-interface/proto/management_interface.proto | 2 | ||||
| -rw-r--r-- | mullvad-management-interface/src/types.rs | 4 | ||||
| -rw-r--r-- | mullvad-types/src/settings/mod.rs | 2 |
13 files changed, 132 insertions, 30 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ed1b7796f..3e0c9bbe91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Line wrap the file at 100 chars. Th ## [Unreleased] ### Added +- Extend DNS blocking with the following new categories: "Adult content" and "gambling". - Obfuscate traffic to the Mullvad API using bridges if it cannot be reached directly. - Add device management to desktop app. This simplifies knowing which device is which and adds the option to log out other devices when there are already 5 connected when logging in. diff --git a/gui/locales/messages.pot b/gui/locales/messages.pot index 7de976a7e4..e61ed3eb0a 100644 --- a/gui/locales/messages.pot +++ b/gui/locales/messages.pot @@ -969,23 +969,19 @@ msgid "Block ads" msgstr "" msgctxt "preferences-view" -msgid "Block malware" +msgid "Block adult content" msgstr "" msgctxt "preferences-view" -msgid "Block trackers" +msgid "Block gambling" +msgstr "" + +msgctxt "preferences-view" +msgid "Block malware" msgstr "" -#. This is displayed when either or both of the block ads/trackers settings are -#. turned on which makes the custom DNS setting disabled. The text enclosed in "**" -#. will appear bold. -#. Available placeholders: -#. %(blockAdsFeatureName)s - The name displayed next to the "Block ads" toggle. -#. %(blockTrackersFeatureName)s - The name displayed next to the "Block trackers" toggle. -#. %(blockMalwareFeatureName)s - The name displayed next to the "Block malware" toggle. -#. %(preferencesPageName)s - The page title showed on top in the preferences page. msgctxt "preferences-view" -msgid "Disable **%(blockAdsFeatureName)s**, **%(blockTrackersFeatureName)s** and **%(blockMalwareFeatureName)s** (under %(preferencesPageName)s) to activate this setting." +msgid "Block trackers" msgstr "" #. This is displayed when the custom DNS setting is turned on which makes the block @@ -997,6 +993,15 @@ msgctxt "preferences-view" msgid "Disable **%(customDnsFeatureName)s** (under Advanced settings) to activate these settings." msgstr "" +#. This is displayed when either or both of the block ads/trackers settings are +#. turned on which makes the custom DNS setting disabled. The text enclosed in "**" +#. will appear bold. +#. Available placeholders: +#. %(preferencesPageName)s - The page title showed on top in the preferences page. +msgctxt "preferences-view" +msgid "Disable all content blockers (under %(preferencesPageName)s) to activate this setting." +msgstr "" + msgctxt "preferences-view" msgid "Enable or disable system notifications. The critical notifications will always be displayed." msgstr "" diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index 52c43441a6..029936093f 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -463,6 +463,8 @@ export class DaemonRpc { defaultOptions.setBlockAds(dns.defaultOptions.blockAds); defaultOptions.setBlockTrackers(dns.defaultOptions.blockTrackers); defaultOptions.setBlockMalware(dns.defaultOptions.blockMalware); + defaultOptions.setBlockAdultContent(dns.defaultOptions.blockAdultContent); + defaultOptions.setBlockGambling(dns.defaultOptions.blockGambling); dnsOptions.setDefaultOptions(defaultOptions); const customOptions = new grpcTypes.CustomDnsOptions(); @@ -1131,6 +1133,8 @@ function convertFromTunnelOptions(tunnelOptions: grpcTypes.TunnelOptions.AsObjec blockAds: tunnelOptions.dnsOptions?.defaultOptions?.blockAds ?? false, blockTrackers: tunnelOptions.dnsOptions?.defaultOptions?.blockTrackers ?? false, blockMalware: tunnelOptions.dnsOptions?.defaultOptions?.blockMalware ?? false, + blockAdultContent: tunnelOptions.dnsOptions?.defaultOptions?.blockAdultContent ?? false, + blockGambling: tunnelOptions.dnsOptions?.defaultOptions?.blockGambling ?? false, }, customOptions: { addresses: tunnelOptions.dnsOptions?.customOptions?.addressesList ?? [], diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index 8acdac16a0..c1fb5407f7 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -197,6 +197,8 @@ class ApplicationMain { blockAds: false, blockTrackers: false, blockMalware: false, + blockAdultContent: false, + blockGambling: false, }, customOptions: { addresses: [], diff --git a/gui/src/renderer/components/CustomDnsSettings.tsx b/gui/src/renderer/components/CustomDnsSettings.tsx index 3ab38cf3c3..9c976062c1 100644 --- a/gui/src/renderer/components/CustomDnsSettings.tsx +++ b/gui/src/renderer/components/CustomDnsSettings.tsx @@ -49,7 +49,9 @@ export default function CustomDnsSettings() { dns.state === 'custom' || (!dns.defaultOptions.blockAds && !dns.defaultOptions.blockTrackers && - !dns.defaultOptions.blockMalware), + !dns.defaultOptions.blockMalware && + !dns.defaultOptions.blockAdultContent && + !dns.defaultOptions.blockGambling), [dns], ); @@ -281,32 +283,19 @@ export default function CustomDnsSettings() { } function DisabledMessage() { - const blockAdsFeatureName = messages.pgettext('preferences-view', 'Block ads'); - const blockTrackersFeatureName = messages.pgettext('preferences-view', 'Block trackers'); - const blockMalwareFeatureName = messages.pgettext('preferences-view', 'Block malware'); const preferencesPageName = messages.pgettext('preferences-nav', 'Preferences'); // TRANSLATORS: This is displayed when either or both of the block ads/trackers settings are // TRANSLATORS: turned on which makes the custom DNS setting disabled. The text enclosed in "**" // TRANSLATORS: will appear bold. // TRANSLATORS: Available placeholders: - // TRANSLATORS: %(blockAdsFeatureName)s - The name displayed next to the "Block ads" toggle. - // TRANSLATORS: %(blockTrackersFeatureName)s - The name displayed next to the "Block trackers" toggle. - // TRANSLATORS: %(blockMalwareFeatureName)s - The name displayed next to the "Block malware" toggle. // TRANSLATORS: %(preferencesPageName)s - The page title showed on top in the preferences page. const customDnsDisabledMessage = messages.pgettext( 'preferences-view', - 'Disable **%(blockAdsFeatureName)s**, **%(blockTrackersFeatureName)s** and **%(blockMalwareFeatureName)s** (under %(preferencesPageName)s) to activate this setting.', + 'Disable all content blockers (under %(preferencesPageName)s) to activate this setting.', ); - return formatMarkdown( - sprintf(customDnsDisabledMessage, { - blockAdsFeatureName, - blockTrackersFeatureName, - blockMalwareFeatureName, - preferencesPageName, - }), - ); + return formatMarkdown(sprintf(customDnsDisabledMessage, { preferencesPageName })); } interface ICellListItemProps { diff --git a/gui/src/renderer/components/Preferences.tsx b/gui/src/renderer/components/Preferences.tsx index 9213c7c7e9..0d6fea3809 100644 --- a/gui/src/renderer/components/Preferences.tsx +++ b/gui/src/renderer/components/Preferences.tsx @@ -181,6 +181,44 @@ export default class Preferences extends React.Component<IProps, IState> { /> </AriaInput> </Cell.Container> + </AriaInputGroup> + <StyledSeparator /> + <AriaInputGroup> + <Cell.Container disabled={this.props.dns.state === 'custom'}> + <AriaLabel> + <Cell.InputLabel> + {messages.pgettext('preferences-view', 'Block adult content')} + </Cell.InputLabel> + </AriaLabel> + <AriaInput> + <Cell.Switch + isOn={ + this.props.dns.state === 'default' && + this.props.dns.defaultOptions.blockAdultContent + } + onChange={this.setBlockAdultContent} + /> + </AriaInput> + </Cell.Container> + </AriaInputGroup> + <StyledSeparator /> + <AriaInputGroup> + <Cell.Container disabled={this.props.dns.state === 'custom'}> + <AriaLabel> + <Cell.InputLabel> + {messages.pgettext('preferences-view', 'Block gambling')} + </Cell.InputLabel> + </AriaLabel> + <AriaInput> + <Cell.Switch + isOn={ + this.props.dns.state === 'default' && + this.props.dns.defaultOptions.blockGambling + } + onChange={this.setBlockGambling} + /> + </AriaInput> + </Cell.Container> {this.props.dns.state === 'custom' && <CustomDnsEnabledFooter />} </AriaInputGroup> @@ -404,6 +442,26 @@ export default class Preferences extends React.Component<IProps, IState> { }); }; + private setBlockAdultContent = async (enabled: boolean) => { + await this.props.setDnsOptions({ + ...this.props.dns, + defaultOptions: { + ...this.props.dns.defaultOptions, + blockAdultContent: enabled, + }, + }); + }; + + private setBlockGambling = async (enabled: boolean) => { + await this.props.setDnsOptions({ + ...this.props.dns, + defaultOptions: { + ...this.props.dns.defaultOptions, + blockGambling: enabled, + }, + }); + }; + private showKillSwitchInfo = () => { this.setState({ showKillSwitchInfo: true }); }; diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts index 3d665ba86b..1c759e1a52 100644 --- a/gui/src/renderer/redux/settings/reducers.ts +++ b/gui/src/renderer/redux/settings/reducers.ts @@ -138,6 +138,8 @@ const initialState: ISettingsReduxState = { blockAds: false, blockTrackers: false, blockMalware: false, + blockAdultContent: false, + blockGambling: false, }, customOptions: { addresses: [], diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts index b08f375e96..dc3088cc80 100644 --- a/gui/src/shared/daemon-rpc-types.ts +++ b/gui/src/shared/daemon-rpc-types.ts @@ -290,6 +290,8 @@ export interface IDnsOptions { blockAds: boolean; blockTrackers: boolean; blockMalware: boolean; + blockAdultContent: boolean; + blockGambling: boolean; }; } diff --git a/mullvad-cli/src/cmds/dns.rs b/mullvad-cli/src/cmds/dns.rs index 72869b6c7b..300e1c3955 100644 --- a/mullvad-cli/src/cmds/dns.rs +++ b/mullvad-cli/src/cmds/dns.rs @@ -40,6 +40,18 @@ impl Command for Dns { .long("block-malware") .takes_value(false) .help("Block domains known to be used by malware"), + ) + .arg( + clap::Arg::new("block adult content") + .long("block-adult-content") + .takes_value(false) + .help("Block domains known to be used for adult content"), + ) + .arg( + clap::Arg::new("block gambling") + .long("block-gambling") + .takes_value(false) + .help("Block domains known to be used for gambling"), ), ) .subcommand( @@ -63,6 +75,8 @@ impl Command for Dns { matches.is_present("block ads"), matches.is_present("block trackers"), matches.is_present("block malware"), + matches.is_present("block adult content"), + matches.is_present("block gambling"), ) .await } @@ -90,6 +104,8 @@ impl Dns { block_ads: bool, block_trackers: bool, block_malware: bool, + block_adult_content: bool, + block_gambling: bool, ) -> Result<()> { let mut rpc = new_rpc_client().await?; let settings = rpc.get_settings(()).await?.into_inner(); @@ -99,6 +115,8 @@ impl Dns { block_ads, block_trackers, block_malware, + block_adult_content, + block_gambling, }), ..settings.tunnel_options.unwrap().dns_options.unwrap() }) @@ -145,6 +163,11 @@ impl Dns { println!("Block ads: {}", options.default_options.block_ads); println!("Block trackers: {}", options.default_options.block_trackers); println!("Block malware: {}", options.default_options.block_malware); + println!( + "Block adult content: {}", + options.default_options.block_adult_content + ); + println!("Block gambling: {}", options.default_options.block_gambling); } DnsState::Custom => { println!("Custom DNS: yes\nServers:"); diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index e2e18cc6a1..8313d79373 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -95,9 +95,11 @@ const WG_RECONNECT_DELAY: Duration = Duration::from_secs(4 * 60); /// we compute the resolver IP to use based on these constants. The last /// byte can be ORed together to combine multiple block lists. const DNS_BLOCKING_IP_BASE: Ipv4Addr = Ipv4Addr::new(100, 64, 0, 0); -const DNS_AD_BLOCKING_IP_BIT: u8 = 0b001; -const DNS_TRACKER_BLOCKING_IP_BIT: u8 = 0b010; -const DNS_MALWARE_BLOCKING_IP_BIT: u8 = 0b100; +const DNS_AD_BLOCKING_IP_BIT: u8 = 1 << 0; // 0b00000001 +const DNS_TRACKER_BLOCKING_IP_BIT: u8 = 1 << 1; // 0b00000010 +const DNS_MALWARE_BLOCKING_IP_BIT: u8 = 1 << 2; // 0b00000100 +const DNS_ADULT_BLOCKING_IP_BIT: u8 = 1 << 3; // 0b00001000 +const DNS_GAMBLING_BLOCKING_IP_BIT: u8 = 1 << 4; // 0b00010000 pub type ResponseTx<T, E> = oneshot::Sender<Result<T, E>>; @@ -826,6 +828,12 @@ where if options.default_options.block_malware { last_byte |= DNS_MALWARE_BLOCKING_IP_BIT; } + if options.default_options.block_adult_content { + last_byte |= DNS_ADULT_BLOCKING_IP_BIT; + } + if options.default_options.block_gambling { + last_byte |= DNS_GAMBLING_BLOCKING_IP_BIT; + } if last_byte != 0 { let mut dns_ip = DNS_BLOCKING_IP_BASE.octets(); diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto index 887cc97d03..ef69be0706 100644 --- a/mullvad-management-interface/proto/management_interface.proto +++ b/mullvad-management-interface/proto/management_interface.proto @@ -437,6 +437,8 @@ message DefaultDnsOptions { bool block_ads = 1; bool block_trackers = 2; bool block_malware = 3; + bool block_adult_content = 4; + bool block_gambling = 5; } message CustomDnsOptions { diff --git a/mullvad-management-interface/src/types.rs b/mullvad-management-interface/src/types.rs index 1081829998..13721066a5 100644 --- a/mullvad-management-interface/src/types.rs +++ b/mullvad-management-interface/src/types.rs @@ -610,6 +610,8 @@ impl From<&mullvad_types::settings::DnsOptions> for DnsOptions { block_ads: options.default_options.block_ads, block_trackers: options.default_options.block_trackers, block_malware: options.default_options.block_malware, + block_adult_content: options.default_options.block_adult_content, + block_gambling: options.default_options.block_gambling, }), custom_options: Some(CustomDnsOptions { addresses: options @@ -1416,6 +1418,8 @@ impl TryFrom<DnsOptions> for mullvad_types::settings::DnsOptions { block_ads: default_options.block_ads, block_trackers: default_options.block_trackers, block_malware: default_options.block_malware, + block_adult_content: default_options.block_adult_content, + block_gambling: default_options.block_gambling, }, custom_options: MullvadCustomDnsOptions { addresses: custom_options diff --git a/mullvad-types/src/settings/mod.rs b/mullvad-types/src/settings/mod.rs index 638a0d01e4..969eb8e4e5 100644 --- a/mullvad-types/src/settings/mod.rs +++ b/mullvad-types/src/settings/mod.rs @@ -262,6 +262,8 @@ pub struct DefaultDnsOptions { pub block_ads: bool, pub block_trackers: bool, pub block_malware: bool, + pub block_adult_content: bool, + pub block_gambling: bool, } /// Custom DNS config |
