Skip to content

Commit 75ee328

Browse files
committed
Make methods adding targets consistent
Adopt the same path verification strategy in all methods of Targets class that add new target files by utilizing the _check_relpath() method. Signed-off-by: Teodora Sechkova <[email protected]>
1 parent aacb792 commit 75ee328

File tree

1 file changed

+56
-76
lines changed

1 file changed

+56
-76
lines changed

tuf/repository_tool.py

Lines changed: 56 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,22 +1896,26 @@ def add_paths(self, paths, child_rolename):
18961896
def add_target(self, filepath, custom=None):
18971897
"""
18981898
<Purpose>
1899-
Add a filepath (must be located in the repository's targets directory) to
1900-
the Targets object.
1899+
Add a filepath (must be relative to the repository's targets directory)
1900+
to the Targets object.
19011901
1902-
This method does not actually create 'filepath' on the file system.
1903-
'filepath' must already exist on the file system. If 'filepath'
1904-
has already been added, it will be replaced with any new file
1905-
or 'custom' information.
1902+
This method does not access the file system. 'filepath' must already
1903+
exist on the file system.
1904+
1905+
If 'filepath' does not exist the file will still be added to 'roleinfo'.
1906+
Only later calls to write() and writeall() will fail.
1907+
1908+
If 'filepath' has already been added, it will be replaced with any new
1909+
file or 'custom' information.
19061910
19071911
>>>
19081912
>>>
19091913
>>>
19101914
19111915
<Arguments>
19121916
filepath:
1913-
The path of the target file. It must exist in the repository's targets
1914-
directory.
1917+
The path of the target file. It must be relative to the repository's
1918+
targets directory.
19151919
19161920
custom:
19171921
An optional object providing additional information about the file.
@@ -1920,8 +1924,8 @@ def add_target(self, filepath, custom=None):
19201924
securesystemslib.exceptions.FormatError, if 'filepath' is improperly
19211925
formatted.
19221926
1923-
securesystemslib.exceptions.Error, if 'filepath' is not located in the
1924-
repository's targets directory.
1927+
tuf.exceptions.InvalidNameError, if 'filepath' is not relative (starts
1928+
with a directory separator).
19251929
19261930
<Side Effects>
19271931
Adds 'filepath' to this role's list of targets. This role's
@@ -1935,47 +1939,38 @@ def add_target(self, filepath, custom=None):
19351939
# Ensure the arguments have the appropriate number of objects and object
19361940
# types, and that all dict keys are properly named. Raise
19371941
# 'securesystemslib.exceptions.FormatError' if there is a mismatch.
1938-
securesystemslib.formats.PATH_SCHEMA.check_match(filepath)
1942+
tuf.formats.RELPATH_SCHEMA.check_match(filepath)
19391943

19401944
if custom is None:
19411945
custom = {}
1942-
19431946
else:
19441947
tuf.formats.CUSTOM_SCHEMA.check_match(custom)
19451948

1946-
filepath = os.path.join(self._targets_directory, filepath)
1947-
19481949
# Add 'filepath' (i.e., relative to the targets directory) to the role's
19491950
# list of targets. 'filepath' will not be verified as an allowed path
19501951
# according to some delegating role. Not verifying 'filepath' here allows
19511952
# freedom to add targets and parent restrictions in any order, minimize the
19521953
# number of times these checks are performed, and allow any role to
1953-
# delegate trust of packages to this Targes role.
1954-
if os.path.isfile(filepath):
1955-
1956-
# Update the role's 'tuf.roledb.py' entry and avoid duplicates. Make
1957-
# sure to exclude the path separator when calculating the length of the
1958-
# targets directory.
1959-
targets_directory_length = len(self._targets_directory) + 1
1960-
roleinfo = tuf.roledb.get_roleinfo(self._rolename, self._repository_name)
1961-
relative_path = filepath[targets_directory_length:].replace('\\', '/')
1954+
# delegate trust of packages to this Targets role.
19621955

1963-
if relative_path not in roleinfo['paths']:
1964-
logger.debug('Adding new target: ' + repr(relative_path))
1965-
roleinfo['paths'].update({relative_path: custom})
1966-
1967-
else:
1968-
logger.debug('Replacing target: ' + repr(relative_path))
1969-
roleinfo['paths'].update({relative_path: custom})
1956+
# Check if the target path is relative and normalize it. File's existence
1957+
# on the file system is not verified. If the file does not exist relative
1958+
# to the targets directory, later calls to write() will fail.
1959+
relative_path = self._check_relpath(filepath)
19701960

1961+
# Update the role's 'tuf.roledb.py' entry and avoid duplicates.
1962+
roleinfo = tuf.roledb.get_roleinfo(self._rolename, self._repository_name)
19711963

1972-
tuf.roledb.update_roleinfo(self._rolename, roleinfo,
1973-
repository_name=self._repository_name)
1964+
if relative_path not in roleinfo['paths']:
1965+
logger.debug('Adding new target: ' + repr(relative_path))
1966+
roleinfo['paths'].update({relative_path: custom})
19741967

19751968
else:
1976-
raise securesystemslib.exceptions.Error(repr(filepath) + ' is not'
1977-
' a valid file in the repository\'s targets'
1978-
' directory: ' + repr(self._targets_directory))
1969+
logger.debug('Replacing target: ' + repr(relative_path))
1970+
roleinfo['paths'].update({relative_path: custom})
1971+
1972+
tuf.roledb.update_roleinfo(self._rolename, roleinfo,
1973+
repository_name=self._repository_name)
19791974

19801975

19811976

@@ -1999,9 +1994,8 @@ def add_targets(self, list_of_targets):
19991994
securesystemslib.exceptions.FormatError, if the arguments are improperly
20001995
formatted.
20011996
2002-
securesystemslib.exceptions.Error, if any of the paths listed in
2003-
'list_of_targets' is not located in the repository's targets directory or
2004-
is invalid.
1997+
tuf.exceptions.InvalidNameError, if any target in 'list_of_targets'
1998+
is not relative (starts with a directory separator).
20051999
20062000
<Side Effects>
20072001
This Targets' roleinfo is updated with the paths in 'list_of_targets'.
@@ -2017,7 +2011,6 @@ def add_targets(self, list_of_targets):
20172011
tuf.formats.RELPATHS_SCHEMA.check_match(list_of_targets)
20182012

20192013
# Update the tuf.roledb entry.
2020-
targets_directory_length = len(self._targets_directory)
20212014
relative_list_of_targets = []
20222015

20232016
# Ensure the paths in 'list_of_targets' are valid and are located in the
@@ -2027,15 +2020,7 @@ def add_targets(self, list_of_targets):
20272020
# freedom to add targets and parent restrictions in any order, and minimize
20282021
# the number of times these checks are performed.
20292022
for target in list_of_targets:
2030-
filepath = os.path.join(self._targets_directory, target)
2031-
2032-
if os.path.isfile(filepath):
2033-
relative_list_of_targets.append(
2034-
filepath[targets_directory_length + 1:].replace('\\', '/'))
2035-
2036-
else:
2037-
raise securesystemslib.exceptions.Error(repr(filepath) + ' is not'
2038-
' a valid file.')
2023+
relative_list_of_targets.append(self._check_relpath(target))
20392024

20402025
# Update this Targets 'tuf.roledb.py' entry.
20412026
roleinfo = tuf.roledb.get_roleinfo(self._rolename, self._repository_name)
@@ -2223,12 +2208,11 @@ def delegate(self, rolename, public_keys, paths, threshold=1,
22232208
securesystemslib.exceptions.FormatError, if any of the arguments are
22242209
improperly formatted.
22252210
2226-
securesystemslib.exceptions.Error, if the delegated role already exists
2227-
or if any target in 'list_of_targets' is an invalid path (i.e., not
2228-
located in the repository's targets directory).
2211+
securesystemslib.exceptions.Error, if the delegated role already exists.
22292212
2230-
tuf.exceptions.InvalidNameError, if any path in 'paths' is not a
2231-
relative path (starts with a directory separator).
2213+
tuf.exceptions.InvalidNameError, if any path in 'paths' or any
2214+
target in 'list_of_targets' is not relative (starts with a directory
2215+
separator).
22322216
22332217
<Side Effects>
22342218
A new Target object is created for 'rolename' that is accessible to the
@@ -2274,16 +2258,15 @@ def delegate(self, rolename, public_keys, paths, threshold=1,
22742258
# Ensure the paths of 'list_of_targets' are located in the repository's
22752259
# targets directory.
22762260
relative_targetpaths = {}
2277-
targets_directory_length = len(self._targets_directory)
22782261

22792262
if list_of_targets:
22802263
for target in list_of_targets:
2281-
target = os.path.join(self._targets_directory, target)
2282-
if not os.path.isfile(target):
2283-
logger.warning(repr(target) + ' does not exist in the'
2284-
' repository\'s targets directory: ' + repr(self._targets_directory))
2285-
2286-
relative_targetpaths.update({target[targets_directory_length:]: {}})
2264+
# Check if the target path is relative and normalize it. File's
2265+
# existence on the file system is not verified. If the file does not
2266+
# exist relative to the targets directory, later calls to write()
2267+
# will fail.
2268+
rel_targetpath = self._check_relpath(target)
2269+
relative_targetpaths.update({rel_targetpath: {}})
22872270

22882271
# A list of relative and verified paths or glob patterns to be added to the
22892272
# child role's entry in the parent's delegations field.
@@ -2468,9 +2451,12 @@ def delegate_hashed_bins(self, list_of_targets, keys_of_hashed_bins,
24682451
formatted.
24692452
24702453
securesystemslib.exceptions.Error, if 'number_of_bins' is not a power of
2471-
2, or one of the targets in 'list_of_targets' is not located in the
2454+
2, or one of the targets in 'list_of_targets' is not relative to the
24722455
repository's targets directory.
24732456
2457+
tuf.exceptions.InvalidNameError, if any target in 'list_of_targets'
2458+
is not relative (starts with a directory separator).
2459+
24742460
<Side Effects>
24752461
Delegates multiple target roles from the current parent role.
24762462
@@ -2518,17 +2504,12 @@ def delegate_hashed_bins(self, list_of_targets, keys_of_hashed_bins,
25182504
for bin_index in six.moves.xrange(total_hash_prefixes):
25192505
target_paths_in_bin[bin_index] = []
25202506

2521-
# Assign every path to its bin. Log a warning if the target path does not
2522-
# exist in the repository's targets directory.
2507+
# Assign every path to its bin.
25232508
for target_path in list_of_targets:
2524-
if not os.path.isfile(os.path.join(self._targets_directory, target_path)):
2525-
logger.warning('A path in "list of'
2526-
' targets" is not located in the repository\'s targets'
2527-
' directory: ' + repr(target_path))
2528-
2529-
else:
2530-
logger.debug(repr(target_path) + ' is located in the repository\'s'
2531-
' targets directory.')
2509+
# Check if the target path is relative and normalize it. File's existence
2510+
# on the file system is not verified. If the file does not exist relative
2511+
# to the targets directory, later calls to write() will fail.
2512+
target_path = self._check_relpath(target_path)
25322513

25332514
# Determine the hash prefix of 'target_path' by computing the digest of
25342515
# its path relative to the targets directory. Example:
@@ -2736,11 +2717,10 @@ def _locate_and_update_target_in_bin(self, target_filepath, method_name):
27362717
raise securesystemslib.exceptions.Error(self.rolename + ' has not'
27372718
' delegated to hashed bins.')
27382719

2739-
# Log warning if 'target_filepath' is not located in the repository's
2740-
# targets directory.
2741-
if not os.path.isfile(os.path.join(self._targets_directory, target_filepath)):
2742-
logger.warning(repr(target_filepath) + ' is not located in the'
2743-
' repository\'s targets directory: ' + repr(self._targets_directory))
2720+
# Check if the target path is relative and normalize it. File's existence
2721+
# on the file system is not verified. If the file does not exist relative
2722+
# to the targets directory, later calls to write() will fail.
2723+
target_filepath = self._check_relpath(target_filepath)
27442724

27452725
# Determine the hash prefix of 'target_path' by computing the digest of
27462726
# its path relative to the targets directory. Example:

0 commit comments

Comments
 (0)