From f2de8985e8e7e406e02f1a95db025da22c29fe7c Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Thu, 21 Dec 2017 15:54:06 -0500 Subject: [PATCH] Add option to exclude custom field when matching targetinfo Signed-off-by: Vladimir Diaz --- tuf/client/updater.py | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/tuf/client/updater.py b/tuf/client/updater.py index 22daa0e7..59b46025 100755 --- a/tuf/client/updater.py +++ b/tuf/client/updater.py @@ -118,6 +118,7 @@ import shutil import time import fnmatch +import copy import tuf import tuf.download @@ -223,7 +224,7 @@ def __init__(self, map_file): - def get_valid_targetinfo(self, target_filename): + def get_valid_targetinfo(self, target_filename, match_custom_field=True): """ Get valid targetinfo, if any, for the given 'target_filename'. The map @@ -236,6 +237,11 @@ def get_valid_targetinfo(self, target_filename): target_filename: The relative path of the target file to update. + match_custom_field: + Boolean that indicates whether the optional custom field in targetinfo + should match across the targetinfo provided by the threshold of + repositories. + tuf.exceptions.FormatError, if the argument is improperly formatted. @@ -284,7 +290,8 @@ def get_valid_targetinfo(self, target_filename): else: # Do the repositories in the mapping provide a threshold of matching # targetinfo? - valid_targetinfo = self._matching_targetinfo(target_filename, mapping) + valid_targetinfo = self._matching_targetinfo(target_filename, + mapping, match_custom_field) if valid_targetinfo: return valid_targetinfo @@ -350,7 +357,8 @@ def _verify_metadata_directories(self, repositories_directory): - def _matching_targetinfo(self, target_filename, mapping): + def _matching_targetinfo( + self, target_filename, mapping, match_custom_field=True): valid_targetinfo = {} # Retrieve the targetinfo from each repository using the underlying @@ -369,19 +377,19 @@ def _matching_targetinfo(self, target_filename, mapping): valid_targetinfo[updater] = targetinfo matching_targetinfo = {} - matches = 0 logger.debug('Verifying that a threshold of targetinfo are equal...') - for valid_updater, valid_targetinfo in six.iteritems(valid_targetinfo): - if targetinfo != valid_targetinfo: + for valid_updater, compared_targetinfo in six.iteritems(valid_targetinfo): + + if not self._targetinfo_match( + targetinfo, compared_targetinfo, match_custom_field): continue else: - matching_targetinfo[updater] = targetinfo - matches = matches + 1 + matching_targetinfo[valid_updater] = targetinfo - if not matches >= mapping['threshold']: + if not len(matching_targetinfo) >= mapping['threshold']: continue else: @@ -399,6 +407,23 @@ def _matching_targetinfo(self, target_filename, mapping): + + def _targetinfo_match(self, targetinfo1, targetinfo2, match_custom_field=True): + if match_custom_field: + return (targetinfo1 == targetinfo2) + + else: + targetinfo1_without_custom = copy.deepcopy(targetinfo1) + targetinfo2_without_custom = copy.deepcopy(targetinfo2) + targetinfo1_without_custom['fileinfo'].pop('custom', None) + targetinfo2_without_custom['fileinfo'].pop('custom', None) + + return (targetinfo1_without_custom == targetinfo2_without_custom) + + + + + def _target_matches_path_pattern(self, target_filename, path_patterns): for path_pattern in path_patterns: logger.debug('Interrogating pattern ' + repr(path_pattern) + 'for'