def _log_status(self, rolename, signable, repository_name): """ Non-public function prints the number of (good/threshold) signatures of 'rolename'. """ status = sig.get_signature_status(signable, rolename, repository_name) message = repr(rolename) + ' role contains ' +\ repr(len(status['good_sigs'])) + ' / ' + repr(status['threshold']) +\ ' signatures.' logger.info(message)
def _generate_and_write_metadata(rolename, metadata_filename, write_partial, targets_directory, prefix='', repository_name='default'): """ Non-public function that can generate and write the metadata of the specified 'rolename'. It also increments version numbers if: 1. write_partial==True and the metadata is the first to be written. 2. write_partial=False (i.e., write()), the metadata was not loaded as partially written, and a write_partial is not needed. """ metadata = None # Retrieve the roleinfo of 'rolename' to extract the needed metadata # attributes, such as version number, expiration, etc. roleinfo = roledb.get_roleinfo(rolename, repository_name) metadata = generate_targets_metadata(targets_directory, roleinfo['paths'], roleinfo['version'], roleinfo['expires'], roleinfo['delegations'], False) # Prepend the prefix to the project's filepath to avoid signature errors in # upstream. for element in list(metadata['targets']): junk, relative_target = os.path.split(element) prefixed_path = os.path.join(prefix, relative_target) metadata['targets'][prefixed_path] = metadata['targets'][element] if prefix != '': del (metadata['targets'][element]) signable = repo_lib.sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename, repository_name) # Check if the version number of 'rolename' may be automatically incremented, # depending on whether if partial metadata is loaded or if the metadata is # written with write() / write_partial(). # Increment the version number if this is the first partial write. if write_partial: temp_signable = repo_lib.sign_metadata(metadata, [], metadata_filename, repository_name) temp_signable['signatures'].extend(roleinfo['signatures']) status = sig.get_signature_status(temp_signable, rolename, repository_name) if len(status['good_sigs']) == 0: metadata['version'] = metadata['version'] + 1 signable = repo_lib.sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename, repository_name) # non-partial write() else: if sig.verify(signable, rolename, repository_name): metadata['version'] = metadata['version'] + 1 signable = repo_lib.sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename, repository_name) # Write the metadata to file if contains a threshold of signatures. signable['signatures'].extend(roleinfo['signatures']) if sig.verify(signable, rolename, repository_name) or write_partial: repo_lib._remove_invalid_and_duplicate_signatures( signable, repository_name) storage_backend = sslib_storage.FilesystemBackend() filename = repo_lib.write_metadata_file(signable, metadata_filename, metadata['version'], False, storage_backend) # 'signable' contains an invalid threshold of signatures. else: message = 'Not enough signatures for ' + repr(metadata_filename) raise sslib_exceptions.Error(message, signable) return signable, filename