Sat Jul 10 22:10:59 MDT 2010 zooko@zooko.com * minor code clean-up in dirnode.py Impose micro-POLA by passing only the writekey instead of the whole node object to {{{_encrypt_rw_uri()}}}. Remove DummyImmutableFileNode in nodemaker.py, which is obviated by this. Add micro-optimization by precomputing the netstring of the empty string and branching on whether the writekey is present or not outside of {{{_encrypt_rw_uri()}}}. Add doc about writekey to docstring. New patches: [minor code clean-up in dirnode.py zooko@zooko.com**20100711041059 Ignore-this: 5301818c5a3212ea4ae7f1c7c6840765 Impose micro-POLA by passing only the writekey instead of the whole node object to {{{_encrypt_rw_uri()}}}. Remove DummyImmutableFileNode in nodemaker.py, which is obviated by this. Add micro-optimization by precomputing the netstring of the empty string and branching on whether the writekey is present or not outside of {{{_encrypt_rw_uri()}}}. Add doc about writekey to docstring. ] { hunk ./src/allmydata/dirnode.py 174 new_contents = self.node._pack_contents(children) return new_contents +def _encrypt_rw_uri(writekey, rw_uri): + precondition(isinstance(rw_uri, str), rw_uri) + precondition(isinstance(writekey, str), writekey) hunk ./src/allmydata/dirnode.py 178 -def _encrypt_rw_uri(filenode, rw_uri): - assert isinstance(rw_uri, str) - writekey = filenode.get_writekey() - if not writekey: - return "" salt = hashutil.mutable_rwcap_salt_hash(rw_uri) key = hashutil.mutable_rwcap_key_hash(salt, writekey) cryptor = AES(key) hunk ./src/allmydata/dirnode.py 188 # The MAC is not checked by readers in Tahoe >= 1.3.0, but we still # produce it for the sake of older readers. - -def pack_children(filenode, childrenx, deep_immutable=False): +def pack_children(childrenx, writekey, deep_immutable=False): # initial_children must have metadata (i.e. {} instead of None) children = {} for (namex, (node, metadata)) in childrenx.iteritems(): hunk ./src/allmydata/dirnode.py 196 "directory creation requires metadata to be a dict, not None", metadata) children[normalize(namex)] = (node, metadata) - return _pack_normalized_children(filenode, children, deep_immutable=deep_immutable) + return _pack_normalized_children(children, writekey=writekey, deep_immutable=deep_immutable) hunk ./src/allmydata/dirnode.py 199 -def _pack_normalized_children(filenode, children, deep_immutable=False): +ZERO_LEN_NETSTR=netstring('') +def _pack_normalized_children(children, writekey, deep_immutable=False): """Take a dict that maps: children[unicode_nfc_name] = (IFileSystemNode, metadata_dict) and pack it into a single string, for use as the contents of the backing hunk ./src/allmydata/dirnode.py 209 as the pre-packed entry, which is faster than re-packing everything each time. + If writekey is provided then I will superencrypt the child's writecap with + writekey. + If deep_immutable is True, I will require that all my children are deeply immutable, and will raise a MustBeDeepImmutableError if not. """ hunk ./src/allmydata/dirnode.py 215 + precondition((writekey is None) or isinstance(writekey, str), writekey) has_aux = isinstance(children, AuxValueDict) entries = [] hunk ./src/allmydata/dirnode.py 236 if rw_uri is None: rw_uri = "" assert isinstance(rw_uri, str), rw_uri - + # should be prevented by MustBeDeepImmutableError check above assert not (rw_uri and deep_immutable) hunk ./src/allmydata/dirnode.py 244 if ro_uri is None: ro_uri = "" assert isinstance(ro_uri, str), ro_uri + if writekey is not None: + writecap = netstring(_encrypt_rw_uri(writekey, rw_uri)) + else: + writecap = ZERO_LEN_NETSTR entry = "".join([netstring(name.encode("utf-8")), netstring(strip_prefix_for_ro(ro_uri, deep_immutable)), hunk ./src/allmydata/dirnode.py 250 - netstring(_encrypt_rw_uri(filenode, rw_uri)), + writecap, netstring(simplejson.dumps(metadata))]) entries.append(netstring(entry)) return "".join(entries) hunk ./src/allmydata/dirnode.py 377 def _pack_contents(self, children): # expects children in the same format as _unpack_contents returns - return _pack_normalized_children(self._node, children) + return _pack_normalized_children(children, self._node.get_writekey()) def is_readonly(self): return self._node.is_readonly() hunk ./src/allmydata/nodemaker.py 11 from allmydata.unknown import UnknownNode from allmydata import uri -class DummyImmutableFileNode: - def get_writekey(self): - return None - class NodeMaker: implements(INodeMaker) hunk ./src/allmydata/nodemaker.py 46 # this returns synchronously. It starts with a "cap string". assert isinstance(writecap, (str, type(None))), type(writecap) assert isinstance(readcap, (str, type(None))), type(readcap) - + bigcap = writecap or readcap if not bigcap: # maybe the writecap was hidden because we're in a readonly hunk ./src/allmydata/nodemaker.py 96 def create_new_mutable_directory(self, initial_children={}): d = self.create_mutable_file(lambda n: - pack_children(n, initial_children)) + pack_children(initial_children, n.get_writekey())) d.addCallback(self._create_dirnode) return d hunk ./src/allmydata/nodemaker.py 103 def create_immutable_directory(self, children, convergence=None): if convergence is None: convergence = self.secret_holder.get_convergence_secret() - n = DummyImmutableFileNode() # writekey=None - packed = pack_children(n, children, deep_immutable=True) + packed = pack_children(children, None, deep_immutable=True) uploadable = Data(packed, convergence) d = self.uploader.upload(uploadable, history=self.history) d.addCallback(lambda results: self.create_from_cap(None, results.uri)) hunk ./src/allmydata/test/test_dirnode.py 1249 kids = self._make_kids(nm, ["imm", "lit", "write", "read", "dirwrite", "dirread"]) - packed = dirnode.pack_children(fn, kids, deep_immutable=False) + packed = dirnode.pack_children(kids, fn.get_writekey(), deep_immutable=False) self.failUnlessIn("lit", packed) kids = self._make_kids(nm, ["imm", "lit"]) hunk ./src/allmydata/test/test_dirnode.py 1253 - packed = dirnode.pack_children(fn, kids, deep_immutable=True) + packed = dirnode.pack_children(kids, fn.get_writekey(), deep_immutable=True) self.failUnlessIn("lit", packed) kids = self._make_kids(nm, ["imm", "lit", "write"]) hunk ./src/allmydata/test/test_dirnode.py 1259 self.failUnlessRaises(dirnode.MustBeDeepImmutableError, dirnode.pack_children, - fn, kids, deep_immutable=True) + kids, fn.get_writekey(), deep_immutable=True) # read-only is not enough: all children must be immutable kids = self._make_kids(nm, ["imm", "lit", "read"]) hunk ./src/allmydata/test/test_dirnode.py 1265 self.failUnlessRaises(dirnode.MustBeDeepImmutableError, dirnode.pack_children, - fn, kids, deep_immutable=True) + kids, fn.get_writekey(), deep_immutable=True) kids = self._make_kids(nm, ["imm", "lit", "dirwrite"]) self.failUnlessRaises(dirnode.MustBeDeepImmutableError, hunk ./src/allmydata/test/test_dirnode.py 1270 dirnode.pack_children, - fn, kids, deep_immutable=True) + kids, fn.get_writekey(), deep_immutable=True) kids = self._make_kids(nm, ["imm", "lit", "dirread"]) self.failUnlessRaises(dirnode.MustBeDeepImmutableError, hunk ./src/allmydata/test/test_dirnode.py 1275 dirnode.pack_children, - fn, kids, deep_immutable=True) + kids, fn.get_writekey(), deep_immutable=True) class FakeMutableFile: implements(IMutableFileNode) } Context: [upcase_since_on_welcome terrellrussell@gmail.com**20100708193903] [server_version_on_welcome_page.dpatch.txt freestorm77@gmail.com**20100605191721 Ignore-this: b450c76dc875f5ac8cca229a666cbd0a - The storage server version is 0 for all storage nodes in the Welcome Page ] [NEWS: add NEWS snippets about two recent patches zooko@zooko.com**20100708162058 Ignore-this: 6c9da6a0ad7351a960bdd60f81532899 ] [directory_html_top_banner.dpatch freestorm77@gmail.com**20100622205301 Ignore-this: 1d770d975e0c414c996564774f049bca The div tag with the link "Return to Welcome page" on the directory.xhtml page is not correct ] [tahoe_css_toolbar.dpatch freestorm77@gmail.com**20100622210046 Ignore-this: 5b3ebb2e0f52bbba718a932f80c246c0 CSS modification to be correctly diplayed with Internet Explorer 8 The links on the top of page directory.xhtml are not diplayed in the same line as display with Firefox. ] [runnin_test_tahoe_css.dpatch freestorm77@gmail.com**20100622214714 Ignore-this: e0db73d68740aad09a7b9ae60a08c05c Runnin test for changes in tahoe.css file ] [runnin_test_directory_xhtml.dpatch freestorm77@gmail.com**20100622201403 Ignore-this: f8962463fce50b9466405cb59fe11d43 Runnin test for diretory.xhtml top banner ] [stringutils.py: tolerate sys.stdout having no 'encoding' attribute. david-sarah@jacaranda.org**20100626040817 Ignore-this: f42cad81cef645ee38ac1df4660cc850 ] [quickstart.html: python 2.5 -> 2.6 as recommended version david-sarah@jacaranda.org**20100705175858 Ignore-this: bc3a14645ea1d5435002966ae903199f ] [SFTP: don't call .stopProducing on the producer registered with OverwriteableFileConsumer (which breaks with warner's new downloader). david-sarah@jacaranda.org**20100628231926 Ignore-this: 131b7a5787bc85a9a356b5740d9d996f ] [docs/how_to_make_a_tahoe-lafs_release.txt: trivial correction, install.html should now be quickstart.html. david-sarah@jacaranda.org**20100625223929 Ignore-this: 99a5459cac51bd867cc11ad06927ff30 ] [setup: in the Makefile, refuse to upload tarballs unless someone has passed the environment variable "BB_BRANCH" with value "trunk" zooko@zooko.com**20100619034928 Ignore-this: 276ddf9b6ad7ec79e27474862e0f7d6 ] [trivial: tiny update to in-line comment zooko@zooko.com**20100614045715 Ignore-this: 10851b0ed2abfed542c97749e5d280bc (I'm actually committing this patch as a test of the new eager-annotation-computation of trac-darcs.) ] [docs: about.html link to home page early on, and be decentralized storage instead of cloud storage this time around zooko@zooko.com**20100619065318 Ignore-this: dc6db03f696e5b6d2848699e754d8053 ] [docs: update about.html, especially to have a non-broken link to quickstart.html, and also to comment out the broken links to "for Paranoids" and "for Corporates" zooko@zooko.com**20100619065124 Ignore-this: e292c7f51c337a84ebfeb366fbd24d6c ] [TAG allmydata-tahoe-1.7.0 zooko@zooko.com**20100619052631 Ignore-this: d21e27afe6d85e2e3ba6a3292ba2be1 ] Patch bundle hash: 78405c9323962dcc85027948fa9d1129eb35efd4