diff options
author | Rob Austein <sra@hactrn.net> | 2016-03-21 02:39:08 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2016-03-21 02:39:08 +0000 |
commit | 004393bdc2f3df5d85da88819bf47d72a883f7bb (patch) | |
tree | f325be9f47b29c5f134832f4933ff0066529c8de /rpki/rpkic.py | |
parent | d3cb2a1152bdb9a0cb391a388c702ff2f3be8371 (diff) |
Rework rpkic setuid handling to something a bit more robust.
svn path=/branches/tk705/; revision=6322
Diffstat (limited to 'rpki/rpkic.py')
-rw-r--r-- | rpki/rpkic.py | 98 |
1 files changed, 82 insertions, 16 deletions
diff --git a/rpki/rpkic.py b/rpki/rpkic.py index 7d63bbe7..68cac4b2 100644 --- a/rpki/rpkic.py +++ b/rpki/rpkic.py @@ -24,17 +24,11 @@ an overview of the available commands; type "help foo" for (more) detailed help on the "foo" command. """ -# NB: As of this writing, I'm trying really hard to avoid having this -# program depend on a Django settings.py file. This may prove to be a -# waste of time in the long run, but for for now, this means that one -# has to be careful about exactly how and when one imports Django -# modules, or anything that imports Django modules. Bottom line is -# that we don't import such modules until we need them. - import os -import argparse import sys +import pwd import time +import argparse import rpki.config import rpki.sundial import rpki.log @@ -51,6 +45,25 @@ from rpki.cli import Cmd, parsecmd, cmdarg module_doc = __doc__ + +class swap_uids(object): + """ + Context manager to wrap os.setreuid() calls safely. + """ + + def __init__(self): + self.uid = os.getuid() + self.euid = os.geteuid() + + def __enter__(self): + os.setreuid(self.euid, self.uid) + return self + + def __exit__(self, _type, value, traceback): + os.setreuid(self.uid, self.euid) + return False + + class main(Cmd): prompt = "rpkic> " @@ -77,6 +90,8 @@ class main(Cmd): def __init__(self): + self.drop_privs() + Cmd.__init__(self) os.environ["TZ"] = "UTC" time.tzset() @@ -114,6 +129,50 @@ class main(Cmd): else: args.func(self, args) + + def drop_privs(self): + """ + Initialize UID swapping and drop unneeded privs. + + Any error here we don't understand is dangerous and therefore fatal. + """ + + try: + + try: + os.setgid(int(os.environ["SUDO_GID"])) + except KeyError: + pass + + try: + uid = int(os.environ["SUDO_UID"]) + except KeyError: + uid = os.getuid() + + try: + os.setreuid(uid, pwd.getpwnam(rpki.autoconf.RPKI_USER).pw_uid) + except (KeyError, OSError) as e: + sys.exit("Couldn't drop privs to user {}: {!s}".format(rpki.autoconf.RPKI_USER, e)) + + except Exception as e: + sys.exit("Fatal error trying to drop privs: {!s}".format(e)) + + def read_history(self): + """ + UID-swapping wrapper for parent .read_history() method. + """ + + with swap_uids(): + Cmd.read_history(self) + + def save_history(self): + """ + UID-swapping wrapper for parent .save_history() method. + """ + + with swap_uids(): + Cmd.save_history(self) + def read_config(self): # pylint: disable=W0201,W0602,W0621 @@ -224,13 +283,15 @@ class main(Cmd): rootd_case = self.zoo.run_rootd and self.zoo.handle == self.zoo.cfg.get("handle") r = self.zoo.initialize() - r.save("%s.identity.xml" % self.zoo.handle, - None if rootd_case else sys.stdout) + with swap_uids(): + r.save("%s.identity.xml" % self.zoo.handle, + None if rootd_case else sys.stdout) if rootd_case: r = self.zoo.configure_rootd() if r is not None: - r.save("%s.%s.repository-request.xml" % (self.zoo.handle, self.zoo.handle), sys.stdout) + with swap_uids(): + r.save("%s.%s.repository-request.xml" % (self.zoo.handle, self.zoo.handle), sys.stdout) self.zoo.write_bpki_files() @@ -250,7 +311,8 @@ class main(Cmd): self.zoo.reset_identity(args.handle) r = self.zoo.initialize_resource_bpki() - r.save("%s.identity.xml" % self.zoo.handle, sys.stdout) + with swap_uids(): + r.save("%s.identity.xml" % self.zoo.handle, sys.stdout) @parsecmd(argsubparsers) @@ -304,7 +366,8 @@ class main(Cmd): """ r, child_handle = self.zoo.configure_child(args.child_xml, args.child_handle, args.valid_until) - r.save("%s.%s.parent-response.xml" % (self.zoo.handle, child_handle), sys.stdout) + with swap_uids(): + r.save("%s.%s.parent-response.xml" % (self.zoo.handle, child_handle), sys.stdout) self.zoo.synchronize_ca() @@ -350,7 +413,8 @@ class main(Cmd): """ r, parent_handle = self.zoo.configure_parent(args.parent_xml, args.parent_handle) - r.save("%s.%s.repository-request.xml" % (self.zoo.handle, parent_handle), sys.stdout) + with swap_uids(): + r.save("%s.%s.repository-request.xml" % (self.zoo.handle, parent_handle), sys.stdout) @parsecmd(argsubparsers, @@ -383,7 +447,8 @@ class main(Cmd): r = self.zoo.configure_rootd() if r is not None: - r.save("%s.%s.repository-request.xml" % (self.zoo.handle, self.zoo.handle), sys.stdout) + with swap_uids(): + r.save("%s.%s.repository-request.xml" % (self.zoo.handle, self.zoo.handle), sys.stdout) self.zoo.write_bpki_files() @@ -419,7 +484,8 @@ class main(Cmd): """ r, client_handle = self.zoo.configure_publication_client(args.client_xml, args.sia_base, args.flat) - r.save("%s.repository-response.xml" % client_handle.replace("/", "."), sys.stdout) + with swap_uids(): + r.save("%s.repository-response.xml" % client_handle.replace("/", "."), sys.stdout) try: self.zoo.synchronize_pubd() except rpki.irdb.models.Repository.DoesNotExist: |