Validate vault's file parameters

A user can pass file names for password, public and private key files to
the vault plugin. The plugin attempts to read from these files. If any
file can't be, an internal error was raised. The patch wraps all reads
and turns any IOError and UnicodeError into a ValidationError.

https://fedorahosted.org/freeipa/ticket/5155

Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
Christian Heimes
2015-07-30 15:48:40 +02:00
committed by Martin Basti
parent b8c46f2a32
commit 8e28ddd8fa

View File

@@ -19,6 +19,7 @@
import base64 import base64
import getpass import getpass
import io
import json import json
import os import os
import sys import sys
@@ -210,6 +211,33 @@ EXAMPLES:
ipa vault-remove-member <name> --users <usernames> ipa vault-remove-member <name> --users <usernames>
""") """)
def validated_read(argname, filename, mode='r', encoding=None):
"""Read file and catch errors
IOError and UnicodeError (for text files) are turned into a
ValidationError
"""
try:
with io.open(filename, mode=mode, encoding=encoding) as f:
data = f.read()
except IOError as exc:
raise errors.ValidationError(
name=argname,
error=_("Cannot read file '%(filename)s': %(exc)s") % {
'filename': filename, 'exc': exc[1]
}
)
except UnicodeError as exc:
raise errors.ValidationError(
name=argname,
error=_("Cannot decode file '%(filename)s': %(exc)s") % {
'filename': filename, 'exc': exc
}
)
return data
register = Registry() register = Registry()
@@ -591,8 +619,10 @@ class vault_add(PKQuery, Local):
pass pass
elif password_file: elif password_file:
with open(password_file, 'rb') as f: password = validated_read('password-file',
password = f.read().rstrip('\n').decode('utf-8') password_file,
encoding='utf-8')
password = password.rstrip('\n')
else: else:
password = self.obj.get_new_password() password = self.obj.get_new_password()
@@ -611,8 +641,9 @@ class vault_add(PKQuery, Local):
pass pass
elif public_key_file: elif public_key_file:
with open(public_key_file, 'rb') as f: public_key = validated_read('public-key-file',
public_key = f.read() public_key_file,
mode='rb')
# store vault public key # store vault public key
options['ipavaultpublickey'] = public_key options['ipavaultpublickey'] = public_key
@@ -904,8 +935,7 @@ class vault_archive(PKQuery, Local):
reason=_('Input data specified multiple times')) reason=_('Input data specified multiple times'))
elif input_file: elif input_file:
with open(input_file, 'rb') as f: data = validated_read('in', input_file, mode='rb')
data = f.read()
elif not data: elif not data:
data = '' data = ''
@@ -937,8 +967,10 @@ class vault_archive(PKQuery, Local):
pass pass
elif password_file: elif password_file:
with open(password_file) as f: password = validated_read('password-file',
password = f.read().rstrip('\n').decode('utf-8') password_file,
encoding='utf-8')
password = password.rstrip('\n')
else: else:
password = self.obj.get_existing_password() password = self.obj.get_existing_password()
@@ -1254,8 +1286,10 @@ class vault_retrieve(PKQuery, Local):
pass pass
elif password_file: elif password_file:
with open(password_file) as f: password = validated_read('password-file',
password = f.read().rstrip('\n').decode('utf-8') password_file,
encoding='utf-8')
password = password.rstrip('\n')
else: else:
password = self.obj.get_existing_password() password = self.obj.get_existing_password()
@@ -1277,8 +1311,9 @@ class vault_retrieve(PKQuery, Local):
pass pass
elif private_key_file: elif private_key_file:
with open(private_key_file, 'rb') as f: private_key = validated_read('private-key-file',
private_key = f.read() private_key_file,
mode='rb')
else: else:
raise errors.ValidationError( raise errors.ValidationError(