Add webrtc_ip_handling_policy setting

This exposes all possible values, but before
https://codereview.qt-project.org/#/c/240121/ we won't be able to change those
at runtime (or enable URL patterns, which thankfully weren't enabled for the
old setting).

In theory, it'd be possible to handle the "public-interface-only" value via
QWebEngineSettings without requiring a restart, but it isn't worth the trouble.

Closes #4201
This commit is contained in:
Florian Bruhin 2018-09-17 18:35:38 +02:00
parent 6fe09c12da
commit bd21686e0d
8 changed files with 96 additions and 29 deletions

View File

@ -36,6 +36,8 @@ Added
model.
- New `qt.low_end_device_mode` setting which turns on Chromium's low-end device
mode. This mode uses less RAM, but the expense of performance.
- New `content.webrtc_ip_handling_policy` setting, which allows more
fine-grained/restrictive control about which IPs are exposed via WebRTC.
Changed
~~~~~~~
@ -71,6 +73,8 @@ Removed
~~~~~~~
- Support for importing pre-v1.0.0 history files has been removed.
- The `content.webrtc_public_interfaces_only` setting has been removed and
replaced by `content.webrtc_ip_handling_policy`.
v1.4.2
------

View File

@ -158,7 +158,7 @@
|<<content.ssl_strict,content.ssl_strict>>|Validate SSL handshakes.
|<<content.user_stylesheets,content.user_stylesheets>>|List of user stylesheet filenames to use.
|<<content.webgl,content.webgl>>|Enable WebGL.
|<<content.webrtc_public_interfaces_only,content.webrtc_public_interfaces_only>>|Only expose public interfaces via WebRTC.
|<<content.webrtc_ip_handling_policy,content.webrtc_ip_handling_policy>>|Which interfaces to expose via WebRTC.
|<<content.windowed_fullscreen,content.windowed_fullscreen>>|Limit fullscreen to the browser window (does not expand to fill the screen).
|<<content.xss_auditing,content.xss_auditing>>|Monitor load requests for cross-site scripting attempts.
|<<downloads.location.directory,downloads.location.directory>>|Directory to save downloads to.
@ -2073,14 +2073,22 @@ Type: <<types,Bool>>
Default: +pass:[true]+
[[content.webrtc_public_interfaces_only]]
=== content.webrtc_public_interfaces_only
Only expose public interfaces via WebRTC.
On Qt 5.9, this option requires a restart. On Qt 5.10, this option doesn't work at all because of a Qt bug. On Qt >= 5.11, no restart is required.
[[content.webrtc_ip_handling_policy]]
=== content.webrtc_ip_handling_policy
Which interfaces to expose via WebRTC.
On Qt 5.10, this option doesn't work because of a Qt bug.
This setting requires a restart.
Type: <<types,Bool>>
Type: <<types,String>>
Default: +pass:[false]+
Valid values:
* +all-interfaces+: WebRTC has the right to enumerate all interfaces and bind them to discover public interfaces.
* +default-public-and-private-interfaces+: WebRTC should only use the default route used by http. This also exposes the associated default private address. Default route is the route chosen by the OS on a multi-homed endpoint.
* +default-public-interface-only+: WebRTC should only use the default route used by http. This doesn't expose any local addresses.
* +disable-non-proxied-udp+: WebRTC should only use TCP to contact peers or servers unless the proxy server supports UDP. This doesn't expose any local addresses either.
Default: +pass:[all-interfaces]+
On QtWebEngine, this setting requires Qt 5.9.2 or newer.

View File

@ -166,8 +166,6 @@ class WebEngineSettings(websettings.AbstractSettings):
# Qt 5.11
'content.autoplay':
('PlaybackRequiresUserGesture', lambda val: not val),
'content.webrtc_public_interfaces_only':
('WebRTCPublicInterfacesOnly', None),
}
for name, (attribute, converter) in new_attributes.items():
try:

View File

