c82ed3
From e11e73abc101361c0b66b3b958a64c9c8f6c608b Mon Sep 17 00:00:00 2001
c82ed3
From: Simo Sorce <simo@redhat.com>
c82ed3
Date: Mon, 16 Sep 2019 11:12:25 -0400
c82ed3
Subject: [PATCH 1/2] CVE-2019-14867: Make sure to have storage space for tag
c82ed3
c82ed3
ber_scanf expects a pointer to a ber_tag_t to return the tag pointed at
c82ed3
by "t", if that is not provided the pointer will be store in whatever
c82ed3
memory location is pointed by the stack at that time causeing a crash.
c82ed3
c82ed3
It's also possible for unprivileged end users to trigger parsing of the
c82ed3
krbPrincipalKey.
c82ed3
c82ed3
Fixes #8071: CVE-2019-14867
c82ed3
c82ed3
Reported by Todd Lipcon from Cloudera
c82ed3
c82ed3
Signed-off-by: Simo Sorce <simo@redhat.com>
c82ed3
Reviewed-By: Christian Heimes <cheimes@redhat.com>
c82ed3
(cherry picked from commit d2e0d94521893bc5f002a335a8c0b99601e1afd6)
c82ed3
---
c82ed3
 util/ipa_krb5.c | 2 +-
c82ed3
 1 file changed, 1 insertion(+), 1 deletion(-)
c82ed3
c82ed3
diff --git a/util/ipa_krb5.c b/util/ipa_krb5.c
c82ed3
index a27cd4a4e..c09c3daa5 100644
c82ed3
--- a/util/ipa_krb5.c
c82ed3
+++ b/util/ipa_krb5.c
c82ed3
@@ -554,7 +554,7 @@ int ber_decode_krb5_key_data(struct berval *encoded, int *m_kvno,
c82ed3
         retag = ber_peek_tag(be, &setlen);
c82ed3
         if (retag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 2)) {
c82ed3
             /* not supported yet, skip */
c82ed3
-            retag = ber_scanf(be, "t[x]}");
c82ed3
+            retag = ber_scanf(be, "t[x]}", &tag;;
c82ed3
         } else {
c82ed3
             retag = ber_scanf(be, "}");
c82ed3
         }
c82ed3
-- 
c82ed3
2.23.0
c82ed3
c82ed3
c82ed3
From 39120fa9a4a00983917659e4253446ed82839975 Mon Sep 17 00:00:00 2001
c82ed3
From: Rob Crittenden <rcritten@redhat.com>
c82ed3
Date: Tue, 2 Jul 2019 13:44:48 -0400
c82ed3
Subject: [PATCH 2/2] CVE-2019-10195: Don't log passwords embedded in commands
c82ed3
 in calls using batch
c82ed3
c82ed3
A raw batch request was fully logged which could expose parameters
c82ed3
we don't want logged, like passwords.
c82ed3
c82ed3
Override _repr_iter to use the individual commands to log the
c82ed3
values so that values are properly obscured.
c82ed3
c82ed3
In case of errors log the full value on when the server is in
c82ed3
debug mode.
c82ed3
c82ed3
Reported by Jamison Bennett from Cloudera
c82ed3
c82ed3
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
c82ed3
Reviewed-by:  Florence Blanc-Renaud <frenaud@redhat.com>
c82ed3
---
c82ed3
 ipaserver/plugins/batch.py | 96 ++++++++++++++++++++++++++++----------
c82ed3
 1 file changed, 72 insertions(+), 24 deletions(-)
c82ed3
c82ed3
diff --git a/ipaserver/plugins/batch.py b/ipaserver/plugins/batch.py
c82ed3
index c9895a8f6..b95944c54 100644
c82ed3
--- a/ipaserver/plugins/batch.py
c82ed3
+++ b/ipaserver/plugins/batch.py
c82ed3
@@ -93,35 +93,82 @@ class batch(Command):
c82ed3
         Output('results', (list, tuple), doc='')
c82ed3
     )
c82ed3
 
