From 4a0313d84f7ec84fc3b6368d2da1fb50305391c6 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Fri, 13 Nov 2020 12:31:52 -0500 Subject: [PATCH 01/31] Here's my first pass at it --- docs/specifications/index.rst | 1 + docs/specifications/url.rst | 103 ++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 docs/specifications/url.rst diff --git a/docs/specifications/index.rst b/docs/specifications/index.rst index 7d99934f6..2029c9e5a 100644 --- a/docs/specifications/index.rst +++ b/docs/specifications/index.rst @@ -8,6 +8,7 @@ the data formats used by Tahoe. :maxdepth: 2 outline + url uri file-encoding URI-extension diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst new file mode 100644 index 000000000..369f78392 --- /dev/null +++ b/docs/specifications/url.rst @@ -0,0 +1,103 @@ +URLs +==== + +The goal of this document is to completely specify the construction and use of the URLs by Tahoe-LAFS for service location. +This includes, but is not limited to, the original Foolscap-based URLs. +These are not to be confused with the URI-like capabilities Tahoe-LAFS uses to refer to stored data. +An attempt is also made to outline the rationale for certain choices about these URLs. +The intended audience for this document is Tahoe-LAFS maintainers and other developers interested in interoperating with Tahoe-LAFS or these URLs. + +Background +---------- + +Tahoe-LAFS first used Foolscap_ for network communication. +Foolscap connection setup takes as an input a Foolscap URL or a *fURL*. +A fURL includes three components: + +* the base32-encoded SHA1 hash of the DER form of an x509v3 certificate +* zero or more network addresses +* an object identifier + +A Foolscap client tries to connect to each network address in turn. +If a connection is established then TLS is negotiated. +The server is authenticated by matching its certificate against the hash in the fURL. +A matching certificate serves as proof that the handshaking peer is the correct server. +This serves as the process by which the client authenticates the server. + +The client can then exercise further Foolscap functionality using the fURL's object identifier. +If the object identifier is an unguessable, secret string then it serves as a capability. +This serves as the process by which the server authorizes the client. + +NURLs +----- + +The authentication and authorization properties of fURLs are a good fit for Tahoe-LAFS' requirements. +These are not inherently tied to the Foolscap protocol itself. +In particular they are beneficial to :doc:`http-storage-node-protocol` which uses HTTP instead of Foolscap. +It is conceivable they will also be used with WebSockets at some point as well. + +Continuing to refer to these URLs as fURLs when they are being used for other protocols may cause confusion. +Therefore, +this document coins the name *NURL* for these URLs. +This can be considered to expand to "New URLs" or "Authe*N*ticating URLs" or "Authorizi*N*g URLs" as the reader prefers. + +Syntax +------ + +The EBNF for a NURL is as follows:: + + scheme = "pb://" + + hostname = domain-name | ipv4-address | ipv6-address + net-loc = hostname, [ ":" port ] + net-loc-list = net-loc, [ { ",", net-loc } ] + + swiss-number = segment + + nurl = scheme, hash, "@", net-loc-list, "/", swiss-number + +See https://tools.ietf.org/html/rfc4648#section-5 for the definition of ``urlsafe-base64-string`` +(RFC 4648 provides an ad hoc definition rather than EBNF). +See https://tools.ietf.org/html/rfc3986#section-3.3 for the definition of ``segment``. + +Versions +-------- + +Though all NURLs are syntactically compatible some semantic differences are allowed. +These differences are separated into distinct versions. + +Version 0 +--------- + +A Foolscap fURL is considered the canonical definition of a version 0 NURL. +Notably, +the hash component is defined as the base32-encoded SHA1 hash of the DER form of an x509v3 certificate. +A version 0 NURL is identified by the length of the hash string which is always 32 bytes. + +Version 1 +--------- + +The hash component of a version 1 NURL differs in three ways from the prior version. + +1. The hash function used is SHA3-224 instead of SHA1. + The security of SHA1 `continues to be eroded`_. + Contrariwise SHA3 is currently the most recent addition to the SHA family by NIST. + The 224 bit instance is chosen to keep the output short and because it offers greater collision resistance than SHA1 was thought to offer even at its inception + (prior to security research showing actual collision resistance is lower). +2. The hash is computed over the certificate's SPKI instead of the whole certificate. + This allows certificate re-generation so long as the public key remains the same. + This is useful to allow contact information to be updated or extension of validity period. + Use of an SPKI hash has also been `explored by the web community`_ during its flirtation with using it for HTTPS certificate pinning + (though this is now largely abandoned). +3. The hash is encoded using urlsafe-base64 (without padding) instead of base32. + This provides a more compact representation and minimizes the usability impacts of switching from a 160 bit hash to a 224 bit hash. + +A version 1 NURL is identified by the length of the hash string which is always 38 bytes. + +It is possible for a client to unilaterally upgrade a version 0 NURL to a version 1 NURL. +After establishing and authenticating a connection the client will have received a copy of the server's certificate. +This is sufficient to compute the new hash and rewrite the NURL to upgrade it to version 1. +This provides stronger authentication assurances for future uses but it is not required. + +.. _`continues to be eroded`: https://en.wikipedia.org/wiki/SHA-1#Cryptanalysis_and_validation +.. _`explored by the web community`: https://www.imperialviolet.org/2011/05/04/pinning.html From 983800d593dd473927cee5d51ce795ce11ddcdfb Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Fri, 13 Nov 2020 12:35:03 -0500 Subject: [PATCH 02/31] news fragment --- newsfragments/3503.other | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/3503.other diff --git a/newsfragments/3503.other b/newsfragments/3503.other new file mode 100644 index 000000000..5d0c681b6 --- /dev/null +++ b/newsfragments/3503.other @@ -0,0 +1 @@ +The specification section of the Tahoe-LAFS documentation now includes explicit discussion of the security properties of Foolscap "fURLs" on which it depends. From a40f4ecef3cc763ee8ba40977c44617a0223bb6d Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Fri, 13 Nov 2020 12:56:33 -0500 Subject: [PATCH 03/31] Fix the ebnf and add more references --- docs/specifications/url.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 369f78392..c8beddc1c 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -46,19 +46,23 @@ Syntax The EBNF for a NURL is as follows:: + nurl = scheme, hash, "@", net-loc-list, "/", swiss-number + scheme = "pb://" - hostname = domain-name | ipv4-address | ipv6-address - net-loc = hostname, [ ":" port ] + hash = unreserved + net-loc-list = net-loc, [ { ",", net-loc } ] + net-loc = hostname, [ ":" port ] + hostname = domain | IPv4address | IPv6address swiss-number = segment - nurl = scheme, hash, "@", net-loc-list, "/", swiss-number - -See https://tools.ietf.org/html/rfc4648#section-5 for the definition of ``urlsafe-base64-string`` -(RFC 4648 provides an ad hoc definition rather than EBNF). See https://tools.ietf.org/html/rfc3986#section-3.3 for the definition of ``segment``. +See https://tools.ietf.org/html/rfc2396#appendix-A for the definition of ``unreserved``. +See https://tools.ietf.org/html/draft-main-ipaddr-text-rep-02#section-3.1 for the definition of ``IPv4address``. +See https://tools.ietf.org/html/draft-main-ipaddr-text-rep-02#section-3.2 for the definition of ``IPv6address``. +See https://tools.ietf.org/html/rfc1035#section-2.3.1 for the definition of ``domain``. Versions -------- From c9b9f2d0ce4e5a82cbe4c56e25fd7a6e3010edb1 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Fri, 13 Nov 2020 13:57:36 -0500 Subject: [PATCH 04/31] Be explicit with the version Forward compatibility issues seem like a problem with the hash length based solution --- docs/specifications/url.rst | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index c8beddc1c..8b44e1951 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -46,7 +46,7 @@ Syntax The EBNF for a NURL is as follows:: - nurl = scheme, hash, "@", net-loc-list, "/", swiss-number + nurl = scheme, hash, "@", net-loc-list, "/", swiss-number, [ version1 ] scheme = "pb://" @@ -58,6 +58,8 @@ The EBNF for a NURL is as follows:: swiss-number = segment + version1 = "#v=1" + See https://tools.ietf.org/html/rfc3986#section-3.3 for the definition of ``segment``. See https://tools.ietf.org/html/rfc2396#appendix-A for the definition of ``unreserved``. See https://tools.ietf.org/html/draft-main-ipaddr-text-rep-02#section-3.1 for the definition of ``IPv4address``. @@ -76,7 +78,10 @@ Version 0 A Foolscap fURL is considered the canonical definition of a version 0 NURL. Notably, the hash component is defined as the base32-encoded SHA1 hash of the DER form of an x509v3 certificate. -A version 0 NURL is identified by the length of the hash string which is always 32 bytes. +A version 0 NURL is identified in two ways: + +* Primarily, by the absence of the ``v=1`` fragment. +* Secondarily, by the length of the hash string which is always 32 bytes. Version 1 --------- @@ -96,7 +101,9 @@ The hash component of a version 1 NURL differs in three ways from the prior vers 3. The hash is encoded using urlsafe-base64 (without padding) instead of base32. This provides a more compact representation and minimizes the usability impacts of switching from a 160 bit hash to a 224 bit hash. -A version 1 NURL is identified by the length of the hash string which is always 38 bytes. +A version 1 NURL is identified by the presence of the ``v=1`` fragment. +Though the length of the hash string (38 bytes) could also be used to differentiate it from a version 0 NURL, +there is no guarantee that this will be effective in differentiating it from future versions so this approach should not be used. It is possible for a client to unilaterally upgrade a version 0 NURL to a version 1 NURL. After establishing and authenticating a connection the client will have received a copy of the server's certificate. From b34afb819fab1fe877f1527df870bd79af1a6d69 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Fri, 13 Nov 2020 14:05:22 -0500 Subject: [PATCH 05/31] don't even hint at hash length as a version indicator --- docs/specifications/url.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 8b44e1951..e83abb3fb 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -78,10 +78,7 @@ Version 0 A Foolscap fURL is considered the canonical definition of a version 0 NURL. Notably, the hash component is defined as the base32-encoded SHA1 hash of the DER form of an x509v3 certificate. -A version 0 NURL is identified in two ways: - -* Primarily, by the absence of the ``v=1`` fragment. -* Secondarily, by the length of the hash string which is always 32 bytes. +A version 0 NURL is identified by the absence of the ``v=1`` fragment. Version 1 --------- From 59902e037b1575d041cfb71b2ed856b329429a65 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Fri, 13 Nov 2020 14:11:21 -0500 Subject: [PATCH 06/31] some rst improvements --- docs/specifications/url.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index e83abb3fb..2bb554818 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -33,13 +33,13 @@ NURLs The authentication and authorization properties of fURLs are a good fit for Tahoe-LAFS' requirements. These are not inherently tied to the Foolscap protocol itself. -In particular they are beneficial to :doc:`http-storage-node-protocol` which uses HTTP instead of Foolscap. +In particular they are beneficial to :doc:`../proposed/http-storage-node-protocol` which uses HTTP instead of Foolscap. It is conceivable they will also be used with WebSockets at some point as well. Continuing to refer to these URLs as fURLs when they are being used for other protocols may cause confusion. Therefore, -this document coins the name *NURL* for these URLs. -This can be considered to expand to "New URLs" or "Authe*N*ticating URLs" or "Authorizi*N*g URLs" as the reader prefers. +this document coins the name **NURL** for these URLs. +This can be considered to expand to "**N**\ ew URLs" or "Authe\ **N**\ ticating URLs" or "Authorizi\ **N**\ g URLs" as the reader prefers. Syntax ------ @@ -109,3 +109,4 @@ This provides stronger authentication assurances for future uses but it is not r .. _`continues to be eroded`: https://en.wikipedia.org/wiki/SHA-1#Cryptanalysis_and_validation .. _`explored by the web community`: https://www.imperialviolet.org/2011/05/04/pinning.html +.. _Foolscap: https://github.com/warner/foolscap From e60c643b5f46d9365dc67e6022c904f10c261b45 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 10:57:38 -0500 Subject: [PATCH 07/31] Make configutil.write_config atomic and also make it take a FilePath --- src/allmydata/test/test_configutil.py | 7 +++++-- src/allmydata/util/configutil.py | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/allmydata/test/test_configutil.py b/src/allmydata/test/test_configutil.py index 9e792dc87..19e5b303d 100644 --- a/src/allmydata/test/test_configutil.py +++ b/src/allmydata/test/test_configutil.py @@ -15,6 +15,9 @@ if PY2: import os.path +from twisted.python.filepath import ( + FilePath, +) from twisted.trial import unittest from allmydata.util import configutil @@ -55,7 +58,7 @@ enabled = false # test that set_config can mutate an existing option configutil.set_config(config, "node", "nickname", "Alice!") - configutil.write_config(tahoe_cfg, config) + configutil.write_config(FilePath(tahoe_cfg), config) config = configutil.get_config(tahoe_cfg) self.failUnlessEqual(config.get("node", "nickname"), "Alice!") @@ -63,7 +66,7 @@ enabled = false # test that set_config can set a new option descriptor = "Twas brillig, and the slithy toves Did gyre and gimble in the wabe" configutil.set_config(config, "node", "descriptor", descriptor) - configutil.write_config(tahoe_cfg, config) + configutil.write_config(FilePath(tahoe_cfg), config) config = configutil.get_config(tahoe_cfg) self.failUnlessEqual(config.get("node", "descriptor"), descriptor) diff --git a/src/allmydata/util/configutil.py b/src/allmydata/util/configutil.py index 4bee7d043..d905a8e00 100644 --- a/src/allmydata/util/configutil.py +++ b/src/allmydata/util/configutil.py @@ -59,8 +59,21 @@ def set_config(config, section, option, value): assert config.get(section, option) == value def write_config(tahoe_cfg, config): - with open(tahoe_cfg, "w") as f: - config.write(f) + """ + Write a configuration to a file. + + :param FilePath tahoe_cfg: The path to which to write the config. + + :param ConfigParser config: The configuration to write. + + :return: ``None`` + """ + tmp = tahoe_cfg.temporarySibling() + # FilePath.open can only open files in binary mode which does not work + # with ConfigParser.write. + with open(tmp.path, "wt") as fp: + config.write(fp) + tmp.moveTo(tahoe_cfg) def validate_config(fname, cfg, valid_config): """ From aedac9d570641ad6a30d1a207f9968e8765eca79 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 11:02:58 -0500 Subject: [PATCH 08/31] news fragment --- newsfragments/3511.minor | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 newsfragments/3511.minor diff --git a/newsfragments/3511.minor b/newsfragments/3511.minor new file mode 100644 index 000000000..e69de29bb From 34714d5f6b691d03269100db1914a85ca6756f2e Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 12:42:31 -0500 Subject: [PATCH 09/31] Add everything and nothing config validation helpers --- src/allmydata/test/test_configutil.py | 101 ++++++++++++++++++++++++++ src/allmydata/util/configutil.py | 26 ++++++- 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/src/allmydata/test/test_configutil.py b/src/allmydata/test/test_configutil.py index 19e5b303d..e6035c512 100644 --- a/src/allmydata/test/test_configutil.py +++ b/src/allmydata/test/test_configutil.py @@ -14,6 +14,17 @@ if PY2: from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, list, object, range, str, max, min # noqa: F401 import os.path +from configparser import ( + ConfigParser, +) + +from hypothesis import ( + given, +) +from hypothesis.strategies import ( + dictionaries, + text, +) from twisted.python.filepath import ( FilePath, @@ -23,6 +34,51 @@ from twisted.trial import unittest from allmydata.util import configutil +def arbitrary_config_dicts( + min_sections=0, + max_sections=3, + max_items_per_section=3, + max_item_length=8, + max_value_length=8, +): + """ + Build ``dict[str, dict[str, str]]`` instances populated with arbitrary + configurations. + """ + return dictionaries( + text(), + dictionaries( + text(max_size=max_item_length), + text(max_size=max_value_length), + max_size=max_items_per_section, + ), + min_size=min_sections, + max_size=max_sections, + ) + + +def to_configparser(dictconfig): + """ + Take a ``dict[str, dict[str, str]]`` and turn it into the corresponding + populated ``ConfigParser`` instance. + """ + cp = ConfigParser() + for section, items in dictconfig.items(): + cp.add_section(section) + for k, v in items.items(): + cp.set( + section, + k, + # ConfigParser has a feature that everyone knows and loves + # where it will use %-style interpolation to substitute + # values from one part of the config into another part of + # the config. Escape all our `%`s to avoid hitting this + # and complicating things. + v.replace("%", "%%"), + ) + return cp + + class ConfigUtilTests(unittest.TestCase): def setUp(self): super(ConfigUtilTests, self).setUp() @@ -166,3 +222,48 @@ enabled = false config = configutil.get_config(fname) self.assertEqual(config.get("node", "a"), "foo") self.assertEqual(config.get("node", "b"), "bar") + + @given(arbitrary_config_dicts()) + def test_everything_valid(self, cfgdict): + """ + ``validate_config`` returns ``None`` when the validator is + ``ValidConfiguration.everything()``. + """ + cfg = to_configparser(cfgdict) + self.assertIs( + configutil.validate_config( + "", + cfg, + configutil.ValidConfiguration.everything(), + ), + None, + ) + + @given(arbitrary_config_dicts(min_sections=1)) + def test_nothing_valid(self, cfgdict): + """ + ``validate_config`` raises ``UnknownConfigError`` when the validator is + ``ValidConfiguration.nothing()`` for all non-empty configurations. + """ + cfg = to_configparser(cfgdict) + with self.assertRaises(configutil.UnknownConfigError): + configutil.validate_config( + "", + cfg, + configutil.ValidConfiguration.nothing(), + ) + + def test_nothing_empty_valid(self): + """ + ``validate_config`` returns ``None`` when the validator is + ``ValidConfiguration.nothing()`` if the configuration is empty. + """ + cfg = ConfigParser() + self.assertIs( + configutil.validate_config( + "", + cfg, + configutil.ValidConfiguration.nothing(), + ), + None, + ) diff --git a/src/allmydata/util/configutil.py b/src/allmydata/util/configutil.py index d905a8e00..c85f58af3 100644 --- a/src/allmydata/util/configutil.py +++ b/src/allmydata/util/configutil.py @@ -115,10 +115,34 @@ class ValidConfiguration(object): an item name as bytes and returns True if that section, item pair is valid, False otherwise. """ - _static_valid_sections = attr.ib() + _static_valid_sections = attr.ib( + validator=attr.validators.instance_of(dict) + ) _is_valid_section = attr.ib(default=lambda section_name: False) _is_valid_item = attr.ib(default=lambda section_name, item_name: False) + @classmethod + def everything(cls): + """ + Create a validator which considers everything valid. + """ + return cls( + {}, + lambda section_name: True, + lambda section_name, item_name: True, + ) + + @classmethod + def nothing(cls): + """ + Create a validator which considers nothing valid. + """ + return cls( + {}, + lambda section_name: False, + lambda section_name, item_name: False, + ) + def is_valid_section(self, section_name): """ :return: True if the given section name is valid, False otherwise. From 021615bdfffbe56b803e0602f72a62cebb358b36 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 12:44:52 -0500 Subject: [PATCH 10/31] Some further test_configutil improvements --- src/allmydata/test/test_configutil.py | 47 ++++++++++++--------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/allmydata/test/test_configutil.py b/src/allmydata/test/test_configutil.py index e6035c512..04631cb55 100644 --- a/src/allmydata/test/test_configutil.py +++ b/src/allmydata/test/test_configutil.py @@ -128,13 +128,15 @@ enabled = false self.failUnlessEqual(config.get("node", "descriptor"), descriptor) def test_config_validation_success(self): - fname = self.create_tahoe_cfg('[node]\nvalid = foo\n') - - config = configutil.get_config(fname) + """ + ``configutil.validate_config`` returns ``None`` when the configuration it + is given has nothing more than the static sections and items defined + by the validator. + """ # should succeed, no exceptions configutil.validate_config( - fname, - config, + "", + to_configparser({"node": {"valid": "foo"}}), self.static_valid_config, ) @@ -144,24 +146,20 @@ enabled = false validation but are matched by the dynamic validation is considered valid. """ - fname = self.create_tahoe_cfg('[node]\nvalid = foo\n') - - config = configutil.get_config(fname) # should succeed, no exceptions configutil.validate_config( - fname, - config, + "", + to_configparser({"node": {"valid": "foo"}}), self.dynamic_valid_config, ) def test_config_validation_invalid_item(self): - fname = self.create_tahoe_cfg('[node]\nvalid = foo\ninvalid = foo\n') - - config = configutil.get_config(fname) + config = to_configparser({"node": {"valid": "foo", "invalid": "foo"}}) e = self.assertRaises( configutil.UnknownConfigError, configutil.validate_config, - fname, config, + "", + config, self.static_valid_config, ) self.assertIn("section [node] contains unknown option 'invalid'", str(e)) @@ -171,13 +169,12 @@ enabled = false A configuration with a section that is matched by neither the static nor dynamic validators is rejected. """ - fname = self.create_tahoe_cfg('[node]\nvalid = foo\n[invalid]\n') - - config = configutil.get_config(fname) + config = to_configparser({"node": {"valid": "foo"}, "invalid": {}}) e = self.assertRaises( configutil.UnknownConfigError, configutil.validate_config, - fname, config, + "", + config, self.static_valid_config, ) self.assertIn("contains unknown section [invalid]", str(e)) @@ -187,13 +184,12 @@ enabled = false A configuration with a section that is matched by neither the static nor dynamic validators is rejected. """ - fname = self.create_tahoe_cfg('[node]\nvalid = foo\n[invalid]\n') - - config = configutil.get_config(fname) + config = to_configparser({"node": {"valid": "foo"}, "invalid": {}}) e = self.assertRaises( configutil.UnknownConfigError, configutil.validate_config, - fname, config, + "", + config, self.dynamic_valid_config, ) self.assertIn("contains unknown section [invalid]", str(e)) @@ -203,13 +199,12 @@ enabled = false A configuration with a section, item pair that is matched by neither the static nor dynamic validators is rejected. """ - fname = self.create_tahoe_cfg('[node]\nvalid = foo\ninvalid = foo\n') - - config = configutil.get_config(fname) + config = to_configparser({"node": {"valid": "foo", "invalid": "foo"}}) e = self.assertRaises( configutil.UnknownConfigError, configutil.validate_config, - fname, config, + "", + config, self.dynamic_valid_config, ) self.assertIn("section [node] contains unknown option 'invalid'", str(e)) From 84647e25b78e7d78e101e7157414a181413aeb98 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 12:59:23 -0500 Subject: [PATCH 11/31] Refine the ConfigParser generator Limit the characters used in the section and item name strategies. ConfigParser doesn't allow all characters in all places. --- src/allmydata/test/test_configutil.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/allmydata/test/test_configutil.py b/src/allmydata/test/test_configutil.py index 04631cb55..ea7759fec 100644 --- a/src/allmydata/test/test_configutil.py +++ b/src/allmydata/test/test_configutil.py @@ -17,6 +17,9 @@ import os.path from configparser import ( ConfigParser, ) +from functools import ( + partial, +) from hypothesis import ( given, @@ -24,6 +27,7 @@ from hypothesis import ( from hypothesis.strategies import ( dictionaries, text, + characters, ) from twisted.python.filepath import ( @@ -37,6 +41,7 @@ from allmydata.util import configutil def arbitrary_config_dicts( min_sections=0, max_sections=3, + max_section_name_size=8, max_items_per_section=3, max_item_length=8, max_value_length=8, @@ -45,10 +50,23 @@ def arbitrary_config_dicts( Build ``dict[str, dict[str, str]]`` instances populated with arbitrary configurations. """ + identifier_text = partial( + text, + # Don't allow most control characters or spaces + alphabet=characters( + blacklist_categories=('Cc', 'Cs', 'Zs'), + ), + ) return dictionaries( - text(), + identifier_text( + min_size=1, + max_size=max_section_name_size, + ), dictionaries( - text(max_size=max_item_length), + identifier_text( + min_size=1, + max_size=max_item_length, + ), text(max_size=max_value_length), max_size=max_items_per_section, ), From 53aa434d77d52931ef08a48a15b8ceb34d9665d4 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 13:01:08 -0500 Subject: [PATCH 12/31] Add a helper to make a deep copy of a ConfigParser This will help avoid unintentional side-effects --- src/allmydata/test/test_configutil.py | 13 +++++++++++++ src/allmydata/util/configutil.py | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/allmydata/test/test_configutil.py b/src/allmydata/test/test_configutil.py index ea7759fec..1b8fb5029 100644 --- a/src/allmydata/test/test_configutil.py +++ b/src/allmydata/test/test_configutil.py @@ -280,3 +280,16 @@ enabled = false ), None, ) + + @given(arbitrary_config_dicts()) + def test_copy_config(self, cfgdict): + """ + ``copy_config`` creates a new ``ConfigParser`` object containing the same + values as its input. + """ + cfg = to_configparser(cfgdict) + copied = configutil.copy_config(cfg) + # Should be equal + self.assertEqual(cfg, copied) + # But not because they're the same object. + self.assertIsNot(cfg, copied) diff --git a/src/allmydata/util/configutil.py b/src/allmydata/util/configutil.py index c85f58af3..8063ba449 100644 --- a/src/allmydata/util/configutil.py +++ b/src/allmydata/util/configutil.py @@ -173,6 +173,23 @@ class ValidConfiguration(object): ) +def copy_config(old): + """ + Return a brand new ``ConfigParser`` containing the same values as + the given object. + + :param ConfigParser old: The configuration to copy. + + :return ConfigParser: The new object containing the same configuration. + """ + new = ConfigParser() + for section_name in old.sections(): + new.add_section(section_name) + for k, v in old.items(section_name): + new.set(section_name, k, v.replace("%", "%%")) + return new + + def _either(f, g): """ :return: A function which returns True if either f or g returns True. From f21e3189b5ca91d6f59f9eb1988e79b278100a0d Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 13:17:16 -0500 Subject: [PATCH 13/31] Remove some repetition between read_config and config_from_string --- src/allmydata/node.py | 105 +++++++++++++++++--------- src/allmydata/test/cli/test_create.py | 7 +- 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/src/allmydata/node.py b/src/allmydata/node.py index 9e7143fd4..f320e6e12 100644 --- a/src/allmydata/node.py +++ b/src/allmydata/node.py @@ -22,9 +22,14 @@ import errno import tempfile from base64 import b32decode, b32encode +import attr + # On Python 2 this will be the backported package. import configparser +from twisted.python.filepath import ( + FilePath, +) from twisted.python import log as twlog from twisted.application import service from twisted.python.failure import Failure @@ -192,25 +197,27 @@ def read_config(basedir, portnumfile, generated_files=[], _valid_config=None): # canonicalize the portnum file portnumfile = os.path.join(basedir, portnumfile) - # (try to) read the main config file - config_fname = os.path.join(basedir, "tahoe.cfg") + config_path = FilePath(basedir).child("tahoe.cfg") try: - parser = configutil.get_config(config_fname) + config_str = config_path.getContent() except EnvironmentError as e: if e.errno != errno.ENOENT: raise # The file is missing, just create empty ConfigParser. - parser = configutil.get_config_from_string(u"") + config_str = u"" + else: + config_str = config_str.decode("utf-8-sig") - configutil.validate_config(config_fname, parser, _valid_config) - - # make sure we have a private configuration area - fileutil.make_dirs(os.path.join(basedir, "private"), 0o700) - - return _Config(parser, portnumfile, basedir, config_fname) + return config_from_string( + basedir, + portnumfile, + config_str, + _valid_config, + config_path, + ) -def config_from_string(basedir, portnumfile, config_str, _valid_config=None): +def config_from_string(basedir, portnumfile, config_str, _valid_config=None, fpath=None): """ load and validate configuration from in-memory string """ @@ -223,9 +230,19 @@ def config_from_string(basedir, portnumfile, config_str, _valid_config=None): # load configuration from in-memory string parser = configutil.get_config_from_string(config_str) - fname = "" - configutil.validate_config(fname, parser, _valid_config) - return _Config(parser, portnumfile, basedir, fname) + configutil.validate_config( + "" if fpath is None else fpath.path, + parser, + _valid_config, + ) + + return _Config( + parser, + portnumfile, + basedir, + fpath, + _valid_config, + ) def get_app_versions(): @@ -260,6 +277,7 @@ def _error_about_old_config_files(basedir, generated_files): raise e +@attr.s class _Config(object): """ Manages configuration of a Tahoe 'node directory'. @@ -268,30 +286,47 @@ class _Config(object): class; names and funtionality have been kept the same while moving the code. It probably makes sense for several of these APIs to have better names. + + :ivar ConfigParser config: The actual configuration values. + + :ivar str portnum_fname: filename to use for the port-number file (a + relative path inside basedir). + + :ivar str _basedir: path to our "node directory", inside which all + configuration is managed. + + :ivar (FilePath|NoneType) config_path: The path actually used to create + the configparser (might be ``None`` if using in-memory data). + + :ivar ValidConfiguration valid_config_sections: The validator for the + values in this configuration. """ + config = attr.ib(validator=attr.validators.instance_of(configparser.ConfigParser)) + portnum_fname = attr.ib() + _basedir = attr.ib( + converter=lambda basedir: abspath_expanduser_unicode(ensure_text(basedir)), + ) + config_path = attr.ib( + validator=attr.validators.optional( + attr.validators.instance_of(FilePath), + ), + ) + valid_config_sections = attr.ib( + default=configutil.ValidConfiguration.everything(), + validator=attr.validators.instance_of(configutil.ValidConfiguration), + ) - def __init__(self, configparser, portnum_fname, basedir, config_fname): - """ - :param configparser: a ConfigParser instance + @property + def nickname(self): + nickname = self.get_config("node", "nickname", u"") + assert isinstance(nickname, str) + return nickname - :param portnum_fname: filename to use for the port-number file - (a relative path inside basedir) - - :param basedir: path to our "node directory", inside which all - configuration is managed - - :param config_fname: the pathname actually used to create the - configparser (might be 'fake' if using in-memory data) - """ - self.portnum_fname = portnum_fname - self._basedir = abspath_expanduser_unicode(ensure_text(basedir)) - self._config_fname = config_fname - self.config = configparser - self.nickname = self.get_config("node", "nickname", u"") - assert isinstance(self.nickname, str) - - def validate(self, valid_config_sections): - configutil.validate_config(self._config_fname, self.config, valid_config_sections) + @property + def _config_fname(self): + if self.config_path is None: + return "" + return self.config_path.path def write_config_file(self, name, value, mode="w"): """ diff --git a/src/allmydata/test/cli/test_create.py b/src/allmydata/test/cli/test_create.py index f013c0205..aee07a671 100644 --- a/src/allmydata/test/cli/test_create.py +++ b/src/allmydata/test/cli/test_create.py @@ -52,13 +52,8 @@ class Config(unittest.TestCase): create_node.write_node_config(f, opts) create_node.write_client_config(f, opts) - config = configutil.get_config(fname) # should succeed, no exceptions - configutil.validate_config( - fname, - config, - client._valid_config(), - ) + client.read_config(d, "") @defer.inlineCallbacks def test_client(self): From 862d32a90d27b6387affa6f56d7d323ab7829747 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 13:18:21 -0500 Subject: [PATCH 14/31] Add `_Config.set_config` for presistently changing config values --- src/allmydata/node.py | 18 ++++++++ src/allmydata/test/test_node.py | 81 ++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/allmydata/node.py b/src/allmydata/node.py index f320e6e12..99062d771 100644 --- a/src/allmydata/node.py +++ b/src/allmydata/node.py @@ -371,6 +371,24 @@ class _Config(object): ) return default + def set_config(self, section, option, value): + """ + Set a config options in a section and re-write the tahoe.cfg file + """ + if option.endswith(".furl") and "#" in value: + raise UnescapedHashError(section, option, value) + + copied_config = configutil.copy_config(self.config) + configutil.set_config(copied_config, section, option, value) + configutil.validate_config( + self._config_fname, + copied_config, + self.valid_config_sections, + ) + if self.config_path is not None: + configutil.write_config(self.config_path, copied_config) + self.config = copied_config + def get_config_from_file(self, name, required=False): """Get the (string) contents of a config file, or None if the file did not exist. If required=True, raise an exception rather than diff --git a/src/allmydata/test/test_node.py b/src/allmydata/test/test_node.py index 693183ea4..a4c64a654 100644 --- a/src/allmydata/test/test_node.py +++ b/src/allmydata/test/test_node.py @@ -29,6 +29,9 @@ from hypothesis.strategies import ( from unittest import skipIf +from twisted.python.filepath import ( + FilePath, +) from twisted.trial import unittest from twisted.internet import defer @@ -52,7 +55,11 @@ from allmydata import client from allmydata.util import fileutil, iputil from allmydata.util.namespace import Namespace -from allmydata.util.configutil import UnknownConfigError +from allmydata.util.configutil import ( + ValidConfiguration, + UnknownConfigError, +) + from allmydata.util.i2p_provider import create as create_i2p_provider from allmydata.util.tor_provider import create as create_tor_provider import allmydata.test.common_util as testutil @@ -431,6 +438,78 @@ class TestCase(testutil.SignalMixin, unittest.TestCase): yield client.create_client(basedir) self.failUnless(ns.called) + def test_set_config_unescaped_furl_hash(self): + """ + ``_Config.set_config`` raises ``UnescapedHashError`` if the item being set + is a furl and the value includes ``"#"`` and does not set the value. + """ + basedir = self.mktemp() + new_config = config_from_string(basedir, "", "") + with self.assertRaises(UnescapedHashError): + new_config.set_config("foo", "bar.furl", "value#1") + with self.assertRaises(MissingConfigEntry): + new_config.get_config("foo", "bar.furl") + + def test_set_config_new_section(self): + """ + ``_Config.set_config`` can be called with the name of a section that does + not already exist to create that section and set an item in it. + """ + basedir = self.mktemp() + new_config = config_from_string(basedir, "", "", ValidConfiguration.everything()) + new_config.set_config("foo", "bar", "value1") + self.assertEqual( + new_config.get_config("foo", "bar"), + "value1" + ) + + def test_set_config_replace(self): + """ + ``_Config.set_config`` can be called with a section and item that already + exists to change an existing value to a new one. + """ + basedir = self.mktemp() + new_config = config_from_string(basedir, "", "", ValidConfiguration.everything()) + new_config.set_config("foo", "bar", "value1") + new_config.set_config("foo", "bar", "value2") + self.assertEqual( + new_config.get_config("foo", "bar"), + "value2" + ) + + def test_set_config_write(self): + """ + ``_Config.set_config`` persists the configuration change so it can be + re-loaded later. + """ + # Let our nonsense config through + valid_config = ValidConfiguration.everything() + basedir = FilePath(self.mktemp()) + basedir.makedirs() + cfg = basedir.child(b"tahoe.cfg") + cfg.setContent(b"") + new_config = read_config(basedir.path, "", [], valid_config) + new_config.set_config("foo", "bar", "value1") + loaded_config = read_config(basedir.path, "", [], valid_config) + self.assertEqual( + loaded_config.get_config("foo", "bar"), + "value1", + ) + + def test_set_config_rejects_invalid_config(self): + """ + ``_Config.set_config`` raises ``UnknownConfigError`` if the section or + item is not recognized by the validation object and does not set the + value. + """ + # Make everything invalid. + valid_config = ValidConfiguration.nothing() + new_config = config_from_string(self.mktemp(), "", "", valid_config) + with self.assertRaises(UnknownConfigError): + new_config.set_config("foo", "bar", "baz") + with self.assertRaises(MissingConfigEntry): + new_config.get_config("foo", "bar") + class TestMissingPorts(unittest.TestCase): """ From 88ce823618c9066d374f2d615904ffe550eb8e44 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 18:26:52 -0500 Subject: [PATCH 15/31] Update integration test caller of altered write_config --- integration/util.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/integration/util.py b/integration/util.py index a64bcbf8e..d212a002f 100644 --- a/integration/util.py +++ b/integration/util.py @@ -6,6 +6,9 @@ from os.path import exists, join from six.moves import StringIO from functools import partial +from twisted.python.filepath import ( + FilePath, +) from twisted.internet.defer import Deferred, succeed from twisted.internet.protocol import ProcessProtocol from twisted.internet.error import ProcessExitedAlready, ProcessDone @@ -258,7 +261,7 @@ def _create_node(reactor, request, temp_dir, introducer_furl, flog_gatherer, nam config_path = join(node_dir, 'tahoe.cfg') config = get_config(config_path) set_config(config, 'node', 'log_gatherer.furl', flog_gatherer) - write_config(config_path, config) + write_config(FilePath(config_path), config) created_d.addCallback(created) d = Deferred() From 594f8019d1b20326bcd25846ab3866adca61b782 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 18:29:36 -0500 Subject: [PATCH 16/31] Better support Windows here --- src/allmydata/util/configutil.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/allmydata/util/configutil.py b/src/allmydata/util/configutil.py index 8063ba449..ea64e1704 100644 --- a/src/allmydata/util/configutil.py +++ b/src/allmydata/util/configutil.py @@ -20,6 +20,10 @@ from configparser import ConfigParser import attr +from twisted.python.runtime import ( + platform, +) + class UnknownConfigError(Exception): """ @@ -73,6 +77,10 @@ def write_config(tahoe_cfg, config): # with ConfigParser.write. with open(tmp.path, "wt") as fp: config.write(fp) + # Windows doesn't have atomic overwrite semantics for moveTo. Thus we end + # up slightly less than atomic. + if platform.isWindows(): + tahoe_cfg.remove() tmp.moveTo(tahoe_cfg) def validate_config(fname, cfg, valid_config): From e385cd02a36062030cbb1909d54012e7c8292395 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 25 Nov 2020 18:30:36 -0500 Subject: [PATCH 17/31] Footnote about the zero-or-more thing for fURLs --- docs/specifications/url.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 2bb554818..05807a858 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -15,7 +15,7 @@ Foolscap connection setup takes as an input a Foolscap URL or a *fURL*. A fURL includes three components: * the base32-encoded SHA1 hash of the DER form of an x509v3 certificate -* zero or more network addresses +* zero or more network addresses [1]_ * an object identifier A Foolscap client tries to connect to each network address in turn. @@ -110,3 +110,11 @@ This provides stronger authentication assurances for future uses but it is not r .. _`continues to be eroded`: https://en.wikipedia.org/wiki/SHA-1#Cryptanalysis_and_validation .. _`explored by the web community`: https://www.imperialviolet.org/2011/05/04/pinning.html .. _Foolscap: https://github.com/warner/foolscap + +.. [1] ``foolscap.furl.decode_furl`` is taken as the canonical definition of the syntax of a fURL. + The **location hints** part of the fURL, + as it is referred to in Foolscap, + is matched by the regular expression fragment ``([^/]*)``. + Since this matches the empty string, + no network addresses are required to form a fURL. + The supporting code around the regular expression also takes extra steps to allow an empty string to match here. From c4f7643b999c1266f20ca1ec747d42027c44855f Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 07:25:25 -0500 Subject: [PATCH 18/31] introduce "swiss number" and clarify text a bit --- docs/specifications/url.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 05807a858..16bf79d9f 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -26,7 +26,10 @@ This serves as the process by which the client authenticates the server. The client can then exercise further Foolscap functionality using the fURL's object identifier. If the object identifier is an unguessable, secret string then it serves as a capability. -This serves as the process by which the server authorizes the client. +This unguessable identifier is sometimes called a `swiss number`_ (or swissnum). +The client's use of the swissnum is what allows the server to authorize the client. + +.. _`swiss number`: http://wiki.erights.org/wiki/Swiss_number NURLs ----- From ee72029bd49f44bde17b0d66d54c89a6de104823 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 07:31:59 -0500 Subject: [PATCH 19/31] warn about what's unauthenticated --- docs/specifications/url.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 16bf79d9f..24794ceec 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -98,6 +98,11 @@ The hash component of a version 1 NURL differs in three ways from the prior vers This is useful to allow contact information to be updated or extension of validity period. Use of an SPKI hash has also been `explored by the web community`_ during its flirtation with using it for HTTPS certificate pinning (though this is now largely abandoned). + +.. note:: + *Only* the certificate's keypair is pinned by the SPKI hash. + The freedom to change every other part of the certificate is coupled with the fact that all other parts of the certificate contain arbitrary information set by the private key holder. + 3. The hash is encoded using urlsafe-base64 (without padding) instead of base32. This provides a more compact representation and minimizes the usability impacts of switching from a 160 bit hash to a 224 bit hash. From 02579768bd379a9c453870620a655f3b9e2e1f26 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 09:18:12 -0500 Subject: [PATCH 20/31] Still gonna TLS --- docs/specifications/url.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 24794ceec..1f55b7db3 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -44,6 +44,9 @@ Therefore, this document coins the name **NURL** for these URLs. This can be considered to expand to "**N**\ ew URLs" or "Authe\ **N**\ ticating URLs" or "Authorizi\ **N**\ g URLs" as the reader prefers. +The anticipated use for a **NURL** will still be to establish a TLS connection to a peer. +The protocol run over that TLS connection could be Foolscap though it is more likely to be an HTTP-based protocol. + Syntax ------ From ccc6afa14063cf3ff69877850b1761f187d48cf0 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 09:43:05 -0500 Subject: [PATCH 21/31] explicit callback --- docs/specifications/url.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 1f55b7db3..8829d756f 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -45,7 +45,7 @@ this document coins the name **NURL** for these URLs. This can be considered to expand to "**N**\ ew URLs" or "Authe\ **N**\ ticating URLs" or "Authorizi\ **N**\ g URLs" as the reader prefers. The anticipated use for a **NURL** will still be to establish a TLS connection to a peer. -The protocol run over that TLS connection could be Foolscap though it is more likely to be an HTTP-based protocol. +The protocol run over that TLS connection could be Foolscap though it is more likely to be an HTTP-based protocol (such as GBS). Syntax ------ From 4ee28a8479235d463c427a76336508c05ad0f748 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 10:16:40 -0500 Subject: [PATCH 22/31] Some example NURLs for flavor --- docs/specifications/url.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 8829d756f..e6e905bab 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -86,6 +86,12 @@ Notably, the hash component is defined as the base32-encoded SHA1 hash of the DER form of an x509v3 certificate. A version 0 NURL is identified by the absence of the ``v=1`` fragment. +Examples +~~~~~~~~ + +* ``pb://sisi4zenj7cxncgvdog7szg3yxbrnamy@tcp:127.1:34399/xphmwz6lx24rh2nxlinni`` +* ``pb://2uxmzoqqimpdwowxr24q6w5ekmxcymby@localhost:47877/riqhpojvzwxujhna5szkn`` + Version 1 --------- @@ -118,6 +124,12 @@ After establishing and authenticating a connection the client will have received This is sufficient to compute the new hash and rewrite the NURL to upgrade it to version 1. This provides stronger authentication assurances for future uses but it is not required. +Examples +~~~~~~~~ + +* ``pb://1WUX44xKjKdpGLohmFcBNuIRN-8rlv1Iij_7rQ@tcp:127.1:34399/jhjbc3bjbhk#v=1`` +* ``pb://azEu8vlRpnEeYm0DySQDeNY3Z2iJXHC_bsbaAw@localhost:47877/64i4aokv4ej#v=1`` + .. _`continues to be eroded`: https://en.wikipedia.org/wiki/SHA-1#Cryptanalysis_and_validation .. _`explored by the web community`: https://www.imperialviolet.org/2011/05/04/pinning.html .. _Foolscap: https://github.com/warner/foolscap From a5f0be6513936dfcb18c5719decaf06cd87f9765 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 10:16:49 -0500 Subject: [PATCH 23/31] Oops these have schemes most of the time except tcp is implied if the scheme is missing Is this grammar ambiguous? I don't know but I think so. --- docs/specifications/url.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index e6e905bab..32e755bed 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -59,7 +59,13 @@ The EBNF for a NURL is as follows:: hash = unreserved net-loc-list = net-loc, [ { ",", net-loc } ] - net-loc = hostname, [ ":" port ] + net-loc = tcp-loc | tor-loc | i2p-loc + + tcp-loc = [ "tcp:" ], hostname, [ ":" port ] + tor-loc = "tor:", hostname, [ ":" port ] + i2p-loc = "i2p:", i2p-addr, [ ":" port ] + + i2p-addr = { unreserved }, ".i2p" hostname = domain | IPv4address | IPv6address swiss-number = segment From b2c0d1b7ae67e990fdd8d6e9f5aa0c81dc64e76a Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 10:31:22 -0500 Subject: [PATCH 24/31] Caveat the rest of the certificate fields --- docs/specifications/url.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 32e755bed..4aa5c21d6 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -117,6 +117,9 @@ The hash component of a version 1 NURL differs in three ways from the prior vers .. note:: *Only* the certificate's keypair is pinned by the SPKI hash. The freedom to change every other part of the certificate is coupled with the fact that all other parts of the certificate contain arbitrary information set by the private key holder. + It is neither guaranteed nor expected that a certificate-issuing authority has validated this information. + Therefore, + *all* certificate fields should be considered within the context of the relationship identified by the SPKI hash. 3. The hash is encoded using urlsafe-base64 (without padding) instead of base32. This provides a more compact representation and minimizes the usability impacts of switching from a 160 bit hash to a 224 bit hash. From c3ba08c205008c142567d34a869ccb7f9e5fefca Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 10:41:26 -0500 Subject: [PATCH 25/31] open questions --- docs/specifications/url.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/specifications/url.rst b/docs/specifications/url.rst index 4aa5c21d6..31fb05fad 100644 --- a/docs/specifications/url.rst +++ b/docs/specifications/url.rst @@ -150,3 +150,16 @@ Examples Since this matches the empty string, no network addresses are required to form a fURL. The supporting code around the regular expression also takes extra steps to allow an empty string to match here. + +Open Questions +-------------- + +1. Should we make a hard recommendation that all certificate fields are ignored? + The system makes no guarantees about validation of these fields. + Is it just an unnecessary risk to let a user see them? + +2. Should the version specifier be a query-arg-alike or a fragment-alike? + The value is only necessary on the client side which makes it similar to an HTTP URL fragment. + The current Tahoe-LAFS configuration parsing code has special handling of the fragment character (``#``) which makes it unusable. + However, + the configuration parsing code is easily changed. From d81fe54faf1eeea19f41beeebccb43f489f9d33a Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 10:50:36 -0500 Subject: [PATCH 26/31] typo fix --- src/allmydata/node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/allmydata/node.py b/src/allmydata/node.py index 99062d771..93fb7461d 100644 --- a/src/allmydata/node.py +++ b/src/allmydata/node.py @@ -373,7 +373,7 @@ class _Config(object): def set_config(self, section, option, value): """ - Set a config options in a section and re-write the tahoe.cfg file + Set a config option in a section and re-write the tahoe.cfg file """ if option.endswith(".furl") and "#" in value: raise UnescapedHashError(section, option, value) From df53fdcf9bd923e7b548d21d5365f3179e8ba8aa Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Thu, 26 Nov 2020 10:53:42 -0500 Subject: [PATCH 27/31] add missing docs to new set_config method --- src/allmydata/node.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/allmydata/node.py b/src/allmydata/node.py index 93fb7461d..98d7dbafa 100644 --- a/src/allmydata/node.py +++ b/src/allmydata/node.py @@ -374,6 +374,16 @@ class _Config(object): def set_config(self, section, option, value): """ Set a config option in a section and re-write the tahoe.cfg file + + :param str section: The name of the section in which to set the + option. + + :param str option: The name of the option to set. + + :param str value: The value of the option. + + :raise UnescapedHashError: If the option holds a fURL and there is a + ``#`` in the value. """ if option.endswith(".furl") and "#" in value: raise UnescapedHashError(section, option, value) From ff49414ae9c3c58345b8e04c04372ef6012c78e3 Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 30 Nov 2020 17:20:23 -0500 Subject: [PATCH 28/31] Use Tor project's new repository signing key Fix for https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3542 --- integration/install-tor.sh | 1440 +++++++++++++++++++----------------- newsfragments/3542.minor | 0 2 files changed, 757 insertions(+), 683 deletions(-) create mode 100644 newsfragments/3542.minor diff --git a/integration/install-tor.sh b/integration/install-tor.sh index 2478389f8..66fa64cb1 100755 --- a/integration/install-tor.sh +++ b/integration/install-tor.sh @@ -25,694 +25,768 @@ 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 +PVg3cta5Ctmn/mM2ehO3Y+XCEtenTZJP8ZtHg3pZEt4PtQaOBtrWxqX1h633KEIa +0a7dASaU4KOZg/SyKoChcSr2pY+jtzDacsZ8q/et+zz2gktdvcDSkJurkPjlORx9 +CcWFhOd7PFP4ZWn0A0AkufMpbLXhlVJCmSykyyG0Don3C9i7sG045303KNy6CA+l +jvcm/EBeeMWvLMdjr51XmkGFjaAs4Lyw0CfKj9uNZdriOtSVtH2kcMmNSvcUln2B +FZTBo2NeRKGJAhwEEAECAAYFAktpE+EACgkQxel8K2OfamZhpg/+P9NPk88rqRnE +uDVDHodlkA5hG0d0Yi5vkV9rw07yjYut474aUd3FjJFqNEoiW+6dFbNy6YqqYPhr +XLtnfJl5LAUJUzMA2aSLtbuX+cq18DCv5ZmU4DW6kZOWi5vX7QkQCTTLP03VlcD3 +Gu6HyofseBMgE4zoEXdmZSZmPnOygakFLzC9w+D1XfK2gcaTKjAJJdW80aY56eUe +zFDKLhOw+YzIK1/ZeeOTS4LeITtTq5J6/hnwHrJdjApX80v2WJzVVoy7lQbxAPsl +JHZdYVFCBy2Tyk7kYdddVxYCcdYr0e8A+GfG/tQJGxvZ3O4nOrezSv0XmlhLZ5rj +Cn8M6fg/NKUXsPtXiac+DQJbr5RwQ5Sc7bnPVsCywqetOeA+xv3L2wi94rg4u97Q +iwqhDW0SE9zZuQL5vaXl/GFpaRXs+mVGATS9h+0lDBQPi21oPkdN/BKKzr//2GCl +5VFb+rkOY65HthCuiIrT8jFGArJIF4nXku/4BPpNrganC89iTsd5+UUNFIlta+WY +kENQ9tC2mwj96BaK0KyRQZP9AAzTo5wG8aouczptpwSH0aECJNy8kd/UR8IAkZkx +jY4+zyfQDlb4aNDsVGvempgjFcNo0rciKrPQl5GyRLQj2azuv46gaGcYzqsobejS +/2jqJLMnkTeExaCryrWuXo/raWBWQLOJAhwEEAECAAYFAkybgq4ACgkQ2HRyfjOa +f6huKQ//Yfey5BJXqZqIt9i6tyw2VqzMtZ1gAqFdEKeuSmz30xty9g6KknIjpeZo ++POb3rQFUKGZ/q4AjWKdD9C5WUvLcXd0RCWeDG7dmD78h35OWwqhc+8FXO1vU0nG +yFdEx89cNiO42M/z+eYeoysgVL3ixbCjJlrN4MHrilqshxH5MvG7JfIfoPwucQyt +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 +EWaMEjPPQbNJ1KrFzAFfIUeFTbBL5kMmJK5aYVUiHWnLZq0SK5OlWGqBihuRLI7O +IoBOjlcoXvFoEgSkgUKpapE6C9VkErW60WCK91sMhaa8CY9pVDPaanMG2o73BfS3 +jGPylm4H2+8jlJ1+l5ietvoyiqOST1iIfOsbi30mxuVJ4JBvKtmapqpBwT6eNvCi +PKsMyjB5oWI5IVbK8MDIaYQM9TL+nyMGhl19GzcUMP8tZRlCifM9b/zmMMt1sgVY +0koF8AZfh3Ho9KLyXqNMUtXAFSQrAcTbN5SmzjlJtl+hz6uhiHH9kAeSX4MFRXX6 +JDfZxyAw72JqJkZaPEAKQCpodkNwNG9b2dedIBsTaD9IoEkryDtR17qV2ePwlCey +muwNnGVVaJ8hLbI7ZATbIaSn7XNvMGM8hX0N/ram5nTvrR2laG1o1ss5oxtg7PfT +rhMyCTrzTcxc8VskAgtbJjoyi4kCHAQQAQIABgUCUHsxcgAKCRBTnENrguQL99ul +EACwc68fdeLrP5U/oRJ38+WkQxO08Doa7dspj1cy763kXGlzp27xvXlc9xWMEkLZ +eFG6az+sI3YvW6Lq1PZYzQRLsjgMKDNDMDMB5xR3g65lRW4KKd0pCs5/CRxs2hDP +k6ulih2E12N/yqwgXTstbEDzXmaBe/66uGdtAnK0GinXdE+5wBMu0y0CFxJygkCm +to/hOeYufOHSLIcVVrzbsLH3meuPX9hUxjN4RIOduwWeHi0IWUCx5IyGPtMNBAfX ++AIVYmX7rWpEH+bqlfaEZYJh5kLDebzCq8gtRteRzvRz0jCX/Zr7SZu1PskjRN+e +MLdkNgsF9TXQy2vFFM5aRoEenHeD5gMla8pBFnbZP+AA4nPrbuKUyVcfdrLIIgQE +KIvxjKetSj3MV1PTuH5YNBw2I3qxrgmrv+YlClmiy/VQXt3///////////////// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// -////////////////////////////////////iQIcBBABAgAGBQJRcGlBAAoJELlv -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 +Q2lYX0csvuv3Gp5MuNpCuHS5bW4kLyOpRZh1JrqniL8K1Mp8cdBhMf6H+ZckQuXS +hGHwOhGyBMu3X7biXikSvdgQmbDQMtaDbxuYZ+JGXF0uacPVnlAUwW1F55IIhmUH +IV7t+poYo/8M0HJ/lB9y5auamrJT4acsPWS+fYHAjfGfpSE7T7QWuiIKJ2EmpVa5 +hpGhzII9ahF0wtHTKkF7d7RYV1p1UUA5nu8QFTope8fyERJDZg88ICt+TpXJ7+PJ +9THcXgNI+papKy2wKHPfly6B+071BA4n0UX0tV7zqWk9axoN+nyUL97/k572kLTb +xahrBEYXphdNeqqXHa/udWpTYaKwSGYmIohTSIqBZh7Xa/rhLsx2UfgR5B0WW34E +8cTzuiZz//////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// -////////////////////////////////////////iQIcBBABCAAGBQJX+0LWAAoJ -EAJ4If97HP7GahAQAMxf3Nyab2t+xJlFR+/ZCvqMq5rM8iq67ZK5fLG000RjLiBN -5bd6BglAq03l2DuE3b9hdnosKfU3FCeysivn0af0kxjMaH+W+9JSQJ9E5EjO+RgI -JDkn3n6X/lQjVl3N7R6FeaWY6Ug9paSCtAlVlwCfg/rn2jFIiHQb++44nQFpaX4W -uNzZWoy1SOGg32e624fjsgqB0aH2cmY3oGdMFt8FGuzOfa89JGW8P7mUeZsiQQRx -R4y+L7omQ60rlveKZeEo/ZVfSZUVtzM9wplXpUMbF6/XtUC9dmsVrSZePrsAHnjj -bbk0GBKit2UswC8fKdHVz9YiWKuM4QLEWiucYLkcWcHUFyp1Tk9ZeS3R3yPASC4e -WV72IVGS0mjjolcFwatMfYghQ42+sR+G6duEcJSN7sqrdzYxRny7aYz7GFXv1GCE -iz/CzhepHDROpu9KZv6xetyP4xmaunanzzrd7kM23530jFRK53GJ/4p6XlwYA3jN -sxaGoAADOTIwqolgxtvdrNwEeX0pNpFI85BXSJrvBxKseL4o2NlxxvkyrLPIuuU6 -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 -I4Tesw== -=i53l +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 +keSPmmDrjl8cySCNsMo= +=R0uO -----END PGP PUBLIC KEY BLOCK----- EOF diff --git a/newsfragments/3542.minor b/newsfragments/3542.minor new file mode 100644 index 000000000..e69de29bb From df3ec2a1d48f124f25060f8133ac2264cac11d38 Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 30 Nov 2020 17:33:43 -0500 Subject: [PATCH 29/31] Try to trigger image building --- .circleci/config.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index afa3fafa1..a9ce0cc03 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -92,16 +92,16 @@ workflows: <<: *DOCKERHUB_CONTEXT images: - # Build the Docker images used by the ci jobs. This makes the ci jobs - # faster and takes various spurious failures out of the critical path. - triggers: - # Build once a day - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - "master" + # # Build the Docker images used by the ci jobs. This makes the ci jobs + # # faster and takes various spurious failures out of the critical path. + # triggers: + # # Build once a day + # - schedule: + # cron: "0 0 * * *" + # filters: + # branches: + # only: + # - "master" jobs: - "build-image-debian-8": From 9ea99726c7d5afbbe91e0c71b4acf6fcca31566d Mon Sep 17 00:00:00 2001 From: Sajith Sasidharan Date: Mon, 30 Nov 2020 19:18:32 -0500 Subject: [PATCH 30/31] Undo docker image building trigger --- .circleci/config.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a9ce0cc03..afa3fafa1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -92,16 +92,16 @@ workflows: <<: *DOCKERHUB_CONTEXT images: - # # Build the Docker images used by the ci jobs. This makes the ci jobs - # # faster and takes various spurious failures out of the critical path. - # triggers: - # # Build once a day - # - schedule: - # cron: "0 0 * * *" - # filters: - # branches: - # only: - # - "master" + # Build the Docker images used by the ci jobs. This makes the ci jobs + # faster and takes various spurious failures out of the critical path. + triggers: + # Build once a day + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - "master" jobs: - "build-image-debian-8": From 587222033d23f5492a80c47deeba5798b1da2955 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 1 Dec 2020 11:58:56 -0500 Subject: [PATCH 31/31] Fix bad merge. --- src/allmydata/introducer/client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/allmydata/introducer/client.py b/src/allmydata/introducer/client.py index c143cef8b..f54595221 100644 --- a/src/allmydata/introducer/client.py +++ b/src/allmydata/introducer/client.py @@ -40,6 +40,7 @@ class IntroducerClient(service.Service, Referenceable): self._my_subscriber_info = { b"version": 0, b"nickname": self._nickname, + b"app-versions": [], b"my-version": self._my_version, b"oldest-supported": self._oldest_supported, }