From 618d3579afd7bfc40707304420bbbbcc7d9ef2ec Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Thu, 7 Dec 2017 07:09:58 -0800 Subject: [PATCH] Fix handling of config tri-state bool values (like acl_public) Commit bc38c2a879305ffd3cdd4f025f4161b430e79150 added the ability to set acl_public from the config file -- but it did not take into account that it is a 'tri-state' value so the string is what is written, causing it to ALWAYS be true. This results in unexpected and insecure behavior if 'acl_public = False' is used in the config file. This patch modifies the Config.update_option to check the option type AND the value if the original is None. If an option's default is None and the value is a bool (true, false, yes, no, 0, 1) then it will set it to a bool value. --- S3/Config.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/S3/Config.py b/S3/Config.py index ccec2228e..74e93ac21 100644 --- a/S3/Config.py +++ b/S3/Config.py @@ -44,6 +44,28 @@ def config_unicodise(string, encoding = "utf-8", errors = "replace"): except UnicodeDecodeError: raise UnicodeDecodeError("Conversion to unicode failed: %r" % string) +def is_true(value): + """Check to see if a string is true, yes, on, or 1 + + value may be a str, or unicode. + + Return True if it is + """ + return value.lower() in ("true", "yes", "on", "1") + +def is_false(value): + """Check to see if a string is false, no, off, or 0 + + value may be a str, or unicode. + + Return True if it is + """ + return value.lower() in ("false", "no", "off", "0") + +def is_bool(value): + """Check a string value to see if it is bool""" + return is_true(value) or is_false(value) + class Config(object): _instance = None _parsed_files = [] @@ -347,10 +369,12 @@ def update_option(self, option, value): raise ValueError("Config: value of option %s must have suffix m, k, or nothing, not '%s'" % (option, value)) ## allow yes/no, true/false, on/off and 1/0 for boolean options - elif type(getattr(Config, option)) is type(True): # bool - if str(value).lower() in ("true", "yes", "on", "1"): + ## Some options default to None, if that's the case check the value to see if it is bool + elif (type(getattr(Config, option)) is type(True) or # Config is bool + (getattr(Config, option) is None and is_bool(value))): # Config is None and value is bool + if is_true(value): value = True - elif str(value).lower() in ("false", "no", "off", "0"): + elif is_false(value): value = False else: raise ValueError("Config: value of option '%s' must be Yes or No, not '%s'" % (option, value))