Wed Jan 27 06:44:30 GMT Standard Time 2010 david-sarah@jacaranda.org * Prevent mutable objects from being retrieved from an immutable directory, and associated forward-compatibility improvements. New patches: [Prevent mutable objects from being retrieved from an immutable directory, and associated forward-compatibility improvements. david-sarah@jacaranda.org**20100127064430 Ignore-this: 5ef6a3554cf6bef0bf0712cc7d6c0252 ] { hunk ./contrib/fuse/impl_c/blackmatch.py 4 #!/usr/bin/env python #----------------------------------------------------------------------------------------------- -from allmydata.uri import CHKFileURI, DirectoryURI, LiteralFileURI +from allmydata.uri import CHKFileURI, DirectoryURI, LiteralFileURI, is_literal_file_uri from allmydata.scripts.common_http import do_http as do_http_req from allmydata.util.hashutil import tagged_hash from allmydata.util.assertutil import precondition hunk ./contrib/fuse/impl_c/blackmatch.py 338 self.fname = self.tfs.cache.tmp_file(os.urandom(20)) if self.fnode is None: log('TFF: [%s] open() for write: no file node, creating new File %s' % (self.name, self.fname, )) - self.fnode = File(0, 'URI:LIT:') + self.fnode = File(0, LiteralFileURI.BASE_STRING) self.fnode.tmp_fname = self.fname # XXX kill this self.parent.add_child(self.name, self.fnode, {}) elif hasattr(self.fnode, 'tmp_fname'): hunk ./contrib/fuse/impl_c/blackmatch.py 365 self.fname = self.fnode.tmp_fname log('TFF: reopening(%s) for reading' % self.fname) else: - if uri.startswith("URI:LIT") or not self.tfs.async: + if is_literal_file_uri(uri) or not self.tfs.async: log('TFF: synchronously fetching file from cache for reading') self.fname = self.tfs.cache.get_file(uri) else: hunk ./contrib/fuse/impl_c/blackmatch.py 1240 def get_file(self, uri): self.log('get_file(%s)' % (uri,)) - if uri.startswith("URI:LIT"): + if is_literal_file_uri(uri): return self.get_literal(uri) else: return self.get_chk(uri, async=False) hunk ./docs/frontends/webapi.txt 153 === Child Lookup === -Tahoe directories contain named children, just like directories in a regular -local filesystem. These children can be either files or subdirectories. +Tahoe directories contain named child entries, just like directories in a regular +local filesystem. These child entries, called "dirnodes", consist of a name, +metadata, a write slot, and a read slot. The write and read slots normally contain +a write-cap and read-cap referring to the same object, which can be either a file +or a subdirectory. The write slot may be empty (actually, both may be empty, +but that is unusual). If you have a Tahoe URL that refers to a directory, and want to reference a named child inside it, just append the child name to the URL. For example, if hunk ./docs/frontends/webapi.txt 397 } } } ] } + For forward-compatibility, a mutable directory can also contain caps in + a format that is unknown to the webapi server. When such caps are retrieved + from a mutable directory in a "ro_uri" field, they will be prefixed with + the string "ro.", indicating that they must not be decoded without + checking that they are read-only. The "ro." prefix must not be stripped + off without performing this check. (Future versions of the webapi server + will perform it where necessary.) + + If both the "rw_uri" and "ro_uri" fields are present in a given PROPDICT, + and the webapi server recognizes the rw_uri as a write cap, then it will + reset the ro_uri to the corresponding read cap and discard the original + contents of ro_uri (in order to ensure that the two caps correspond to the + same object and that the ro_uri is in fact read-only). However this may not + happen for caps in a format unknown to the webapi server. Therefore, when + writing a directory the webapi client should ensure that the contents + of "rw_uri" and "ro_uri" for a given PROPDICT are a consistent + (write cap, read cap) pair if possible. If the webapi client only has + one cap and does not know whether it is a write cap or read cap, then + it is acceptable to set "rw_uri" to that cap and omit "ro_uri". The + client must not put a write cap into a "ro_uri" field. + Note that the webapi-using client application must not provide the "Content-Type: multipart/form-data" header that usually accompanies HTML form submissions, since the body is not formatted this way. Doing so will hunk ./docs/frontends/webapi.txt 432 Like t=mkdir-with-children above, but the new directory will be deep-immutable. This means that the directory itself is immutable, and that - it can only contain deep-immutable objects, like immutable files, literal - files, and deep-immutable directories. A non-empty request body is - mandatory, since after the directory is created, it will not be possible to - add more children to it. + it can only contain objects that are treated as being deep-immutable, like + immutable files, literal files, and deep-immutable directories. + + For forward-compatibility, a deep-immutable directory can also contain caps + in a format that is unknown to the webapi server. When such caps are retrieved + from a deep-immutable directory in a "ro_uri" field, they will be prefixed + with the string "imm.", indicating that they must not be decoded without + checking that they are immutable. The "imm." prefix must not be stripped + off without performing this check. (Future versions of the webapi server + will perform it where necessary.) + + The cap for each child may be given either in the "rw_uri" or "ro_uri" + field of the PROPDICT (not both). If a cap is given in the "rw_uri" field, + then the webapi server will check that it is an immutable read-cap of a + *known* format, and give an error if it is not. If a cap is given in the + "ro_uri" field, then the webapi server will still check whether known + caps are immutable, but for unknown caps it will simply assume that the + cap can be stored, as described above. Note that an attacker would be + able to store any cap in an immutable directory, so this check when + creating the directory is only to help non-malicious clients to avoid + accidentally giving away more authority than intended. + + A non-empty request body is mandatory, since after the directory is created, + it will not be possible to add more children to it. POST /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir PUT /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir hunk ./docs/frontends/webapi.txt 462 Create new directories as necessary to make sure that the named target ($DIRCAP/SUBDIRS../SUBDIR) is a directory. This will create additional - intermediate directories as necessary. If the named target directory already - exists, this will make no changes to it. + intermediate mutable directories as necessary. If the named target directory + already exists, this will make no changes to it. If the final directory is created, it will be empty. hunk ./docs/frontends/webapi.txt 467 - This will return an error if a blocking file is present at any of the parent - names, preventing the server from creating the necessary parent directory. + This operation will return an error if a blocking file is present at any of + the parent names, preventing the server from creating the necessary parent + directory; or if it would require changing an immutable directory. The write-cap of the new directory will be returned as the HTTP response body. hunk ./docs/frontends/webapi.txt 476 POST /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir-with-children - Like above, but if the final directory is created, it will be populated with - initial children from the POST request body, as described above in the - /uri?t=mkdir-with-children operation. + Like /uri?t=mkdir-with-children, but the final directory is created as a + child of an existing mutable directory. This will create additional + intermediate mutable directories as necessary. If the final directory is + created, it will be populated with initial children from the POST request + body, as described above. + + This operation will return an error if a blocking file is present at any of + the parent names, preventing the server from creating the necessary parent + directory; or if it would require changing an immutable directory; or if + the immediate parent directory already has a a child named SUBDIR. POST /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir-immutable hunk ./docs/frontends/webapi.txt 489 - Like above, but the final directory will be deep-immutable, with the - children specified as a JSON dictionary in the POST request body. + Like /uri?t=mkdir-immutable, but the final directory is created as a child + of an existing mutable directory. The final directory will be deep-immutable, + and will be populated with the children specified as a JSON dictionary in + the POST request body. + + In Tahoe 1.6 this operation creates intermediate mutable directories if + necessary, but that behaviour should not be relied on; see ticket #920. + + This operation will return an error if the parent directory is immutable, + or already has a child named SUBDIR. POST /uri/$DIRCAP/[SUBDIRS../]?t=mkdir&name=NAME hunk ./docs/frontends/webapi.txt 502 - Create a new empty directory and attach it to the given existing directory. - This will create additional intermediate directories as necessary. + Create a new empty mutable directory and attach it to the given existing + directory. This will create additional intermediate directories as necessary. hunk ./docs/frontends/webapi.txt 505 - The URL of this form points to the parent of the bottom-most new directory, - whereas the previous form has a URL that points directly to the bottom-most - new directory. + This operation will return an error if a blocking file is present at any of + the parent names, preventing the server from creating the necessary parent + directory, or if it would require changing any immutable directory. + + The URL of this operation points to the parent of the bottommost new directory, + whereas the /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir operation above has a URL + that points directly to the bottommost new directory. POST /uri/$DIRCAP/[SUBDIRS../]?t=mkdir-with-children&name=NAME hunk ./docs/frontends/webapi.txt 515 - As above, but the new directory will be populated with initial children via - the POST request body, as described in /uri?t=mkdir-with-children above. + Like /uri/$DIRCAP/[SUBDIRS../]?t=mkdir&name=NAME, but the new directory will + be populated with initial children via the POST request body. This command + will create additional intermediate mutable directories as necessary. + + This operation will return an error if a blocking file is present at any of + the parent names, preventing the server from creating the necessary parent + directory; or if it would require changing an immutable directory; or if + the immediate parent directory already has a a child named NAME. + Note that the name= argument must be passed as a queryarg, because the POST request body is used for the initial children JSON. hunk ./docs/frontends/webapi.txt 529 POST /uri/$DIRCAP/[SUBDIRS../]?t=mkdir-immutable&name=NAME - As above, but the new directory will be deep-immutable, with the children - specified as a JSON dictionary in the POST request body. Again, the name= - argument must be passed as a queryarg. + Like /uri/$DIRCAP/[SUBDIRS../]?t=mkdir-with-children&name=NAME, but the + final directory will be deep-immutable. The children are specified as a + JSON dictionary in the POST request body. Again, the name= argument must be + passed as a queryarg. + + In Tahoe 1.6 this operation creates intermediate mutable directories if + necessary, but that behaviour should not be relied on; see ticket #920. + + This operation will return an error if the parent directory is immutable, + or already has a child named NAME. === Get Information About A File Or Directory (as JSON) === hunk ./docs/frontends/webapi.txt 761 "childinfo" is a dictionary that contains "rw_uri", "ro_uri", and "metadata" keys. You can take the output of "GET /uri/$DIRCAP1?t=json" and use it as the input to "POST /uri/$DIRCAP2?t=set_children" to make DIR2 - look very much like DIR1. + look very much like DIR1 (except for any existing children of DIR2 that + were not overwritten, and any existing "tahoe" metadata keys as described + below). When the set_children request contains a child name that already exists in the target directory, this command defaults to overwriting that child with hunk ./docs/frontends/webapi.txt 964 POST /uri/$DIRCAP/[SUBDIRS../]?t=upload - This uploads a file, and attaches it as a new child of the given directory. - The file must be provided as the "file" field of an HTML encoded form body, - produced in response to an HTML form like this: + This uploads a file, and attaches it as a new child of the given directory, + which must be mutable. The file must be provided as the "file" field of an + HTML-encoded form body, produced in response to an HTML form like this: