From 482a7dd3f11a19d0fc6e22524736f744deb1ce88 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sat, 27 Aug 2011 12:50:48 -0700 Subject: [PATCH] Add 'tahoe debug dump-cap' support for MDMF, DIR2-CHK, DIR2-MDMF. refs #1507. This also adds tests for all those cases, and fixes an omission in uri.py that broke parsing of DIR2-MDMF-Verifier and DIR2-CHK-Verifier. --- src/allmydata/scripts/debug.py | 60 ++++++++++++-- src/allmydata/test/test_cli.py | 141 +++++++++++++++++++++++++++++++-- src/allmydata/uri.py | 4 + 3 files changed, 194 insertions(+), 11 deletions(-) diff --git a/src/allmydata/scripts/debug.py b/src/allmydata/scripts/debug.py index 786f058c..1cff7751 100644 --- a/src/allmydata/scripts/debug.py +++ b/src/allmydata/scripts/debug.py @@ -415,9 +415,9 @@ def dump_uri_instance(u, nodeid, secret, out, show_header=True): print >>out, "Literal File URI:" print >>out, " data:", quote_output(u.data) - elif isinstance(u, uri.WriteableSSKFileURI): + elif isinstance(u, uri.WriteableSSKFileURI): # SDMF if show_header: - print >>out, "SSK Writeable URI:" + print >>out, "SDMF Writeable URI:" print >>out, " writekey:", base32.b2a(u.writekey) print >>out, " readkey:", base32.b2a(u.readkey) print >>out, " storage index:", si_b2a(u.get_storage_index()) @@ -428,20 +428,54 @@ def dump_uri_instance(u, nodeid, secret, out, show_header=True): print >>out, " write_enabler:", base32.b2a(we) print >>out _dump_secrets(u.get_storage_index(), secret, nodeid, out) - elif isinstance(u, uri.ReadonlySSKFileURI): if show_header: - print >>out, "SSK Read-only URI:" + print >>out, "SDMF Read-only URI:" print >>out, " readkey:", base32.b2a(u.readkey) print >>out, " storage index:", si_b2a(u.get_storage_index()) print >>out, " fingerprint:", base32.b2a(u.fingerprint) elif isinstance(u, uri.SSKVerifierURI): if show_header: - print >>out, "SSK Verifier URI:" + print >>out, "SDMF Verifier URI:" print >>out, " storage index:", si_b2a(u.get_storage_index()) print >>out, " fingerprint:", base32.b2a(u.fingerprint) - elif isinstance(u, uri.DirectoryURI): + elif isinstance(u, uri.WriteableMDMFFileURI): # MDMF + if show_header: + print >>out, "MDMF Writeable URI:" + print >>out, " writekey:", base32.b2a(u.writekey) + print >>out, " readkey:", base32.b2a(u.readkey) + print >>out, " storage index:", si_b2a(u.get_storage_index()) + print >>out, " fingerprint:", base32.b2a(u.fingerprint) + print >>out + if nodeid: + we = hashutil.ssk_write_enabler_hash(u.writekey, nodeid) + print >>out, " write_enabler:", base32.b2a(we) + print >>out + _dump_secrets(u.get_storage_index(), secret, nodeid, out) + elif isinstance(u, uri.ReadonlyMDMFFileURI): + if show_header: + print >>out, "MDMF Read-only URI:" + print >>out, " readkey:", base32.b2a(u.readkey) + print >>out, " storage index:", si_b2a(u.get_storage_index()) + print >>out, " fingerprint:", base32.b2a(u.fingerprint) + elif isinstance(u, uri.MDMFVerifierURI): + if show_header: + print >>out, "MDMF Verifier URI:" + print >>out, " storage index:", si_b2a(u.get_storage_index()) + print >>out, " fingerprint:", base32.b2a(u.fingerprint) + + + elif isinstance(u, uri.ImmutableDirectoryURI): # CHK-based directory + if show_header: + print >>out, "CHK Directory URI:" + dump_uri_instance(u._filenode_uri, nodeid, secret, out, False) + elif isinstance(u, uri.ImmutableDirectoryURIVerifier): + if show_header: + print >>out, "CHK Directory Verifier URI:" + dump_uri_instance(u._filenode_uri, nodeid, secret, out, False) + + elif isinstance(u, uri.DirectoryURI): # SDMF-based directory if show_header: print >>out, "Directory Writeable URI:" dump_uri_instance(u._filenode_uri, nodeid, secret, out, False) @@ -453,6 +487,20 @@ def dump_uri_instance(u, nodeid, secret, out, show_header=True): if show_header: print >>out, "Directory Verifier URI:" dump_uri_instance(u._filenode_uri, nodeid, secret, out, False) + + elif isinstance(u, uri.MDMFDirectoryURI): # MDMF-based directory + if show_header: + print >>out, "Directory Writeable URI:" + dump_uri_instance(u._filenode_uri, nodeid, secret, out, False) + elif isinstance(u, uri.ReadonlyMDMFDirectoryURI): + if show_header: + print >>out, "Directory Read-only URI:" + dump_uri_instance(u._filenode_uri, nodeid, secret, out, False) + elif isinstance(u, uri.MDMFDirectoryURIVerifier): + if show_header: + print >>out, "Directory Verifier URI:" + dump_uri_instance(u._filenode_uri, nodeid, secret, out, False) + else: print >>out, "unknown cap type" diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py index 38c84ccd..39b0f6bb 100644 --- a/src/allmydata/test/test_cli.py +++ b/src/allmydata/test/test_cli.py @@ -187,13 +187,13 @@ class CLI(CLITestMixin, unittest.TestCase): self.failUnless("Literal File URI:" in output, output) self.failUnless("data: 'this is some data'" in output, output) - def test_dump_cap_ssk(self): + def test_dump_cap_sdmf(self): writekey = "\x01" * 16 fingerprint = "\xfe" * 32 u = uri.WriteableSSKFileURI(writekey, fingerprint) output = self._dump_cap(u.to_string()) - self.failUnless("SSK Writeable URI:" in output, output) + self.failUnless("SDMF Writeable URI:" in output, output) self.failUnless("writekey: aeaqcaibaeaqcaibaeaqcaibae" in output, output) self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output) self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) @@ -227,18 +227,104 @@ class CLI(CLITestMixin, unittest.TestCase): u = u.get_readonly() output = self._dump_cap(u.to_string()) - self.failUnless("SSK Read-only URI:" in output, output) + self.failUnless("SDMF Read-only URI:" in output, output) self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output) self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) u = u.get_verify_cap() output = self._dump_cap(u.to_string()) - self.failUnless("SSK Verifier URI:" in output, output) + self.failUnless("SDMF Verifier URI:" in output, output) self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) - def test_dump_cap_directory(self): + def test_dump_cap_mdmf(self): + writekey = "\x01" * 16 + fingerprint = "\xfe" * 32 + u = uri.WriteableMDMFFileURI(writekey, fingerprint) + + output = self._dump_cap(u.to_string()) + self.failUnless("MDMF Writeable URI:" in output, output) + self.failUnless("writekey: aeaqcaibaeaqcaibaeaqcaibae" in output, output) + self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output) + self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) + self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) + + output = self._dump_cap("--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa", + u.to_string()) + self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output) + + fileutil.make_dirs("cli/test_dump_cap/private") + fileutil.write("cli/test_dump_cap/private/secret", "5s33nk3qpvnj2fw3z4mnm2y6fa\n") + output = self._dump_cap("--client-dir", "cli/test_dump_cap", + u.to_string()) + self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output) + + output = self._dump_cap("--client-dir", "cli/test_dump_cap_BOGUS", + u.to_string()) + self.failIf("file renewal secret:" in output, output) + + output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j", + u.to_string()) + self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output) + self.failIf("file renewal secret:" in output, output) + + output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j", + "--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa", + u.to_string()) + self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output) + self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output) + self.failUnless("lease renewal secret: 7pjtaumrb7znzkkbvekkmuwpqfjyfyamznfz4bwwvmh4nw33lorq" in output, output) + + u = u.get_readonly() + output = self._dump_cap(u.to_string()) + self.failUnless("MDMF Read-only URI:" in output, output) + self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output) + self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) + self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) + + u = u.get_verify_cap() + output = self._dump_cap(u.to_string()) + self.failUnless("MDMF Verifier URI:" in output, output) + self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) + self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) + + + def test_dump_cap_chk_directory(self): + key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + uri_extension_hash = hashutil.uri_extension_hash("stuff") + needed_shares = 25 + total_shares = 100 + size = 1234 + u1 = uri.CHKFileURI(key=key, + uri_extension_hash=uri_extension_hash, + needed_shares=needed_shares, + total_shares=total_shares, + size=size) + u = uri.ImmutableDirectoryURI(u1) + + output = self._dump_cap(u.to_string()) + self.failUnless("CHK Directory URI:" in output, output) + self.failUnless("key: aaaqeayeaudaocajbifqydiob4" in output, output) + self.failUnless("UEB hash: nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa" in output, output) + self.failUnless("size: 1234" in output, output) + self.failUnless("k/N: 25/100" in output, output) + self.failUnless("storage index: hdis5iaveku6lnlaiccydyid7q" in output, output) + + output = self._dump_cap("--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa", + u.to_string()) + self.failUnless("file renewal secret: csrvkjgomkyyyil5yo4yk5np37p6oa2ve2hg6xmk2dy7kaxsu6xq" in output, output) + + u = u.get_verify_cap() + output = self._dump_cap(u.to_string()) + self.failUnless("CHK Directory Verifier URI:" in output, output) + self.failIf("key: " in output, output) + self.failUnless("UEB hash: nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa" in output, output) + self.failUnless("size: 1234" in output, output) + self.failUnless("k/N: 25/100" in output, output) + self.failUnless("storage index: hdis5iaveku6lnlaiccydyid7q" in output, output) + + def test_dump_cap_sdmf_directory(self): writekey = "\x01" * 16 fingerprint = "\xfe" * 32 u1 = uri.WriteableSSKFileURI(writekey, fingerprint) @@ -282,6 +368,51 @@ class CLI(CLITestMixin, unittest.TestCase): self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) + def test_dump_cap_mdmf_directory(self): + writekey = "\x01" * 16 + fingerprint = "\xfe" * 32 + u1 = uri.WriteableMDMFFileURI(writekey, fingerprint) + u = uri.MDMFDirectoryURI(u1) + + output = self._dump_cap(u.to_string()) + self.failUnless("Directory Writeable URI:" in output, output) + self.failUnless("writekey: aeaqcaibaeaqcaibaeaqcaibae" in output, + output) + self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output) + self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, + output) + self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) + + output = self._dump_cap("--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa", + u.to_string()) + self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output) + + output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j", + u.to_string()) + self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output) + self.failIf("file renewal secret:" in output, output) + + output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j", + "--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa", + u.to_string()) + self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output) + self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output) + self.failUnless("lease renewal secret: 7pjtaumrb7znzkkbvekkmuwpqfjyfyamznfz4bwwvmh4nw33lorq" in output, output) + + u = u.get_readonly() + output = self._dump_cap(u.to_string()) + self.failUnless("Directory Read-only URI:" in output, output) + self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output) + self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) + self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) + + u = u.get_verify_cap() + output = self._dump_cap(u.to_string()) + self.failUnless("Directory Verifier URI:" in output, output) + self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output) + self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output) + + def _catalog_shares(self, *basedirs): o = debug.CatalogSharesOptions() o.stdout,o.stderr = StringIO(), StringIO() diff --git a/src/allmydata/uri.py b/src/allmydata/uri.py index d9d87354..50b04ca8 100644 --- a/src/allmydata/uri.py +++ b/src/allmydata/uri.py @@ -930,6 +930,8 @@ def from_string(u, deep_immutable=False, name=u""): return DirectoryURIVerifier.init_from_string(s) elif s.startswith('URI:DIR2-CHK:'): return ImmutableDirectoryURI.init_from_string(s) + elif s.startswith('URI:DIR2-CHK-Verifier:'): + return ImmutableDirectoryURIVerifier.init_from_string(s) elif s.startswith('URI:DIR2-LIT:'): return LiteralDirectoryURI.init_from_string(s) elif s.startswith('URI:DIR2-MDMF:'): @@ -940,6 +942,8 @@ def from_string(u, deep_immutable=False, name=u""): if can_be_mutable: return ReadonlyMDMFDirectoryURI.init_from_string(s) kind = "URI:DIR2-MDMF-RO readcap to a mutable directory" + elif s.startswith('URI:DIR2-MDMF-Verifier:'): + return MDMFDirectoryURIVerifier.init_from_string(s) elif s.startswith('x-tahoe-future-test-writeable:') and not can_be_writeable: # For testing how future writeable caps would behave in read-only contexts. kind = "x-tahoe-future-test-writeable: testing cap" -- 2.45.2