c82ed3
+    def _validate_request(self, request):
c82ed3
+        """
c82ed3
+        Check that an individual request in a batch is parseable and the
c82ed3
+        commands exists.
c82ed3
+        """
c82ed3
+        if 'method' not in request:
c82ed3
+            raise errors.RequirementError(name='method')
c82ed3
+        if 'params' not in request:
c82ed3
+            raise errors.RequirementError(name='params')
c82ed3
+        name = request['method']
c82ed3
+        if (name not in self.api.Command or
c82ed3
+                isinstance(self.api.Command[name], Local)):
c82ed3
+            raise errors.CommandError(name=name)
c82ed3
+
c82ed3
+        # If params are not formated as a tuple(list, dict)
c82ed3
+        # the following lines will raise an exception
c82ed3
+        # that triggers an internal server error
c82ed3
+        # Raise a ConversionError instead to report the issue
c82ed3
+        # to the client
c82ed3
+        try:
c82ed3
+            a, kw = request['params']
c82ed3
+            newkw = dict((str(k), v) for k, v in kw.items())
c82ed3
+            api.Command[name].args_options_2_params(*a, **newkw)
c82ed3
+        except (AttributeError, ValueError, TypeError):
c82ed3
+            raise errors.ConversionError(
c82ed3
+                name='params',
c82ed3
+                error=_(u'must contain a tuple (list, dict)'))
c82ed3
+        except Exception as e:
c82ed3
+            raise errors.ConversionError(
c82ed3
+                name='params',
c82ed3
+                error=str(e))
c82ed3
+
c82ed3
+    def _repr_iter(self, **params):
c82ed3
+        """
c82ed3
+        Iterate through the request and use the Command _repr_intr so
c82ed3
+        that sensitive information (passwords) is not exposed.
c82ed3
+
c82ed3
+        In case of a malformatted request redact the entire thing.
c82ed3
+        """
c82ed3
+        exceptions = False
c82ed3
+        for arg in (params.get('methods', [])):
c82ed3
+            try:
c82ed3
+                self._validate_request(arg)
c82ed3
+            except Exception:
c82ed3
+                # redact the whole request since we don't know what's in it
c82ed3
+                exceptions = True
c82ed3
+                yield u'********'
c82ed3
+                continue
c82ed3
+
c82ed3
+            name = arg['method']
c82ed3
+            a, kw = arg['params']
c82ed3
+            newkw = dict((str(k), v) for k, v in kw.items())
c82ed3
+            param = api.Command[name].args_options_2_params(
c82ed3
+                *a, **newkw)
c82ed3
+
c82ed3
+            yield '{}({})'.format(
c82ed3
+                api.Command[name].name,
c82ed3
+                ', '.join(api.Command[name]._repr_iter(**param))
c82ed3
+            )
c82ed3
+
c82ed3
+        if exceptions:
c82ed3
+            logger.debug('batch: %s',
c82ed3
+                         ', '.join(super(batch, self)._repr_iter(**params)))
c82ed3
+
c82ed3
     def execute(self, methods=None, **options):
c82ed3
         results = []
c82ed3
         for arg in (methods or []):
c82ed3
             params = dict()
c82ed3
             name = None
c82ed3
             try:
c82ed3
-                if 'method' not in arg:
c82ed3
-                    raise errors.RequirementError(name='method')
c82ed3
-                if 'params' not in arg:
c82ed3
-                    raise errors.RequirementError(name='params')
c82ed3
+                self._validate_request(arg)
c82ed3
                 name = arg['method']
c82ed3
-                if (name not in self.api.Command or
c82ed3
-                        isinstance(self.api.Command[name], Local)):
c82ed3
-                    raise errors.CommandError(name=name)
c82ed3
-
c82ed3
-                # If params are not formated as a tuple(list, dict)
c82ed3
-                # the following lines will raise an exception
c82ed3
-                # that triggers an internal server error
c82ed3
-                # Raise a ConversionError instead to report the issue
c82ed3
-                # to the client
c82ed3
-                try:
c82ed3
-                    a, kw = arg['params']
c82ed3
-                    newkw = dict((str(k), v) for k, v in kw.items())
c82ed3
-                    params = api.Command[name].args_options_2_params(
c82ed3
-                        *a, **newkw)
c82ed3
-                except (AttributeError, ValueError, TypeError):
c82ed3
-                    raise errors.ConversionError(
c82ed3
-                        name='params',
c82ed3
-                        error=_(u'must contain a tuple (list, dict)'))
c82ed3
+                a, kw = arg['params']
c82ed3
+                newkw = dict((str(k), v) for k, v in kw.items())
c82ed3
+                params = api.Command[name].args_options_2_params(
c82ed3
+                    *a, **newkw)
c82ed3
                 newkw.setdefault('version', options['version'])
c82ed3
 
c82ed3
                 result = api.Command[name](*a, **newkw)
c82ed3
@@ -133,8 +180,9 @@ class batch(Command):
c82ed3
                 )
c82ed3
                 result['error']=None
c82ed3
             except Exception as e:
c82ed3
-                if isinstance(e, errors.RequirementError) or \
c82ed3
-                    isinstance(e, errors.CommandError):
c82ed3
+                if (isinstance(e, errors.RequirementError) or
c82ed3
+                        isinstance(e, errors.CommandError) or
c82ed3
+                        isinstance(e, errors.ConversionError)):
c82ed3
                     logger.info(
c82ed3
                         '%s: batch: %s',
c82ed3
                         context.principal,  # pylint: disable=no-member
c82ed3
-- 
c82ed3
2.23.0
c82ed3