Skip to content

Commit b7ad26c

Browse files
committed
Fixes #989 - in aws_credential_file, fixes read_string only available with py3 + refactor for possible unicode issues
1 parent e364976 commit b7ad26c

File tree

1 file changed

+41
-24
lines changed

1 file changed

+41
-24
lines changed

S3/Config.py

+41-24
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@
2424
import http.client as httplib
2525
import locale
2626

27-
try:
28-
from configparser import NoOptionError, NoSectionError, MissingSectionHeaderError, ConfigParser as PyConfigParser
27+
try:
28+
from configparser import (NoOptionError, NoSectionError,
29+
MissingSectionHeaderError, ParsingError,
30+
ConfigParser as PyConfigParser)
2931
except ImportError:
3032
# Python2 fallback code
31-
from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError, ConfigParser as PyConfigParser
33+
from ConfigParser import (NoOptionError, NoSectionError,
34+
MissingSectionHeaderError, ParsingError,
35+
ConfigParser as PyConfigParser)
3236

3337
try:
3438
unicode
@@ -286,31 +290,44 @@ def role_refresh(self):
286290

287291
def aws_credential_file(self):
288292
try:
289-
aws_credential_file = os.path.expanduser('~/.aws/credentials')
290-
if 'AWS_CREDENTIAL_FILE' in os.environ and os.path.isfile(os.environ['AWS_CREDENTIAL_FILE']):
291-
aws_credential_file = config_unicodise(os.environ['AWS_CREDENTIAL_FILE'])
293+
aws_credential_file = os.path.expanduser('~/.aws/credentials')
294+
credential_file_from_env = os.environ.get('AWS_CREDENTIAL_FILE')
295+
if credential_file_from_env and \
296+
os.path.isfile(credential_file_from_env):
297+
aws_credential_file = config_unicodise(credential_file_from_env)
298+
elif not os.path.isfile(aws_credential_file):
299+
return
300+
301+
warning("Errno %d accessing credentials file %s" % (e.errno, aws_credential_file))
292302

293303
config = PyConfigParser()
294304

295305
debug("Reading AWS credentials from %s" % (aws_credential_file))
306+
with io.open(aws_credential_file, "r",
307+
encoding=getattr(self, 'encoding', 'UTF-8')) as fp:
308+
config_string = fp.read()
296309
try:
297-
config.read(aws_credential_file)
298-
except MissingSectionHeaderError:
299-
# if header is missing, this could be deprecated credentials file format
300-
# as described here: https://blog.csanchez.org/2011/05/
301-
# then do the hacky-hack and add default header
302-
# to be able to read the file with PyConfigParser()
303-
config_string = None
304-
with open(aws_credential_file, 'r') as f:
305-
config_string = '[default]\n' + f.read()
306-
config.read_string(config_string.decode('utf-8'))
307-
310+
try:
311+
# readfp is replaced by read_file in python3,
312+
# but so far readfp it is still available.
313+
config.readfp(io.StringIO(config_string))
314+
except MissingSectionHeaderError:
315+
# if header is missing, this could be deprecated credentials file format
316+
# as described here: https://blog.csanchez.org/2011/05/
317+
# then do the hacky-hack and add default header
318+
# to be able to read the file with PyConfigParser()
319+
config_string = u'[default]\n' + config_string
320+
config.readfp(io.StringIO(config_string))
321+
except ParsingError as exc:
322+
raise ValueError(
323+
"Error reading aws_credential_file "
324+
"(%s): %s" % (aws_credential_file, str(exc)))
308325

309326
profile = config_unicodise(os.environ.get('AWS_PROFILE', "default"))
310327
debug("Using AWS profile '%s'" % (profile))
311328

312329
# get_key - helper function to read the aws profile credentials
313-
# including the legacy ones as described here: https://blog.csanchez.org/2011/05/
330+
# including the legacy ones as described here: https://blog.csanchez.org/2011/05/
314331
def get_key(profile, key, legacy_key, print_warning=True):
315332
result = None
316333

@@ -325,31 +342,31 @@ def get_key(profile, key, legacy_key, print_warning=True):
325342
profile = "default"
326343
result = config.get(profile, key)
327344
warning(
328-
"Legacy configuratin key '%s' used, " % (key) +
345+
"Legacy configuratin key '%s' used, " % (key) +
329346
"please use the standardized config format as described here: " +
330347
"https://aws.amazon.com/blogs/security/a-new-and-standardized-way-to-manage-credentials-in-the-aws-sdks/"
331348
)
332349
except NoOptionError as e:
333350
pass
334351

335352
if result:
336-
debug("Found the configuration option '%s' for the AWS Profile '%s' in the credentials file %s" % (key, profile, aws_credential_file))
353+
debug("Found the configuration option '%s' for the AWS Profile '%s' in the credentials file %s" % (key, profile, aws_credential_file))
337354
return result
338355

339-
profile_access_key = get_key(profile, "aws_access_key_id", "AWSAccessKeyId")
356+
profile_access_key = get_key(profile, "aws_access_key_id", "AWSAccessKeyId")
340357
if profile_access_key:
341358
Config().update_option('access_key', config_unicodise(profile_access_key))
342359

343-
profile_secret_key = get_key(profile, "aws_secret_access_key", "AWSSecretKey")
360+
profile_secret_key = get_key(profile, "aws_secret_access_key", "AWSSecretKey")
344361
if profile_secret_key:
345362
Config().update_option('secret_key', config_unicodise(profile_secret_key))
346363

347-
profile_access_token = get_key(profile, "aws_session_token", None, False)
364+
profile_access_token = get_key(profile, "aws_session_token", None, False)
348365
if profile_access_token:
349366
Config().update_option('access_token', config_unicodise(profile_access_token))
350367

351368
except IOError as e:
352-
warning("%d accessing credentials file %s" % (e.errno, aws_credential_file))
369+
warning("Errno %d accessing credentials file %s" % (e.errno, aws_credential_file))
353370
except NoSectionError as e:
354371
warning("Couldn't find AWS Profile '%s' in the credentials file '%s'" % (profile, aws_credential_file))
355372

0 commit comments

Comments
 (0)