mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
154 lines
No EOL
5.2 KiB
Python
Executable file
154 lines
No EOL
5.2 KiB
Python
Executable file
"""
|
|
<Program Name>
|
|
pushtoolslib.py
|
|
|
|
<Author>
|
|
Vladimir Diaz <vladimir.v.diaz@gmail.com>
|
|
|
|
<Started>
|
|
September 2012.
|
|
|
|
<Copyright>
|
|
See LICENSE for licensing information.
|
|
|
|
<Purpose>
|
|
Provide a central location for functions and data useful to multiple
|
|
'tuf.pushtools' modules. A 'read_config_file' function is currently
|
|
provided that returns correctly formatted configuration dictionaries
|
|
needed by the 'push.py' and 'receive.py' scripts.
|
|
|
|
"""
|
|
|
|
import ConfigParser
|
|
import os
|
|
|
|
import tuf.formats
|
|
|
|
PUSH_CONFIG = 'push.cfg'
|
|
RECEIVE_CONFIG = 'receive.cfg'
|
|
TRANSFER_MODULES = ['scp']
|
|
CONFIG_TYPES = ['push', 'receive']
|
|
|
|
|
|
def read_config_file(filename, config_type):
|
|
"""
|
|
<Purpose>
|
|
Return a dictionary where the keys are section names and the values
|
|
dictionaries of the keys/values in that section. The returned
|
|
dict should be correctly formatted, contain the required data
|
|
according to its config type, and be valid (i.e., a correctly named
|
|
file and available).
|
|
|
|
Example config:
|
|
|
|
config_dict = {'general': {'transfer_module': 'scp', ...},
|
|
'scp': {'host': 'localhost', 'user': 'McFly', ...}}
|
|
|
|
<Arguments>
|
|
filename:
|
|
The filepath to the configuration file.
|
|
|
|
config_type:
|
|
A string identifying the type of config file expected. Supported
|
|
config types: 'push' and 'receive'.
|
|
|
|
<Exceptions>
|
|
tuf.FormatError, if the arguments are improperly formatted.
|
|
|
|
tuf.Error, if there is an error processing the config contents.
|
|
|
|
<Side Effects>
|
|
The contents of 'filename' are read and stored.
|
|
|
|
<Returns>
|
|
A dictionary containing the data loaded from the configuration file.
|
|
|
|
"""
|
|
|
|
# Do the arguments have the correct format?
|
|
# Raise 'tuf.FormatError' if there is a mismatch.
|
|
tuf.formats.PATH_SCHEMA.check_match(filename)
|
|
tuf.formats.NAME_SCHEMA.check_match(config_type)
|
|
|
|
# RawConfigParser is used because unlike ConfigParser,
|
|
# it does not provide magical interpolation/expansion
|
|
# of variables (e.g., '%(option)s' would be ignored).
|
|
config = ConfigParser.RawConfigParser()
|
|
try:
|
|
config.read(filename)
|
|
except ConfigParser.MissingSectionHeaderError, error:
|
|
raise tuf.Error(error)
|
|
|
|
if config.sections() is None:
|
|
raise tuf.Error('Could not read '+repr(filename))
|
|
|
|
# Extract the relevant information from the config and build the
|
|
# 'config_dict' dictionary.
|
|
config_dict = {}
|
|
for section in config.sections():
|
|
config_dict[section] = {}
|
|
for key, value in config.items(section):
|
|
# Split comma-separated entries and store them in a list.
|
|
# 'pushroots' is the only entry that currently accepts
|
|
# multiple values.
|
|
if key in ['pushroots']:
|
|
value = value.split(',')
|
|
config_dict[section][key] = value
|
|
|
|
# Before returning a 'push' config dict, check the config is properly
|
|
# formatted, valid, and contains the required data.
|
|
if config_type == 'push':
|
|
# Ensure 'filename' is an appropriately named push config file.
|
|
if os.path.basename(filename) != PUSH_CONFIG:
|
|
message = repr(filename)+' is not a valid push config file.'+\
|
|
' The push config file should be named: '+repr(PUSH_CONFIG)
|
|
raise tuf.Error(message)
|
|
|
|
# Retrieve the transfer module from the push config. The caller
|
|
# expects a valid config dict containing the required keys/values.
|
|
try:
|
|
transfer_module = config_dict['general']['transfer_module']
|
|
except KeyError, e:
|
|
message = 'The push config file did not contain the required '+\
|
|
'"transfer_module" entry under "[general]".'
|
|
raise tuf.Error(message)
|
|
|
|
# Determine the transfer module and ensure the config file is properly
|
|
# formatted for an "scp configuration file". Raise 'tuf.FormatError'
|
|
# if there is mismatch.
|
|
if transfer_module == 'scp':
|
|
try:
|
|
tuf.formats.SCPCONFIG_SCHEMA.check_match(config_dict)
|
|
except tuf.FormatError, e:
|
|
message = repr(PUSH_CONFIG)+' rejected. '+str(e)
|
|
raise tuf.FormatError(message)
|
|
# A supported transfer module was not found. Raise 'tuf.Error'.
|
|
else:
|
|
message = 'The config file contains an invalid "transfer_module" entry '+\
|
|
'Supported transfer modules: '+repr(TRANSFER_MODULES)
|
|
raise tuf.Error(message)
|
|
|
|
# Before returning a 'receive' config dict, check the config is properly
|
|
# formatted, valid, and contains the required data.
|
|
elif config_type == 'receive':
|
|
# Ensure 'filename' is an appropriately named receive config file.
|
|
if os.path.basename(filename) != RECEIVE_CONFIG:
|
|
message = repr(filename)+' is not a valid receive config file.'+\
|
|
' The receive config file should be named: '+repr(RECEIVE_CONFIG)
|
|
raise tuf.Error(message)
|
|
|
|
# Determine if the config file is properly formatted for a "receive
|
|
# configuration file". Raise 'tuf.FormatError' if there is a
|
|
# mismatch.
|
|
try:
|
|
tuf.formats.RECEIVECONFIG_SCHEMA.check_match(config_dict)
|
|
except tuf.FormatError, e:
|
|
message = repr(RECEIVE_CONFIG)+' rejected. '+str(e)
|
|
raise tuf.FormatError(message)
|
|
|
|
# Invalid 'config_type' requested.
|
|
else:
|
|
message = 'Invalid "config_type" argument. Supported: '+repr(CONFIG_TYPES)
|
|
raise tuf.Error(message)
|
|
|
|
return config_dict |