diff options
author | Rob Austein <sra@hactrn.net> | 2013-03-18 22:53:30 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2013-03-18 22:53:30 +0000 |
commit | be035471c504df1f80f5fb3dc5282c4859fa217f (patch) | |
tree | 6eb97e320ba9706485c356e65381aec0b265edb5 | |
parent | b8205920fb9c0864bc84e06b47e5a7a860fd2120 (diff) |
Rewrite rcynic-cron to remove horrible maze of dependencies on
external programs to chroot or setuid. Declare dependency on rpki-rp
in Ubuntu rpki-ca package.
svn path=/trunk/; revision=5171
-rw-r--r-- | buildtools/debian-skeleton/control | 2 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | rcynic/Makefile.in | 9 | ||||
-rw-r--r-- | rcynic/rcynic-cron.py | 93 |
4 files changed, 61 insertions, 47 deletions
diff --git a/buildtools/debian-skeleton/control b/buildtools/debian-skeleton/control index 11f1dbc8..1c2cbbb9 100644 --- a/buildtools/debian-skeleton/control +++ b/buildtools/debian-skeleton/control @@ -19,7 +19,7 @@ Description: rpki.net relying party tools Package: rpki-ca Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, xsltproc, python (>= 2.7), python-lxml, libxml2-utils, mysql-client, mysql-server, python-mysqldb, python-vobject, python-yaml, python-django (<< 1.5), python-django-south (>= 0.7.5), apache2, libapache2-mod-wsgi +Depends: ${shlibs:Depends}, ${misc:Depends}, rpki-rp (= ${binary:Version}), xsltproc, python (>= 2.7), python-lxml, libxml2-utils, mysql-client, mysql-server, python-mysqldb, python-vobject, python-yaml, python-django (<< 1.5), python-django-south (>= 0.7.5), apache2, libapache2-mod-wsgi Description: rpki.net certification authority tools "Certification authority" tools for issuing RPKI certificates and related objects using the rpki.net toolkit. diff --git a/configure.ac b/configure.ac index 7c0037b0..40d788c7 100644 --- a/configure.ac +++ b/configure.ac @@ -135,10 +135,6 @@ AC_PATH_PROG([SORT], [sort]) AC_PATH_PROG([RRDTOOL], [rrdtool]) AC_PATH_PROG([TRANG], [trang], [\${abs_top_srcdir}/buildtools/trang-not-found]) AC_PATH_PROG([RSYNC], [rsync]) -AC_PATH_PROG([SU], [su]) -AC_PATH_PROG([SUDO], [sudo]) -AC_PATH_PROG([CHROOT], [chroot]) -AC_PATH_PROG([CHROOTUID], [chrootuid]) # Figure out whether we need to build our own OpenSSL library or can # use the system libraries. We're looking for two recent features: diff --git a/rcynic/Makefile.in b/rcynic/Makefile.in index 7b1b7662..0a11abd5 100644 --- a/rcynic/Makefile.in +++ b/rcynic/Makefile.in @@ -19,10 +19,6 @@ SORT = @SORT@ PYTHON = @PYTHON@ RRDTOOL = @RRDTOOL@ INSTALL = @INSTALL@ -SU = @SU@ -SUDO = @SUDO@ -CHROOT = @CHROOT@ -CHROOTUID = @CHROOTUID@ abs_top_srcdir = @abs_top_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -90,15 +86,10 @@ COMPILE_PYTHON = \ COMPILE_PYTHON_CRON = \ AC_PYTHON_INTERPRETER='${PYTHON}' \ AC_RCYNIC_USER='${RCYNIC_USER}' \ - AC_RCYNIC_GROUP='${RCYNIC_GROUP}' \ AC_RCYNIC_DIR='${RCYNIC_DIR}' \ AC_bindir='${bindir}' \ AC_sysconfdir='${sysconfdir}' \ AC_RCYNIC_HTML_DIR='${RCYNIC_HTML_DIR}' \ - AC_SU='${SU}' \ - AC_SUDO='${SUDO}' \ - AC_CHROOT='${CHROOT}' \ - AC_CHROOTUID='${CHROOTUID}' \ ${PYTHON} ${abs_top_srcdir}/buildtools/make-rcynic-script.py <$? >$@; \ chmod 755 $@ diff --git a/rcynic/rcynic-cron.py b/rcynic/rcynic-cron.py index 89b48cf2..69f48ffb 100644 --- a/rcynic/rcynic-cron.py +++ b/rcynic/rcynic-cron.py @@ -27,49 +27,68 @@ PERFORMANCE OF THIS SOFTWARE. # external programs. I don't have time to write and debug that today, # but it might well be simpler and more portable. -import subprocess -import sys -import fcntl import os +import sys import pwd +import fcntl import errno +import getopt -we_are_root = os.getuid() == 0 +def usage(result): + f = sys.stderr if result else sys.stdout + f.write("Usage: %s [--chroot] [--help]\n" % sys.argv[0]) + sys.exit(result) + +def run(*cmd, **kwargs): + chroot_this = kwargs.pop("chroot_this", False) + cwd = kwargs.pop("cwd", None) + pid = os.fork() + if pid == 0: + if chroot_this: + os.chdir(ac_rcynic_dir) + elif cwd is not None: + os.chdir(cwd) + if we_are_root: + os.initgroups(pw.pw_uid, pw.pw_gid) + if chroot_this: + os.chroot(ac_rcynic_dir) + if we_are_root: + os.setgid(pw.pw_gid) + os.setuid(pw.pw_uid) + os.closerange(3, os.sysconf("SC_OPEN_MAX")) + os.execvp(cmd[0], cmd) + os._exit(1) + else: + status = os.waitpid(pid, 0)[1] + if status != 0: + sys.exit("Program %s exited with status %s" % (" ".join(cmd), status)) -beastie = sys.platform.startswith("freebsd") or sys.platform.startswith("darwin") +want_chroot = False -def bin(name, chroot = False): - return os.path.join("/bin" if chroot and we_are_root else ac_bindir, name) +opts, argv = getopt.getopt(sys.argv[1:], "h?", ["chroot", "help"]) +for o, a in opts: + if o in ("-?", "-h", "--help"): + usage(0) + elif o =="--chroot": + want_chroot = True -def etc(name, chroot = False): - return os.path.join("/etc" if chroot and we_are_root else ac_sysconfdir, name) +if argv: + usage("Unexpected arguments: %r" % (argv,)) -def rcy(name): - return os.path.join(ac_rcynic_dir, name) +we_are_root = os.getuid() == 0 -def run(*cmd, **kwargs): - chroot = kwargs.pop("chroot", False) and we_are_root - if we_are_root: - if chroot and beastie: - cmd = (ac_chroot, "-u", ac_rcynic_user, "-g", ac_rcynic_group, ac_rcynic_dir) + cmd - elif chroot and not beastie: - cmd = (ac_chrootuid, ac_rcynic_dir, ac_rcynic_user) + cmd - elif not chroot and beastie: - cmd = (ac_su, "-m", ac_rcynic_user, "-c", " ".join(cmd)) - elif not chroot and not beastie: - cmd = (ac_sudo, "-u", ac_rcynic_user) + cmd - else: - raise RuntimeError("How the frell did I get here?") - try: - subprocess.check_call(cmd, **kwargs) - except subprocess.CalledProcessError, e: - sys.exit(str(e)) +if want_chroot and not we_are_root: + usage("Only root can --chroot") + +try: + pw = pwd.getpwnam(ac_rcynic_user) +except KeyError: + sys.exit("Could not find passwd entry for user %s" % ac_rcynic_user) try: lock = os.open(os.path.join(ac_rcynic_dir, "data/lock"), os.O_RDONLY | os.O_CREAT | os.O_NONBLOCK, 0666) fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB) if we_are_root: - pw = pwd.getpwnam(ac_rcynic_user) os.fchown(lock, pw.pw_uid, pw.pw_gid) except (IOError, OSError), e: if e.errno == errno.EAGAIN: @@ -77,12 +96,20 @@ except (IOError, OSError), e: else: sys.exit("Error %r opening lock %r" % (e.strerror, os.path.join(ac_rcynic_dir, "data/lock"))) -run(bin("rcynic", chroot = True), "-c", etc("rcynic.conf", chroot = True), chroot = True) +if want_chroot: + run("/bin/rcynic", "-c", "/etc/rcynic.conf", chroot_this = True) +else: + run(os.path.join(ac_bindir, "rcynic"), "-c", os.path.join(ac_sysconfdir, "rcynic.conf")) if ac_rcynic_html_dir and os.path.exists(os.path.dirname(ac_rcynic_html_dir)): - run(bin("rcynic-html"), rcy("data/rcynic.xml"), ac_rcynic_html_dir) - -run(bin("rtr-origin"), "--cronjob", rcy("data/authenticated"), cwd = rcy("rpki-rtr")) + run(os.path.join(ac_bindir, "rcynic-html"), + os.path.join(ac_rcynic_dir, "data/rcynic.xml"), + ac_rcynic_html_dir) + +run(os.path.join(ac_bindir, "rtr-origin"), + "--cronjob", + os.path.join(ac_rcynic_dir, "data/authenticated"), + cwd = os.path.join(ac_rcynic_dir, "rpki-rtr")) try: import rpki.gui.cacheview.util |