mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-25 14:40:16 -05:00
ipa tools: remove sensitive material from the commandline
When command line tools accept passwords, remove them from the command line so that they don't get visible in '/proc/pid/commandline'. There is no common method to access the original ARGV vector and modify it from Python. Since this mostly affects Linux systems where IPA services run, we expect use of GNU libc and thus can rely on internal glibc symbols. If they aren't available, the code will skip removing passwords. Fixes: CVE-2024-11029 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
1 parent
cf84a22228
commit
3b38efe758
12 files changed
+90
-21
No files matched your search
@@ -39,6 +39,45 @@ SERVER_NOT_CONFIGURED = 2
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def admin_cleanup_global_argv(option_parser, options, argv):
|
||||
"""Takes option parser and generated options and scrubs sensitive arguments
|
||||
from the global program arguments. Note that this only works for GNU GLIBC
|
||||
as Python has no generic way to get access to the original argv values to
|
||||
modify them in place.
|
||||
|
||||
The code assumes Python behavior, e.g. there are two additional args in the
|
||||
list (/path/to/python -I ...) than what's passed as 'argv' here.
|
||||
"""
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
try:
|
||||
_c = ctypes.CDLL(ctypes.util.find_library("c"))
|
||||
if _c._name is None:
|
||||
return
|
||||
_argv = ctypes.POINTER(ctypes.c_voidp).in_dll(_c, "_dl_argv")
|
||||
# since we run as 'python -I <executable> ...', add two args
|
||||
_argc = len(argv) + 2
|
||||
all_options = []
|
||||
if '_get_all_options' in dir(option_parser):
|
||||
# OptParse parser
|
||||
all_options = option_parser._get_all_options()
|
||||
elif '_actions' in dir(option_parser):
|
||||
# ArgParse parser
|
||||
all_options = option_parser._actions
|
||||
|
||||
for opt in all_options:
|
||||
if getattr(opt, 'sensitive', False):
|
||||
v = getattr(options, opt.dest)
|
||||
for i in range(0, _argc):
|
||||
vi = ctypes.cast(_argv[i],
|
||||
ctypes.c_char_p
|
||||
).value.decode('utf-8')
|
||||
if vi == v:
|
||||
ctypes.memset(_argv[i], ord('X'), len(v))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class ScriptError(Exception):
|
||||
"""An exception that records an error message and a return value
|
||||
"""
|
||||
@@ -148,6 +187,7 @@ class AdminTool:
|
||||
cls._option_parsers[cls] = cls.option_parser
|
||||
|
||||
options, args = cls.option_parser.parse_args(argv[1:])
|
||||
admin_cleanup_global_argv(cls.option_parser, options, argv)
|
||||
|
||||
command_class = cls.get_command_class(options, args)
|
||||
command = command_class(options, args)
|
||||
|
||||
Reference in new issue
Block a user