summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <cheimes@redhat.com>2015-07-30 15:48:40 +0200
committerMartin Basti <mbasti@redhat.com>2015-07-31 15:33:49 +0200
commit2d7565eec6dce67263d3d2b25bf098b680a51f82 (patch)
tree36ee6944040060c683879f5e60121db97a14b0a3
parentb01dc89967c73076c268e6bc3f1d604c3c04b221 (diff)
downloadfreeipa-2d7565eec6dce67263d3d2b25bf098b680a51f82.tar.gz
freeipa-2d7565eec6dce67263d3d2b25bf098b680a51f82.tar.xz
freeipa-2d7565eec6dce67263d3d2b25bf098b680a51f82.zip
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>
-rw-r--r--ipalib/plugins/vault.py59
1 files changed, 47 insertions, 12 deletions
diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index 81197f932..423df6b7c 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -19,6 +19,7 @@
import base64
import getpass
+import io
import json
import os
import sys
@@ -210,6 +211,33 @@ EXAMPLES:
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()
@@ -591,8 +619,10 @@ class vault_add(PKQuery, Local):
pass
elif password_file:
- with open(password_file, 'rb') as f:
- password = f.read().rstrip('\n').decode('utf-8')
+ password = validated_read('password-file',
+ password_file,
+ encoding='utf-8')
+ password = password.rstrip('\n')
else:
password = self.obj.get_new_password()
@@ -611,8 +641,9 @@ class vault_add(PKQuery, Local):
pass
elif public_key_file:
- with open(public_key_file, 'rb') as f:
- public_key = f.read()
+ public_key = validated_read('public-key-file',
+ public_key_file,
+ mode='rb')
# store vault public key
options['ipavaultpublickey'] = public_key
@@ -904,8 +935,7 @@ class vault_archive(PKQuery, Local):
reason=_('Input data specified multiple times'))
elif input_file:
- with open(input_file, 'rb') as f:
- data = f.read()
+ data = validated_read('in', input_file, mode='rb')
elif not data:
data = ''
@@ -937,8 +967,10 @@ class vault_archive(PKQuery, Local):
pass
elif password_file:
- with open(password_file) as f:
- password = f.read().rstrip('\n').decode('utf-8')
+ password = validated_read('password-file',
+ password_file,
+ encoding='utf-8')
+ password = password.rstrip('\n')
else:
password = self.obj.get_existing_password()
@@ -1254,8 +1286,10 @@ class vault_retrieve(PKQuery, Local):
pass
elif password_file:
- with open(password_file) as f:
- password = f.read().rstrip('\n').decode('utf-8')
+ password = validated_read('password-file',
+ password_file,
+ encoding='utf-8')
+ password = password.rstrip('\n')
else:
password = self.obj.get_existing_password()
@@ -1277,8 +1311,9 @@ class vault_retrieve(PKQuery, Local):
pass
elif private_key_file:
- with open(private_key_file, 'rb') as f:
- private_key = f.read()
+ private_key = validated_read('private-key-file',
+ private_key_file,
+ mode='rb')
else:
raise errors.ValidationError(