From 8a7c980e3765f89c4aa1c1a211fd7a9f7a1f479b Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sat, 17 Oct 2009 11:07:07 -0700 Subject: [PATCH] dirnode.py: move pack_children() out to a function, for eventual use by others --- src/allmydata/dirnode.py | 84 ++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/src/allmydata/dirnode.py b/src/allmydata/dirnode.py index 66029f26..47618411 100644 --- a/src/allmydata/dirnode.py +++ b/src/allmydata/dirnode.py @@ -128,6 +128,52 @@ class Adder: new_contents = self.node._pack_contents(children) return new_contents +def _encrypt_rwcap(filenode, rwcap): + assert isinstance(rwcap, str) + salt = hashutil.mutable_rwcap_salt_hash(rwcap) + key = hashutil.mutable_rwcap_key_hash(salt, filenode.get_writekey()) + cryptor = AES(key) + crypttext = cryptor.process(rwcap) + mac = hashutil.hmac(key, salt + crypttext) + assert len(mac) == 32 + return salt + crypttext + mac + # 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, children): + """Take a dict that maps: + children[unicode_name] = (IFileSystemNode, metadata_dict) + and pack it into a single string, for use as the contents of the backing + file. This is the same format as is returned by _unpack_contents. I also + accept an AuxValueDict, in which case I'll use the auxilliary cached data + as the pre-packed entry, which is faster than re-packing everything each + time.""" + has_aux = isinstance(children, AuxValueDict) + entries = [] + for name in sorted(children.keys()): + assert isinstance(name, unicode) + entry = None + if has_aux: + entry = children.get_aux(name) + if not entry: + (child, metadata) = children[name] + assert IFilesystemNode.providedBy(child), (name,child) + assert isinstance(metadata, dict) + rwcap = child.get_uri() # might be RO if the child is not writeable + if rwcap is None: + rwcap = "" + assert isinstance(rwcap, str), rwcap + rocap = child.get_readonly_uri() + if rocap is None: + rocap = "" + assert isinstance(rocap, str), rocap + entry = "".join([netstring(name.encode("utf-8")), + netstring(rocap), + netstring(_encrypt_rwcap(filenode, rwcap)), + netstring(simplejson.dumps(metadata))]) + entries.append(netstring(entry)) + return "".join(entries) + class DirectoryNode: implements(IDirectoryNode, ICheckable, IDeepCheckable) filenode_class = MutableFileNode @@ -161,18 +207,6 @@ class DirectoryNode: d.addCallback(self._unpack_contents) return d - def _encrypt_rwcap(self, rwcap): - assert isinstance(rwcap, str) - salt = hashutil.mutable_rwcap_salt_hash(rwcap) - key = hashutil.mutable_rwcap_key_hash(salt, self._node.get_writekey()) - cryptor = AES(key) - crypttext = cryptor.process(rwcap) - mac = hashutil.hmac(key, salt + crypttext) - assert len(mac) == 32 - return salt + crypttext + mac - # The MAC is not checked by readers in Tahoe >= 1.3.0, but we still - # produce it for the sake of older readers. - def _decrypt_rwcapdata(self, encwrcap): salt = encwrcap[:16] crypttext = encwrcap[16:-32] @@ -217,31 +251,7 @@ class DirectoryNode: def _pack_contents(self, children): # expects children in the same format as _unpack_contents - has_aux = isinstance(children, AuxValueDict) - entries = [] - for name in sorted(children.keys()): - assert isinstance(name, unicode) - entry = None - if has_aux: - entry = children.get_aux(name) - if not entry: - child, metadata = children.get(name) - assert IFilesystemNode.providedBy(child), (name,child) - assert isinstance(metadata, dict) - rwcap = child.get_uri() # might be RO if the child is not writeable - if rwcap is None: - rwcap = "" - assert isinstance(rwcap, str), rwcap - rocap = child.get_readonly_uri() - if rocap is None: - rocap = "" - assert isinstance(rocap, str), rocap - entry = "".join([netstring(name.encode("utf-8")), - netstring(rocap), - netstring(self._encrypt_rwcap(rwcap)), - netstring(simplejson.dumps(metadata))]) - entries.append(netstring(entry)) - return "".join(entries) + return pack_children(self._node, children) def is_readonly(self): return self._node.is_readonly() -- 2.45.2