From 43ed7392cdfc734a4304284906b9d0d503381841 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 28 Oct 2022 20:15:30 +0200 Subject: [proxy] make it possible to export embedded documentation as standalone .html files and include these in the binary release tarball --- .../self_doc/en_US/advanced_ui_features.html.jinja | 70 ++++ .../proxy/self_doc/en_US/doc_index.html.jinja | 59 +++ .../proxy/self_doc/en_US/packages.html.jinja | 218 +++++++++++ .../self_doc/en_US/policy_selection.html.jinja | 109 ++++++ src/hydrilla/proxy/self_doc/en_US/popup.html.jinja | 157 ++++++++ .../proxy/self_doc/en_US/repositories.html.jinja | 128 +++++++ .../self_doc/en_US/script_blocking.html.jinja | 125 +++++++ .../proxy/self_doc/en_US/url_patterns.html.jinja | 409 +++++++++++++++++++++ 8 files changed, 1275 insertions(+) create mode 100644 src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja create mode 100644 src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja create mode 100644 src/hydrilla/proxy/self_doc/en_US/packages.html.jinja create mode 100644 src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja create mode 100644 src/hydrilla/proxy/self_doc/en_US/popup.html.jinja create mode 100644 src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja create mode 100644 src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja create mode 100644 src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja (limited to 'src/hydrilla/proxy/self_doc/en_US') diff --git a/src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja b/src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja new file mode 100644 index 0000000..045309b --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja @@ -0,0 +1,70 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation page explaining what Haketilo's advanced UI features are. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} Advanced UI features {% endblock %} + +{% block main %} + {{ big_heading('Haketilo user interface features for advanced users') }} + + {% call section() %} + {% call paragraph() %} + Certain options that may cause a lot of unnecessary confusion to casual + Haketilo users have been hidden by default. They can be accessed after + enabling advanced UI features on the + {{ hkt_link('settings page', 'home.home') }}. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Concept of libraries') }} + + {% call paragraph() %} + Haketilo has a concept of 2 types of entities - + packages and + libraries. + As explained on the {{ doc_page_link('packages', 'packages') }} page, it's + ultimately a package that provides concrete functionality and a casual + user does not need to be aware of the existence of libraries. + Consequently, with advanced features off the UI does not contain any + notion of libraries and even the + {{ hkt_link('libraries listing page', 'items.libraries') }} link is + removed from the navigation bar. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Selective installation/uninstallation of packages') }} + + {% call paragraph() %} + A packages is automatically installed together with all its dependencies + when the user enables it. + Additionally, whenever some installed Haketilo packages or libraries are + found not to be needed anymore, they can be pruned from the + {{ hkt_link('settings page', 'home.home') }}. + This functionality was deemed sufficient for most users' needs. + With advanced features enabled the UI also allows any single package or + library not in use to be uninstalled manually and any package or library + available from a {{ doc_page_link('repository', 'repositories') }} to be + installed without prior enabling. + {% endcall %} + {% endcall %} +{% endblock main %} diff --git a/src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja b/src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja new file mode 100644 index 0000000..03f2231 --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja @@ -0,0 +1,59 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation pages index. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} Documentation index {% endblock %} + +{% block main %} + {{ big_heading('Haketilo embedded documentation') }} + + {% call section() %} + {% call paragraph() %} + This is the embedded documentation of Haketilo proxy. + It contains some basic information aimed to help new users understand how + the tool works. + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + {{ doc_page_link('Advanced UI features', 'advanced_ui_features') }} + {% endcall %} + {% call list_entry() %} + {{ doc_page_link('Packages', 'packages') }} + {% endcall %} + {% call list_entry() %} + {{ doc_page_link('Policy selection', 'policy_selection') }} + {% endcall %} + {% call list_entry() %} + {{ doc_page_link('Popup', 'popup') }} + {% endcall %} + {% call list_entry() %} + {{ doc_page_link('Repositories', 'repositories') }} + {% endcall %} + {% call list_entry() %} + {{ doc_page_link('Script blocking', 'script_blocking') }} + {% endcall %} + {% call list_entry() %} + {{ doc_page_link('URL patterns', 'url_patterns') }} + {% endcall %} + {% endcall %} + {% endcall %} +{% endblock main %} diff --git a/src/hydrilla/proxy/self_doc/en_US/packages.html.jinja b/src/hydrilla/proxy/self_doc/en_US/packages.html.jinja new file mode 100644 index 0000000..23e6f45 --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/packages.html.jinja @@ -0,0 +1,218 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation page describing the concept of packages in Haketilo. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} Packages {% endblock %} + +{% block main %} + {{ big_heading('Packages in Haketilo') }} + + {% call section() %} + {% call paragraph() %} + Users can modify web pages by creating, installing and enabling + packages. + A package associates {{ doc_page_link('URL patterns', 'url_patterns') }} + with payloads (i.e. sets of scripts) that can be injected to pages. + For instance, if an enabled package associates pattern + https://example.com/*** with a script that adds a big + "Hello world!" text to the page, this package shall cause "Hello world!" + to appear on pages under example.com. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Packages and libraries') }} + + {% call paragraph() %} + To make mapping custom JavaScript applications and their dependencies to + web pages more manageable, Haketilo defines its own concept of "packages" + and "libraries". + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + package - Also called mapping. + It associates URL patterns with libraries. + {% endcall %} + {% call list_entry() %} + library - Sometimes also referred to as + resource. + Defines a set of scripts that can be injected together into a page. + It can also name other libraries as its dependencies. + When injecting scripts of a given library into some page, Haketilo will + first inject scripts of all libraries depended on. + {% endcall %} + {% endcall %} + + {% call paragraph() %} + It's ultimately a package that provides concrete functionality to the end + user and that can be enabled or disabled. + For this reason, a casual user does not even need to be aware of the + existence of libraries. + Haketilo UI advanced interface features need to be enabled on the + {{ hkt_link('settings page', 'home.home') }} for installed libraries to be + viewable. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Installing') }} + + {% call paragraph() %} + Useful packages prepared by others can be installed from Hydrilla + repositories. The repositories can be configured + {{ hkt_link('through Haketilo user interface', 'repos.repos') }} as + described on + {{ doc_page_link('the relevant documentation page', 'repositories') }}. + As of Haketilo 3.0-beta1 they need to be manually "refreshed" for new + packages from them to be shown in Haketilo. + Available packages viewable on the + {{ hkt_link('packages listing page', 'items.packages') }} are not + immediately installed. + This only happens after they are explicitly enabled or automatically + enabled (if the user configured Haketilo to do this). + {% endcall %} + + {% call paragraph() %} + For convenience, users can also create simple packages + {{ hkt_link('directly in Haketilo UI', 'import.items_import') }}. + A simple form can be used to quickly define a standalone script payload + for a set of URL patterns. As of Haketilo 3.0 only simple (i.e. + single-library) payloads can be created this way. + {% endcall %} + + {% call paragraph() %} + It is also possible to import packages from files. + For this, a directory of serveable mappings and reasources - as produced + by Hydrilla builder and used by Hydrilla server - has to be put into a ZIP + archive. + It can then be uploaded to Haketilo via its + {{ hkt_link('import page', 'import.items_import') }}. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Uninstalling') }} + + {% call paragraph() %} + Haketilo tracks dependencies between packages and libraries and + automatically determines which of them are no longer needed. + These are called orphans and if present, can be + removed from the {{ hkt_link('settings page', 'home.home') }}. + A version of package or library that is not being used but is still + available from an active repository is not considered an orphan. It + automatically becomes one when the repository either stops advertising it + as available or gets removed by the user from + {{ hkt_link('the repositories list', 'repos.repos') }}. + {% endcall %} + + {% call paragraph() %} + When advanced UI features are enabled, it is additionally possible to + manually uninstall any single package that is not in use at a given + moment. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Package contents') }} + + {% call paragraph() %} + Each package has an identifier (built from a + restricted set of characters), a long name, a + description, a version + and almost always a list of license files and a + set of URL patterns mapped to libraries. + In addition there might also be other pieces of information such as + required permissions. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Enabling/disabling') }} + + {% call paragraph() %} + The user can put package in any of 3 possible states. + It can be either enabled, + disabled or + not configured. + {% endcall %} + + {% call paragraph() %} + An enabled package always has its payloads injected on pages matched by + their patterns (unless some more specific pattern takes precedence on the + given page as described on the + {{ doc_page_link('policy selection page', 'policy_selection') }}). + {% endcall %} + + {% call paragraph() %} + A disabled package is always ignored. + It has to be manually re-enabled for Haketilo to take it into account + again. + {% endcall %} + + {% call paragraph() %} + Finally, a package that is neither explicitly enabled nor disabled can be + treated differently depending on user's choice on the + {{ hkt_link('settings page', 'home.home') }}. + It is possible to have Haketilo + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + automatically inject such packages' payloads on mathing pages, + {% endcall %} + {% call list_entry() %} + prompt the user on matching pages asking whether the package should be + enabled or + {% endcall %} + {% call list_entry() %} + completely ignore non-configured packages. + {% endcall %} + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Handling multiple versions') }} + + {% call paragraph() %} + It is possible to have many versions of the same package or library + installed. + When this is the case, Haketilo by default uses the newest versions it + can. + Additionally, if certain package is enabled, its page also allows the user + to configure its pinning. + A package can be + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + pinned to use a particular version, + {% endcall %} + {% call list_entry() %} + pinned to use the best version from a particular + {{ doc_page_link('repository', 'repositories') }} or + {% endcall %} + {% call list_entry() %} + not pinned at all (best version overall is used). + {% endcall %} + {% endcall %} + {% endcall %} +{% endblock main %} diff --git a/src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja b/src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja new file mode 100644 index 0000000..687d2bd --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja @@ -0,0 +1,109 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation page describing how Haketilo selects policy to apply to a page. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} Policy selection {% endblock %} + +{% block main %} + {{ big_heading('Page policy selection') }} + + {% call section() %} + {% call paragraph() %} + When a web page is opened, Haketilo is capable of either + {% call unordered_list() %} + {% call list_entry() %} + blocking page's own scripts and + {{ doc_page_link('injecting payload', 'packages') }} + configured by the user, + {% endcall %} + {% call list_entry() %} + blocking page's own scripts and injecting an automatically-chosen + payload that is usable with the page, + {% endcall %} + {% call list_entry() %} + presenting a dialog asking whether to enable an automatically-chosen + payload that is usable with the page, + {% endcall %} + {% call list_entry() %} + {{ doc_page_link('blocking', 'script_blocking') }} page's own scripts + or + {% endcall %} + {% call list_entry() %} + allowing page's own scripts to execute normally (i.e. not modifying + the page in any meaningful way). + {% endcall %} + {% endcall %} + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Policy precedence') }} + + {% call paragraph() %} + User configures Haketilo's behavior by defining script-blocking and + -allowing rules and by adding and enabling packages. Each rule and each + package payload has a {{ doc_page_link('URL pattern', 'url_patterns') }}. + This pattern determines which pages the policy is compatible with. + Patterns also have well-defined specificity. When multiple rules and + packages are combatible with given page's URL, the one with the most + specific pattern "wins". In case of a tie, payload injection is assumed to + take precedence over rule application. + {% endcall %} + + {% call paragraph() %} + In the absence of suitable rules and enabled packages, Haketilo may + consider non-enabled packages that are suitable for use on the + currently-visited site. It will either inject package payload + automatically, ask the user whether to enable the package or ignore it + completely. The user can switch between these 3 behaviors on the Haketilo + {{ hkt_link('settings page', 'home.home') }}. Packages that were + explicitly marked as disabled will always be ignored. Pattern specificity + is also taken into account in case of multiple packages. + {% endcall %} + + {% call paragraph() %} + When absolutely no explicit policy appears suitable for given page, + Haketilo will apply its default script handling behavrior. Whether + JavaScript is blocked or allowed by default is also determined by user's + choice on the {{ hkt_link('settings page', 'home.home') }}. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Special cases') }} + + {% call paragraph() %} + The sites served by Haketilo itself are exempt from all policies. These + are http://hkt.mitm.it, https://hkt.mitm.it + and http://mitm.it. Additionally, if Haketilo experiences an + internal error (e.g. because it could not parse current URL as sent in by + the browser), it will try to block page's JavaScript as a security + measure. + {% endcall %} + + {% call paragraph() %} + Internally, Haketilo also has a special high-priority policy for serving + files used by payloads and for making its APIs accessible to payload + scripts. This is, however, an implementation detail and casual users need + not care about it nor understand these nuances. + {% endcall %} + {% endcall %} +{% endblock main %} diff --git a/src/hydrilla/proxy/self_doc/en_US/popup.html.jinja b/src/hydrilla/proxy/self_doc/en_US/popup.html.jinja new file mode 100644 index 0000000..a5ad909 --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/popup.html.jinja @@ -0,0 +1,157 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation page describing Haketilo popup. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} Popup {% endblock %} + +{% block main %} + {{ big_heading('Haketilo popup') }} + + {% call section() %} + {% call paragraph() %} + Taking inspiration from user interface features of browser extensions, + Haketilo also offers a popup window for quick interaction with the + user. For technical reasons, the popup is presented as part of the web + page and behaves slightly differently from those some users might have + found in similar tools. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Operating') }} + + {% call paragraph() %} + The popup dialog can be opened by typing big letters "HKT" anywhere on the + page. It then presents some basic information about the handling of + current URL. It also allows the user quickly define new + {{ doc_page_link('rules', 'script_blocking') }} or + {{ doc_page_link('payloads', 'packages') }} for it. As of Haketilo 3.0, + however, the actual configuration is not performed from the popup itself + but rather a relevant Haketilo rule/payload definition page is opened in a + new tab. + {% endcall %} + + {% call paragraph() %} + The dialog can be closed by clicking anywhere on the darker area around + it. It can then be reopened by typing "HKT" again. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Enabling/disabling') }} + + {% call paragraph() %} + Popup is unavailable by default on Haketilo special sites including + https://hkt.mitm.it. It can also be disabled independently on + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + pages with JS allowed, + {% endcall %} + {% call list_entry() %} + pages with JS blocked and + {% endcall %} + {% call list_entry() %} + pages with script payload injected. + {% endcall %} + {% endcall %} + + {% call paragraph() %} + This can be configured on the {{ hkt_link('setings page', 'home.home') }} + and might be useful to users who are careful about fingerprinting. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Fingerprinting considerations') }} + + {% call paragraph() %} + To make the popup available, Haketilo has to inject an additional script + to all pages. That makes it easy for pages to determine with certainty + that given user is running Haketilo. This has implications for privacy and + may also be used by a hostile site to selectively cause annoyance to + Haketilo users. + {% endcall %} + + {% call paragraph() %} + The above problems would be present regardless on pages with + Haketilo-injected payloads. I.e. in many cases a site could theoretically + find out the user is not accessing it in a normal way. However, the popup + also increases fingerprintability when no payload is in use and especially + on pages with JavaScript allowed. For this reason, the presence of popup + on pages has been made configurable. + {% endcall %} + + {% call paragraph() %} + It is also worth noting that as of version 3.0 Haketilo does not make + guarantees about the browser fingerprint. Despite best efforts, there are + still other aspects that might make a Haketilo user distinguishable to a + website even when popup is disabled. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Other caveats') }} + + {% call paragraph() %} + Some other potential issues related to the popup are described below. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('Interference with the site') }} + + {% call paragraph() %} + The popup gets injected by Haketilo into the actual web page. Although + care was taken to make accidental breakage unlikely, it might still happen + under some specific conditions. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('Interference with other script-blocking tools') }} + + {% call paragraph() %} + The popup is driven by a piece of JavaScript code injected by Haketilo to + pages. Haketilo by itself makes sure neither the policies specified by the + page nor its own script-blocking mechanisms interfere with this particular + piece. In spite of that, a browser extension or web browser's own settings + might prevent the popup script from executing, making the dialog + unavailable. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('URL mismatch') }} + + {% call paragraph() %} + Sometimes a page might change parts of its address visible in browser's + URL bar. E.g. after opening https://entraide.chatons.org/ in + the browser we might see https://entraide.chatons.org/en/ as + the current address even though no reload happened. In addition, some + browsers hide URL's traling dash ("/") from the user. Regardless of that, + Haketilo's popup always presents the original URL under which the current + page was served. Although this the intended behavior, it might cause + confusion and therefore has been documented here. + {% endcall %} + {% endcall %} +{% endblock main %} diff --git a/src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja b/src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja new file mode 100644 index 0000000..4cf6d2c --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja @@ -0,0 +1,128 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation page describing the concept of repositories in Haketilo. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} Repositories {% endblock %} + +{% block main %} + {{ big_heading('Repositories in Haketilo') }} + + {% call section() %} + {% call paragraph() %} + {{ doc_page_link('Packages', 'packages') }} used to alter sites' behavior + can be obtained by users from Hydrilla repositories. The repositories to + use can be configured from the + {{ hkt_link('relevant Haketilo UI page', 'repos.repos') }}. When Haketilo + is first run, it only has one entry on that page - the official Hydrilla + repository with fixes for sites that normally rely on (often proprietary) + JavaScript. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Adding') }} + + {% call paragraph() %} + Before experimenting with third-party repositories please bear in mind + that a hostile Haketilo package can cause real harm. + Scripts injected by Haketilo have access to data on the page, including + cookies and passwords you may enter. + Do make sure the repositories you are using are trustworthy. + {% endcall %} + + {% call paragraph() %} + On the {{ hkt_link('repository addition page', 'repos.add_repo') }} the + user is expected to supply 2 pieces of information. + The URL of the repository and its + name. + The URL is supposed to be provided by repository owner. + Then name is only used locally and can be chosen by the user. + Allowed are most visible ASCII characters, with possible spaces in-betwen. + No 2 repositories can use the same name. + {% endcall %} + + {% call paragraph() %} + As of Haketilo version 3.0 the user does not need to provide any + authentication data (e.g. private keys) because cryptographic signing of + packages is not yet supported. This may change in the future. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Removing') }} + + {% call paragraph() %} + A repository can be deleted at any time. When this happens, + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + its packages that were in use (e.g. were enabled) retain their state, + {% endcall %} + {% call list_entry() %} + its packages that were installed but not in use become + orphans and can be removed from the + {{ hkt_link('settings page', 'home.home') }} and + {% endcall %} + {% call list_entry() %} + its packages that were not installed are forgotten. + {% endcall %} + {% endcall %} + + {% call paragraph() %} + A deleted repository remains viewable from the + {{ hkt_link('repositories management page', 'repos.repos') }} for as long + as some of its packages remain installed. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Operating') }} + + {% call paragraph() %} + Before repository's contents become viewable on the + {{ hkt_link('packages listing page', 'items.packages') }}, it needs to be + refreshed. + As of Haketilo 3.0-beta1, this action needs to be triggered manually by + the user from the configuration page of that repository. + Subsequent refreshals are needed every time the user wants to pull package + updates. + {% endcall %} + + {% call paragraph() %} + Repository's name and URL can also be changed from its configuration page. + The same requirements for their format hold as when adding a new + repository. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Local items') }} + + {% call paragraph() %} + When the users installs some additional packages without using a + repository, these are considered local packages. + A special "Local items" entry then appears on the + {{ hkt_link('repositories management page', 'repos.repos') }}. Local + packages that are not in use are automatically considered orhpans. + {% endcall %} + {% endcall %} +{% endblock %} diff --git a/src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja b/src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja new file mode 100644 index 0000000..c0a5275 --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja @@ -0,0 +1,125 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation page describing how Haketilo blocks scripts. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} Script blocking {% endblock %} + +{% block main %} + {{ big_heading('Script blocking in Haketilo') }} + + {% call section() %} + {% call paragraph() %} + Modern web browsers allow sites to execute software on users' + devices. This software is usually written in a language called JavaScript + and abbreviated as JS. It can serve various purposes - from small + enhancements to deployment of heavy applications inside the + browser. Because Haketilo aims to give users control over their web + browsing, one of its supported features is blocking of JavaScript + execution on per-page and per-site basis. + {% endcall %} + + {% call paragraph() %} + Besides the casual script-blocking discussed here, Haketilo also blocks + page's JavaScript when injecting the user-specified + {{ doc_page_link('script payloads', 'packages') }}. That functionality is + described on its own documentation page. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Configuring script blocking') }} + + {% call paragraph() %} + User can + {{ + hkt_link('define script-blocking and -allowing rules', 'rules.rules') + }} + using {{ doc_page_link('URL patterns', 'url_patterns') }}. Each such rule + tells Haketilo to either block or allow scripts on pages matched by its + pattern. Rules with more specific patterns can override those with less + specific ones as described on the + {{ doc_page_link('policy selection page', 'policy_selection') }}. + {% endcall %} + + {% call paragraph() %} + As an example, if we want all scripts on english Wikipedia pages to be + blocked, we can add a blocking rule with + pattern https://en.wikipedia.org/***. If we then wanted to + make an exception just for the "List of emoticons" page, we could create + an additional allowing rule with + https://en.wikipedia.org/wiki/List_of_emoticons as its + pattern. It would take effect on that page while all the other english + Wikipedia pages would still have their scripts blocked. + {% endcall %} + + {% call paragraph() %} + It is also possible to configure whether scripts should be blocked by + dafault on pages where no explicit rule and no payload is used. The + relevant option can be found on Haketilo + {{ hkt_link('settings page', 'home.home') }}. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Use with other script-blocking tools') }} + + {% call paragraph() %} + Various browsers and browser extension can also be configured to block + JavaScript. Haketilo works independently of those tools. If the user + desires to have scripts on certain page to execute normally, both Haketilo + and other tools must be configured to allow that. + {% endcall %} + + {% call paragraph() %} + Unlike most similar tools, Haketilo operates outside the web browser. As a + result, it is relatively unlikely for Haketilo to cause these to + malfunction. At the same time, it is relatively easy to have another + script blocker break some Haketilo functionality (e.g. its + {{ doc_page_link('popup', 'popup') }}). + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Technical details') }} + + {% call paragraph() %} + From technical point of view, Haketilo, as of version 3.0, blocks + JavaScript by altering the Content-Security-Policy (abbreviated CSP) + headers in HTTP responses. The original CSP directives sent by site are + retained, with exception of those which would result in CSP violation + reports being sent. Haketilo's own script-blocking directives are then + added to produce the final CSP which user's web browser eventually sees. + {% endcall %} + + {% call paragraph() %} + The above means that neither the scripts that would be blocked by page's + own rules nor those that are blocked by Haketilo are going to cause CSP + reports to be sent. + {% endcall %} + + {% call paragraph() %} + In addition, even when a page has JavaScript nominally blocked, Haketilo + 3.0 may nevertheless inject into it its own script responsible for making + the popup available. The CSP is then modified appropriately to allow only + that script to run. + {% endcall %} + {% endcall %} +{% endblock main %} diff --git a/src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja b/src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja new file mode 100644 index 0000000..f3415c5 --- /dev/null +++ b/src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja @@ -0,0 +1,409 @@ +{# +SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0 + +Documentation page describing URL patterns understood by Haketilo. + +This file is part of Hydrilla&Haketilo. + +Copyright (C) 2022 Wojtek Kosior + +Dual licensed under +* GNU General Public License v3.0 or later and +* Creative Commons Attribution Share Alike 4.0 International. + +You can choose to use either of these licenses or both. + + +I, Wojtek Kosior, thereby promise not to sue for violation of this +file's licenses. Although I request that you do not make use of this +code in a proprietary work, I am not going to enforce this in court. +#} +{% extends "doc_base.html.jinja" %} + +{% block title %} URL patterns {% endblock %} + +{% block main %} + {{ big_heading('Haketio URL patterns') }} + + {% call section() %} + {% call paragraph() %} + We want to be able to apply different rules and custom scripts for + different websites. However, merely specifying "do this for all documents + under https://example.com" is not enough. Single site's pages + might differ strongly and require different custom scripts to be + loaded. Always matching against a full URL like + https://example.com/something/somethingelse is also not + a good option. It doesn't allow us to properly handle a site that serves + similar pages for multiple values substituted for + somethingelse. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Employed solution') }} + + {% call paragraph() %} + Wildcards are being used to address the problem. Each payload and rule in + Haketilo has a URL pattern that specifies to which internet pages it + applies. A URL pattern can be as as simple as literal URL in which case it + only matches itself. It can also contain wildcards in the form of one or + more asterisks (*) that correspond to multiple possible + strings occurring in that place. + {% endcall %} + + {% call paragraph() %} + Wildcards can appear in URL's domain and path that follows it. These 2 + types of wildcards are handled separately. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('Domain wildcards') }} + + {% call paragraph() %} + A domain wildcard takes the form of one, two or three asterisks occurring + in place of a single domain name segment at the beginning + (left). Depending on the number of asterisks, the meaning is as follows + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + no asterisks (e.g. example.com) - match domain name exactly + (e.g. example.com) + {% endcall %} + {% call list_entry() %} + one asterisk (e.g. *.example.com) - match all domains + resulting from substituting * with a + single segment (e.g. + banana.example.com or pineapple.example.com + but not pineapple.pen.example.com + nor example.com) + {% endcall %} + {% call list_entry() %} + two asterisks (e.g. **.example.com) - match all domains + resulting from substituting ** with + two or more segments (e.g. + monad.breakfast.example.com or + pure.monad.breakfast.example.com but + not cabalhell.example.com nor + example.com) + {% endcall %} + {% call list_entry() %} + three asterisks (e.g. ***.example.com) - match all domains + resulting from substituting *** with + zero or more segments (e.g. + hello.parkmeter.example.com or + iliketrains.example.com or example.com) + {% endcall %} + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('Path wildcards') }} + + {% call paragraph() %} + A path wildcard takes the form of one, two or three asterisks occurring in + place of a single path segment at the end of path (right). Depending on + the number of asterisks, the meaning is as follows + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + no asterisks (e.g. /joke/clowns) - match path exactly (e.g. + /joke/clowns) + {% endcall %} + {% call list_entry() %} + one asterisk (e.g. /itscalled/*) - match all paths + resulting from substituting * with a + single segment (e.g. + /itscalled/gnulinux or /itscalled/glamp but + not /itscalled/ nor + /itscalled/gnu/linux) + {% endcall %} + {% call list_entry() %} + two asterisks (e.g. /another/**) - match all paths + resulting from substituting ** with + two or more segments (e.g. + /another/nsa/backdoor or + /another/best/programming/language but + not /another/apibreak nor + /another) + {% endcall %} + {% call list_entry() %} + three asterisks (e.g. /mail/dmarc/***) - match all paths + resulting from substituting *** with + zero or more segments (e.g. + /mail/dmarc/spf, /mail/dmarc or + /mail/dmarc/dkim/failure but + not /mail/) + {% endcall %} + {% endcall %} + + {% call paragraph() %} + If pattern ends without a trailing slash, it + mathes paths with any number of trailing slashes, including zero. If + pattern ends with a trailing slash, it only + mathes paths with one or more trailing slashes. For example, + /itscalled/* matches /itscalled/gnulinux, + /itscalled/gnulinux/ and /itscalled/gnulinux// + while /itscalled/*/ only matches + /itscalled/gnulinux/ and /itscalled/gnulinux// + out of those three. + {% endcall %} + + {% call paragraph() %} + If two patterns only differ by the presence of a trailing slash, + pattern with a trailing slash is considered + more specific. + {% endcall %} + + {% call paragraph() %} + Additionally, any path with literal trailing asterisks is matched by + itself, even if such pattern would otherwise be treated as wildcard + (e.g. /gobacktoxul/** matches /gobacktoxul/**). + This is likely to change in the future and would best not be relied upon. + Appending three additional asterisks to path pattern to represent literal + asterisks is being considered. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('URL scheme wildcard') }} + + {% call paragraph() %} + http:// and https:// shemes in the URL are + matched exactly. However, starting with Haketilo 3.0, it is also possible + for scheme pseudo-wildcard of http*:// to be used. Use of URL + pattern with this scheme is equivalent to the use of 2 separate patterns + starting with http:// and https://, + respectively. For example, pattern http*://example.com shall + match both https://example.com and + http://example.com. + {% endcall %} + + {% call paragraph() %} + http*:// may be considered not to be a true wildcard but + rather an alias for either of the other 2 values. As of Haketilo 3.0, the + speicificity of a URL pattern starting with http*:// is + considered to be the same as that of the corresponding URL pattern + starting with http:// or https://. In case of a + conflict, the order of precedence of such patterns is unspecified. This + behavior is likely to change in the future versions of Haketilo. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('Wildcard pattern priorities and querying') }} + + {% call paragraph() %} + In case multiple patterns match some URL, the more specific one is + preferred. Specificity is considered as follows + {% endcall %} + + {% call unordered_list() %} + {% call list_entry() %} + If patterns only differ in the final path segment, the one with least + wildcard asterisks in that segment if preferred. + {% endcall %} + {% call list_entry() %} + If patterns, besides the above, only differ in path length, one with + longer path is preferred. Neither final wildcard segment nor trailing + dashes account for path length. + {% endcall %} + {% call list_entry() %} + If patterns, besides the above, only differ in the initial domain + segment, one with least wildcard asterisks in that segment is preferred. + {% endcall %} + {% call list_entry() %} + If patterns differ in domain length, one with longer domain is + preferred. Initial wildcard segment does not account for domain length. + {% endcall %} + {% endcall %} + + {% call paragraph() %} + As an example, consider the URL + http://settings.query.example.com/google/tries/destroy/adblockers//. + Patterns matching it are, in the following order + {% endcall %} + + {% call verbatim() %} +http://settings.query.example.com/google/tries/destroy/adblockers/ +http://settings.query.example.com/google/tries/destroy/adblockers +http://settings.query.example.com/google/tries/destroy/adblockers/***/ +http://settings.query.example.com/google/tries/destroy/adblockers/*** +http://settings.query.example.com/google/tries/destroy/*/ +http://settings.query.example.com/google/tries/destroy/* +http://settings.query.example.com/google/tries/destroy/***/ +http://settings.query.example.com/google/tries/destroy/*** +http://settings.query.example.com/google/tries/**/ +http://settings.query.example.com/google/tries/** +http://settings.query.example.com/google/tries/***/ +http://settings.query.example.com/google/tries/*** +http://settings.query.example.com/google/**/ +http://settings.query.example.com/google/** +http://settings.query.example.com/google/***/ +http://settings.query.example.com/google/*** +http://settings.query.example.com/**/ +http://settings.query.example.com/** +http://settings.query.example.com/***/ +http://settings.query.example.com/*** +http://***.settings.query.example.com/google/tries/destroy/adblockers/ +http://***.settings.query.example.com/google/tries/destroy/adblockers +http://***.settings.query.example.com/google/tries/destroy/adblockers/***/ +http://***.settings.query.example.com/google/tries/destroy/adblockers/*** +http://***.settings.query.example.com/google/tries/destroy/*/ +http://***.settings.query.example.com/google/tries/destroy/* +http://***.settings.query.example.com/google/tries/destroy/***/ +http://***.settings.query.example.com/google/tries/destroy/*** +http://***.settings.query.example.com/google/tries/**/ +http://***.settings.query.example.com/google/tries/** +http://***.settings.query.example.com/google/tries/***/ +http://***.settings.query.example.com/google/tries/*** +http://***.settings.query.example.com/google/**/ +http://***.settings.query.example.com/google/** +http://***.settings.query.example.com/google/***/ +http://***.settings.query.example.com/google/*** +http://***.settings.query.example.com/**/ +http://***.settings.query.example.com/** +http://***.settings.query.example.com/***/ +http://***.settings.query.example.com/*** +http://*.query.example.com/google/tries/destroy/adblockers/ +http://*.query.example.com/google/tries/destroy/adblockers +http://*.query.example.com/google/tries/destroy/adblockers/***/ +http://*.query.example.com/google/tries/destroy/adblockers/*** +http://*.query.example.com/google/tries/destroy/*/ +http://*.query.example.com/google/tries/destroy/* +http://*.query.example.com/google/tries/destroy/***/ +http://*.query.example.com/google/tries/destroy/*** +http://*.query.example.com/google/tries/**/ +http://*.query.example.com/google/tries/** +http://*.query.example.com/google/tries/***/ +http://*.query.example.com/google/tries/*** +http://*.query.example.com/google/**/ +http://*.query.example.com/google/** +http://*.query.example.com/google/***/ +http://*.query.example.com/google/*** +http://*.query.example.com/**/ +http://*.query.example.com/** +http://*.query.example.com/***/ +http://*.query.example.com/*** +http://***.query.example.com/google/tries/destroy/adblockers/ +http://***.query.example.com/google/tries/destroy/adblockers +http://***.query.example.com/google/tries/destroy/adblockers/***/ +http://***.query.example.com/google/tries/destroy/adblockers/*** +http://***.query.example.com/google/tries/destroy/*/ +http://***.query.example.com/google/tries/destroy/* +http://***.query.example.com/google/tries/destroy/***/ +http://***.query.example.com/google/tries/destroy/*** +http://***.query.example.com/google/tries/**/ +http://***.query.example.com/google/tries/** +http://***.query.example.com/google/tries/***/ +http://***.query.example.com/google/tries/*** +http://***.query.example.com/google/**/ +http://***.query.example.com/google/** +http://***.query.example.com/google/***/ +http://***.query.example.com/google/*** +http://***.query.example.com/**/ +http://***.query.example.com/** +http://***.query.example.com/***/ +http://***.query.example.com/*** +http://**.example.com/google/tries/destroy/adblockers/ +http://**.example.com/google/tries/destroy/adblockers +http://**.example.com/google/tries/destroy/adblockers/***/ +http://**.example.com/google/tries/destroy/adblockers/*** +http://**.example.com/google/tries/destroy/*/ +http://**.example.com/google/tries/destroy/* +http://**.example.com/google/tries/destroy/***/ +http://**.example.com/google/tries/destroy/*** +http://**.example.com/google/tries/**/ +http://**.example.com/google/tries/** +http://**.example.com/google/tries/***/ +http://**.example.com/google/tries/*** +http://**.example.com/google/**/ +http://**.example.com/google/** +http://**.example.com/google/***/ +http://**.example.com/google/*** +http://**.example.com/**/ +http://**.example.com/** +http://**.example.com/***/ +http://**.example.com/*** +http://***.example.com/google/tries/destroy/adblockers/ +http://***.example.com/google/tries/destroy/adblockers +http://***.example.com/google/tries/destroy/adblockers/***/ +http://***.example.com/google/tries/destroy/adblockers/*** +http://***.example.com/google/tries/destroy/*/ +http://***.example.com/google/tries/destroy/* +http://***.example.com/google/tries/destroy/***/ +http://***.example.com/google/tries/destroy/*** +http://***.example.com/google/tries/**/ +http://***.example.com/google/tries/** +http://***.example.com/google/tries/***/ +http://***.example.com/google/tries/*** +http://***.example.com/google/**/ +http://***.example.com/google/** +http://***.example.com/google/***/ +http://***.example.com/google/*** +http://***.example.com/**/ +http://***.example.com/** +http://***.example.com/***/ +http://***.example.com/*** + {% endcall %} + + {% call paragraph() %} + Variants of those patterns starting with http*:// would of + course match as well. They have been omitted for simplicity. + {% endcall %} + + {% call paragraph() %} + For a simpler URL like https://example.com the patterns would + be + {% endcall %} + + {% call verbatim() %} +https://example.com +https://example.com/*** +https://***.example.com +https://***.example.com/*** + {% endcall %} + + {% call paragraph() %} + Variants of those patterns with a trailing dash added + would not match the URL. Also, the pattern + variants starting with http*:// have been once again omitted. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ small_heading('Limits') }} + + {% call paragraph() %} + In order to prevent some easy-to-conduct DoS attacks, older versions of + Haketilo and Hydrilla limited the lengths of domain and path parts of + processed URLs. This is no longer the case. + {% endcall %} + {% endcall %} + + {% call section() %} + {{ medium_heading('Alternative solution idea: mimicking web server mechanics') }} + + {% call paragraph() %} + While wildcard patterns as presented give a lot of flexibility, they are + not the only viable approach to specifying what URLs to apply + rules/payloads to. In fact, wildcards are different from how the server + side of a typical website decides what to return for a given URL request. + {% endcall %} + + {% call paragraph() %} + In a typical scenario, an HTTP server like Apache reads configuration + files provided by its administrator and uses various (virtual host, + redirect, request rewrite, CGI, etc.) instructions to decide how to handle + given URL. Perhps using a scheme that mimics the configuration options + typically used with web servers would give more efficiency in specifying + what page settings to apply when. + {% endcall %} + + {% call paragraph() %} + This approach may be considered in the future. + {% endcall %} + {% endcall %} +{% endblock main %} -- cgit v1.2.3