@ -769,18 +769,31 @@ content.webgl:
supports_pattern: true
desc: Enable WebGL.
content.webrtc_public_interfaces_only:
default: false
type: Bool
content.webrtc_ip_handling_policy:
default: all-interfaces
type:
name: String
valid_values:
- all-interfaces: WebRTC has the right to enumerate all interfaces and
bind them to discover public interfaces.
- default-public-and-private-interfaces: WebRTC should only use the
default route used by http. This also exposes the associated
default private address. Default route is the route chosen by the
OS on a multi-homed endpoint.
- default-public-interface-only: WebRTC should only use the default route
used by http. This doesn't expose any local addresses.
- disable-non-proxied-udp: WebRTC should only use TCP to contact peers or
servers unless the proxy server supports UDP. This doesn't expose
any local addresses either.
default: all-interfaces
backend:
QtWebKit: false
QtWebEngine: Qt 5.9.2
restart: true
desc: >-
Only expose public interfaces via WebRTC.
Which interfaces to expose via WebRTC.
On Qt 5.9, this option requires a restart.
On Qt 5.10, this option doesn't work at all because of a Qt bug.
On Qt >= 5.11, no restart is required.
On Qt 5.10, this option doesn't work because of a Qt bug.
content.xss_auditing:
type: Bool

View File

@ -276,6 +276,21 @@ class YamlConfig(QObject):
del settings['bindings.default']
self._mark_changed()
# content.webrtc_public_interfaces_only got merged into
# content.webrtc_ip_handling_policy.
old = 'content.webrtc_public_interfaces_only'
new = 'content.webrtc_ip_handling_policy'
if old in settings:
settings[new] = {}
for scope, val in settings[old].items():
if val:
settings[new][scope] = 'default-public-interface-only'
else:
settings[new][scope] = 'all-interfaces'
del settings[old]
self._mark_changed()
self._migrate_bool(settings, 'tabs.favicons.show', 'always', 'never')
self._migrate_bool(settings, 'qt.force_software_rendering',
'software-opengl', 'none')

View File

@ -187,9 +187,11 @@ def qt_args(namespace):
# On Qt 5.11, we can control this via QWebEngineSettings
if not config.val.content.autoplay:
argv.append('--autoplay-policy=user-gesture-required')
if config.val.content.webrtc_public_interfaces_only:
argv.append('--force-webrtc-ip-handling-policy='
'default_public_interface_only')
webrtc_policy = config.val.content.webrtc_ip_handling_policy
if webrtc_policy != 'all-interfaces':
argv.append('--force-webrtc-ip-handling-policy=' +
webrtc_policy.replace('-', '_'))
process_model = config.val.qt.process_model
if process_model == 'process-per-site-instance':

View File

@ -235,6 +235,21 @@ class TestYaml:
data = autoconfig.read()
assert 'bindings.default' not in data
@pytest.mark.parametrize('public_only, expected', [
(True, 'default-public-interface-only'),
(False, 'all-interfaces'),
])
def test_webrtc(self, yaml, autoconfig, public_only, expected):
"""Tests for migration of content.webrtc_public_interfaces_only."""
autoconfig.write({'content.webrtc_public_interfaces_only':
{'global': public_only}})
yaml.load()
yaml._save()
data = autoconfig.read()
assert data['content.webrtc_ip_handling_policy']['global'] == expected
@pytest.mark.parametrize('show, expected', [
(True, 'always'),
(False, 'never'),

View File

@ -438,23 +438,35 @@ class TestQtArgs:
assert ('--autoplay-policy=user-gesture-required' in args) == added
@utils.qt59
@pytest.mark.parametrize('new_version, public_only, added', [
(True, True, False), # new enough to not need it
(False, False, False), # option disabled
(False, True, True),
@pytest.mark.parametrize('policy, arg', [
('all-interfaces', None),
('default-public-and-private-interfaces',
'--force-webrtc-ip-handling-policy='
'default_public_and_private_interfaces'),
('default-public-interface-only',
'--force-webrtc-ip-handling-policy='
'default_public_interface_only'),
('disable-non-proxied-udp',
'--force-webrtc-ip-handling-policy='
'disable_non_proxied_udp'),
])
def test_webrtc(self, config_stub, monkeypatch, parser,
new_version, public_only, added):
policy, arg):
monkeypatch.setattr(configinit.objects, 'backend',
usertypes.Backend.QtWebEngine)
config_stub.val.content.webrtc_public_interfaces_only = public_only
monkeypatch.setattr(configinit.qtutils, 'version_check',
lambda version, compiled=False: new_version)
config_stub.val.content.webrtc_ip_handling_policy = policy
parsed = parser.parse_args([])
args = configinit.qt_args(parsed)
arg = '--force-webrtc-ip-handling-policy=default_public_interface_only'
assert (arg in args) == added
if arg is None:
assert not any(a.startswith('--force-webrtc-ip-handling-policy=')
for a in args)
else:
assert arg in args
@pytest.mark.parametrize('canvas_reading, added', [
(True, False), # canvas reading enabled