From 20e2c5bc19c19624fc906a06cca82b4e5ef8c5a3 Mon Sep 17 00:00:00 2001 From: Alex Dehnert Date: Sat, 15 Sep 2012 21:53:40 -0400 Subject: [PATCH] Wrappers for safely calling commands in a new PAG The usual mechanism for starting a new PAG is pagsh(1). Unfortunately, because it basically just execvp(3) /bin/sh passing the appropriate arguments, it isn't immediately obvious how to safely pass arguments that may contain shell metacharacters. By using the shell's exec and taking advantage of the fact that later arguments to /bin/sh end up in $@ we can safely avoid shell metacharacters. We wrap subprocess.check_{call,output} in pag_check_{call,output}, which perform appropriate contortions to establish the PAG before safely executing the passed commands without evaluating any metacharacters. --- __init__.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/__init__.py b/__init__.py index 62ec848..8f9356d 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +1,4 @@ +import os import subprocess import ldap import ldap.filter @@ -29,6 +30,32 @@ def UrlOrAfsValidator(value): except ValidationError: raise ValidationError('Provide a valid URL or AFS path') +def pag_check_helper(fn, args, aklog=False, ccname=None, **kwargs): + if 'executable' in kwargs: + raise ValueError('"executable" not supported with pag_check_*') + + env = None + if 'env' in kwargs: + env = kwargs['env'] + del kwargs['env'] + if ccname: + if env is not None: + env = dict(env) + else: + env = dict(os.environ) + env['KRB5CCNAME'] = ccname + + pagsh_cmd = 'exec "$@"' + if aklog: pagsh_cmd = "aklog && " + pagsh_cmd + args = ['pagsh', '-c', pagsh_cmd, 'exec', ] + args + + return fn(args, env=env, **kwargs) + +def pag_check_call(args, **kwargs): + return pag_check_helper(subprocess.check_call, args, **kwargs) +def pag_check_output(args, **kwargs): + return pag_check_helper(subprocess.check_output, args, **kwargs) + class ScriptsRemoteUserMiddleware(RemoteUserMiddleware): header = 'SSL_CLIENT_S_DN_Email' -- 2.44.0