diff options
Diffstat (limited to 'rp')
-rw-r--r-- | rp/Makefile.in | 2 | ||||
-rw-r--r-- | rp/config/Makefile.in | 88 | ||||
-rwxr-xr-x | rp/config/rpki-confgen | 282 | ||||
-rw-r--r-- | rp/config/rpki-confgen.xml | 1111 | ||||
-rwxr-xr-x | rp/config/rpki-manage | 15 | ||||
-rwxr-xr-x | rp/config/rpki-sql-backup | 53 | ||||
-rwxr-xr-x | rp/config/rpki-sql-setup | 348 | ||||
-rw-r--r-- | rp/rcynic/Makefile.in | 14 | ||||
-rwxr-xr-x | rp/rcynic/rcynic-cron | 4 | ||||
-rw-r--r-- | rp/rcynic/rules.darwin.mk | 78 | ||||
-rw-r--r-- | rp/rcynic/rules.freebsd.mk | 43 | ||||
-rw-r--r-- | rp/rcynic/rules.linux.mk | 51 | ||||
-rw-r--r-- | rp/rpki-rtr/rules.freebsd.mk | 4 | ||||
-rw-r--r-- | rp/rpki-rtr/rules.linux.mk | 2 |
14 files changed, 1954 insertions, 141 deletions
diff --git a/rp/Makefile.in b/rp/Makefile.in index 2c770a46..d22ddbcb 100644 --- a/rp/Makefile.in +++ b/rp/Makefile.in @@ -1,6 +1,6 @@ # $Id$ -SUBDIRS = rcynic rpki-rtr utils +SUBDIRS = config rcynic rpki-rtr utils all clean test distclean install deinstall uninstall:: @for i in ${SUBDIRS}; do echo "Making $@ in $$i"; (cd $$i && ${MAKE} $@); done diff --git a/rp/config/Makefile.in b/rp/config/Makefile.in new file mode 100644 index 00000000..40d0a882 --- /dev/null +++ b/rp/config/Makefile.in @@ -0,0 +1,88 @@ +# $Id$ + +PYTHON = @PYTHON@ + +INSTALL = @INSTALL@ -m 555 + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localstatedir = @localstatedir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +sysconfdir = @sysconfdir@ + +abs_builddir = @abs_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +abs_top_builddir= @abs_top_builddir@ +srcdir = @srcdir@ + +CFG_INSTALL_TARGETS = @CFG_INSTALL_TARGETS@ + +all:: rpki.rp.xml rpki.rp.sample.conf + +clean:: + cd tests; $(MAKE) $@ + +install:: ${CFG_INSTALL_TARGETS} + +install-always:: all + @echo + @echo "== Default configuration file location is ${sysconfdir}/rpki.conf ==" + @echo + ${INSTALL} -d ${DESTDIR}${sysconfdir}/rpki + ${INSTALL} rpki.rp.xml rpki.rp.sample.conf ${DESTDIR}${sysconfdir}/rpki + +test uninstall deinstall:: + @true + +distclean:: clean + rm -f Makefile + +rpki.rp.xml: ${abs_top_srcdir}/rpki/autoconf.py rpki-confgen rpki-confgen.xml + ${PYTHON} rpki-confgen \ + --read-xml rpki-confgen.xml \ + --autoconf \ + --set myrpki::handle=`hostname -f | sed 's/[.]/_/g'` \ + --set myrpki::rpkid_server_host=`hostname -f` \ + --set myrpki::pubd_server_host=`hostname -f` \ + --pwgen myrpki::shared_sql_password \ + --pwgen web_portal::secret-key \ + --set myrpki::run_rpkid=no \ + --set myrpki::run_pubd=no \ + --write-xml $@ + +rpki.rp.sample.conf: rpki.rp.xml + ${PYTHON} rpki-confgen \ + --read-xml rpki.rp.xml \ + --write-conf $@ + +clean:: + rm -f rpki.rp.xml rpki.rp.sample.conf + +install-postconf: \ + install-user install-conf install-sql install-django + +# This should create user "rpki" and group "rpki", but rcynic already +# does that...but we probably need to do it here instead, bother. + +install-user: + @true + +install-conf: + test -f ${DESTDIR}${sysconfdir}/rpki.conf ||\ + cp -p ${DESTDIR}${sysconfdir}/rpki/rpki.rp.sample.conf ${DESTDIR}${sysconfdir}/rpki.conf + +#uninstall deinstall:: +# rm -f ${DESTDIR}${sysconfdir}/rpki/rpki.rp.xml ${DESTDIR}${sysconfdir}/rpki/rpki.rp.sample.conf + +install-sql: + ${sbindir}/rpki-sql-setup create + +install-django: + ${sbindir}/rpki-manage syncdb --noinput + ${sbindir}/rpki-manage migrate app diff --git a/rp/config/rpki-confgen b/rp/config/rpki-confgen new file mode 100755 index 00000000..e6780446 --- /dev/null +++ b/rp/config/rpki-confgen @@ -0,0 +1,282 @@ +#!/usr/bin/env python + +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# Portions copyright (C) 2013 Internet Systems Consortium ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notices and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL AND ISC DISCLAIM ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL OR +# ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +import os +import sys +import argparse +import base64 +import textwrap + +from lxml.etree import Element, SubElement, ElementTree, Comment + +space4 = " " * 4 +space6 = " " * 6 +space8 = " " * 8 +star78 = "*" * 78 + +wiki_wrapper = textwrap.TextWrapper() +conf_wrapper = textwrap.TextWrapper(initial_indent = "# ", subsequent_indent = "# ") +xml6_wrapper = textwrap.TextWrapper(initial_indent = space6, subsequent_indent = space6) +xml8_wrapper = textwrap.TextWrapper(initial_indent = space8, subsequent_indent = space8) + +class Option(object): + + def __init__(self, name, value, doc): + self.name = name + self.value = value + self.doc = doc + + @property + def width(self): + return len(self.name) + + def to_xml(self): + x = Element("option", name = self.name) + if self.value is not None: + x.set("value", self.value) + for d in self.doc: + SubElement(x, "doc").text = "\n" + xml8_wrapper.fill(d) + "\n" + space6 + return x + + def to_wiki(self, f): + f.write("\n== {0.name} == #{0.name}\n".format(self)) + for d in self.doc: + f.write("\n{0}\n".format(wiki_wrapper.fill(d))) + if self.value is None: + f.write("\n{0}\n".format(wiki_wrapper.fill("No default value."))) + else: + f.write("\n{{{{{{\n#!ini\n{0.name} = {0.value}\n}}}}}}\n".format(self)) + + def to_conf(self, f, width): + for i, d in enumerate(self.doc): + f.write("{}\n{}\n".format("" if i == 0 else "#", + conf_wrapper.fill(d))) + if self.value is None: + f.write("\n#{1.name:{0}} = ???\n".format(width - 1, self)) + else: + f.write("\n{1.name:{0}} = {1.value}\n".format(width, self)) + +class Section(object): + + def __init__(self, name): + self.name = name + self.doc = [] + self.options = [] + + @property + def width(self): + return max(o.width for o in self.options) + + @classmethod + def from_xml(cls, elt): + self = cls(name = elt.get("name")) + for x in elt.iterchildren("doc"): + self.doc.append(" ".join(x.text.split())) + for x in elt.iterchildren("option"): + self.options.append(Option(name = x.get("name"), value = x.get("value"), + doc = [" ".join(d.text.split()) + for d in x.iterchildren("doc")])) + return self + + def to_xml(self): + x = Element("section", name = self.name) + for d in self.doc: + SubElement(x, "doc").text = "\n" + xml6_wrapper.fill(d) + "\n" + space4 + x.extend(o.to_xml() for o in self.options) + return x + + def to_wiki(self, f): + f.write("\n= [{0}] section = #{0}\n".format(self.name)) + for d in self.doc: + f.write("\n{0}\n".format(wiki_wrapper.fill(d))) + for o in self.options: + o.to_wiki(f) + + def to_conf(self, f, width): + f.write("\n" + "#" * 78 + "\n\n[" + self.name + "]\n") + if self.doc: + f.write("\n##") + for i, d in enumerate(self.doc): + f.write("{}\n{}\n".format("" if i == 0 else "#", + conf_wrapper.fill(d))) + f.write("##\n") + for o in self.options: + o.to_conf(f, width) + +def wiki_header(f, ident, toc): + f.write(textwrap.dedent('''\ + {{{{{{ + #!comment + + {star78} + THIS PAGE WAS GENERATED AUTOMATICALLY, DO NOT EDIT. + + Generated from {ident} + by $Id$ + {star78} + + }}}}}} + '''.format(star78 = star78, + ident = ident))) + if toc is not None: + f.write("[[TracNav({})]]\n".format(toc)) + f.write("[[PageOutline]]\n") + +def conf_header(f, ident): + f.write(textproc.dedent('''\ + # Automatically generated. Edit as needed, but be careful of overwriting. + # + # Generated from {ident} + # by $Id$ + + '''.format(ident = ident))) + + +# http://stackoverflow.com/questions/9027028/argparse-argument-order + +class CustomAction(argparse.Action): + + def __call__(self, parser, namespace, values, option_string = None): + if not "ordered_args" in namespace: + namespace.ordered_args = [] + namespace.ordered_args.append((self.dest, values)) + +class CustomFlagAction(CustomAction): + + def __init__(self, option_strings, dest, default = None, + required = False, help = None): # pylint: disable=W0622 + super(CustomFlagAction, self).__init__( + option_strings = option_strings, + dest = dest, + nargs = 0, + const = None, + default = default, + required = required, + help = help) + + +class main(object): + + def __init__(self): + self.sections = [] + self.section_map = None + self.option_map = None + self.ident = None + self.toc = None + + parser = argparse.ArgumentParser(description = __doc__) + parser.add_argument("--read-xml", type = argparse.FileType("r"), metavar = "FILE", action = CustomAction, help = "XML input file defining sections and options", required = True) + parser.add_argument("--write-xml", type = argparse.FileType("w"), metavar = "FILE", action = CustomAction, help = "XML output file to snapshot configuration") + parser.add_argument("--write-conf", type = argparse.FileType("w"), metavar = "FILE", action = CustomAction, help = "rpki.conf configuration file to write") + parser.add_argument("--write-wiki", type = argparse.FileType("w"), metavar = "FILE", action = CustomAction, help = "TracWiki file to write (monolithic)") + parser.add_argument("--write-wiki-pages", metavar = "PATTERN", action = CustomAction, help = "TracWiki filenames (pattern) to write (one section per page)") + parser.add_argument("--set", metavar = "VARVAL", action = CustomAction, help = "variable setting in form \"VAR=VAL\"") + parser.add_argument("--pwgen", metavar = "VAR", action = CustomAction, help = "set variable to generated password") + parser.add_argument("--toc", metavar = "TOCVAL", action = CustomAction, help = "set TOC value to use with TracNav plugin") + parser.add_argument("--autoconf", action = CustomFlagAction, help = "configure [autoconf] section") + args = parser.parse_args() + + for cmd, arg in args.ordered_args: + getattr(self, "do_" + cmd)(arg) + + def do_read_xml(self, arg): + self.option_map = None + root = ElementTree(file = arg).getroot() + self.ident = root.get("ident") + self.sections.extend(Section.from_xml(x) for x in root) + self.option_map = {} + self.section_map = {} + for section in self.sections: + if section.name in self.section_map: + sys.exit("Duplicate section {}".format(section.name)) + self.section_map[section.name] = section + for option in section.options: + name = (section.name, option.name) + if name in self.option_map: + sys.exit("Duplicate option {}::{}".format(*name)) + self.option_map[name] = option + + def do_set(self, arg): + try: + name, value = arg.split("=", 1) + section, option = name.split("::") + except ValueError: + sys.exit("Couldn't parse --set specification \"{}\"".format(arg)) + name = (section, option) + if name not in self.option_map: + sys.exit("Couldn't find option {}::{}".format(*name)) + self.option_map[name].value = value + + def do_pwgen(self, arg): + try: + section, option = arg.split("::") + except ValueError: + sys.exit("Couldn't parse --pwgen specification \"{}\"".format(arg)) + name = (section, option) + if name not in self.option_map: + sys.exit("Couldn't find option {}::{}".format(name)) + self.option_map[name].value = base64.urlsafe_b64encode(os.urandom(66)) + + def do_autoconf(self, ignored): + try: + import rpki.autoconf + for option in self.section_map["autoconf"].options: + try: + option.value = getattr(rpki.autoconf, option.name) + except AttributeError: + pass + except ImportError: + sys.exit("rpki.autoconf module is not available") + except KeyError: + sys.exit("Couldn't find autoconf section") + + def do_write_xml(self, arg): + x = Element("configuration", ident = self.ident) + x.append(Comment(" Machine-editable configuration snapshot, generated automatically, do not touch ")) + x.extend(s.to_xml() for s in self.sections) + ElementTree(x).write(arg, pretty_print = True, encoding = "us-ascii") + + def do_write_wiki(self, arg): + for i, section in enumerate(self.sections): + if i == 0: + wiki_header(arg, self.ident, self.toc) + else: + arg.write("\f\n") + section.to_wiki(arg) + + def do_write_wiki_pages(self, arg): + for section in self.sections: + with open(arg % section.name, "w") as f: + wiki_header(f, self.ident, self.toc) + section.to_wiki(f) + + def do_write_conf(self, arg): + with open(arg, "w") as f: + conf_header(f, self.ident) + width = max(s.width for s in self.sections) + for section in self.sections: + section.to_conf(f, width) + + def do_toc(self, arg): + self.toc = arg + + +if __name__ == "__main__": + main() diff --git a/rp/config/rpki-confgen.xml b/rp/config/rpki-confgen.xml new file mode 100644 index 00000000..1b86a140 --- /dev/null +++ b/rp/config/rpki-confgen.xml @@ -0,0 +1,1111 @@ +<!-- -*- SGML -*- + $Id$ + + Documented option definitions for rpki-confgen to use in generating + rpki.conf and TracWiki documentation. + + Copyright (C) 2009-2013 Internet Systems Consortium ("ISC") + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. +--> + +<configuration ident = "$Id$"> + + <section name = "myrpki"> + + <doc> + The "`[myrpki]`" section contains all the parameters that you + really need to configure. The name "`myrpki`" is historical and + may change in the future. + </doc> + + <option name = "handle"> + <doc> + Every resource-holding or server-operating entity needs a + "handle", which is just an identifier by which the entity + calls itself. Handles do not need to be globally unique, but + should be chosen with an eye towards debugging operational + problems: it's best if you use a handle that your parents and + children will recognize as being you. + </doc> + <doc> + The "`handle`" option in the "`[myrpki]`" section specifies the + default handle for this installation. Previous versions of + the CA tools required a separate configuration file, each with + its own handle setting, for each hosted entity. The current + code allows the current handle to be selected at runtime in + both the GUI and command line user interface tools, so the + handle setting here is just the default when you don't set one + explictly. In the long run, this option may go away entirely, + but for now you need to set this. + </doc> + <doc> + Syntax is an identifier (ASCII letters, digits, hyphen, + underscore -- no whitespace, non-ASCII characters, or other + punctuation). + </doc> + </option> + + <option name = "bpki_servers_directory" + value = "${autoconf::datarootdir}/rpki"> + <doc> + Directory for BPKI files generated by rpkic and used by rpkid + and pubd. You will not normally need to change this. + </doc> + </option> + + <option name = "run_rpkid" + value = "yes"> + <doc> + Whether you want to run your own copy of rpkid (and irdbd). + Leave this alone unless you're doing something unusual like + running a pubd-only installation. + </doc> + </option> + + <option name = "rpkid_server_host"> + <doc> + DNS hostname for rpkid. In most cases, this must resolve to a + publicly-reachable address to be useful, as your RPKI children + will need to contact your rpkid at this address. + </doc> + </option> + + <option name = "rpkid_server_port" + value = "4404"> + <doc> + Server port number for rpkid. This can be any legal TCP port + number that you're not using for something else. + </doc> + </option> + + <option name = "irdbd_server_host" + value = "localhost"> + <doc> + DNS hostname for irdbd, or "`localhost`". This should be + "`localhost`" unless you really know what you are doing. + </doc> + </option> + + <option name = "irdbd_server_port" + value = "4403"> + <doc> + Server port number for irdbd. This can be any legal TCP port + number that you're not using for something else. + </doc> + </option> + + <option name = "run_pubd" + value = "yes"> + <doc> + Whether you want to run your own copy of pubd. In general, + it's best to use your parent's pubd if your parent allows you + to do so, because this will reduce the overall number of + publication sites from which relying parties will need to + retrieve data. However, not all parents offer publication + service, or you may need to run pubd yourself for reliability + reasons, or because you're certifying private address space or + private Autonomous System Numbers. + </doc> + <doc> + The out of band setup protocol will attempt to negotiate + publication service for you with whatever publication service + your parent is using, if it can and if you let it. + </doc> + </option> + + <option name = "pubd_server_host"> + <doc> + DNS hostname for pubd, if you're running it. This must + resolve to a publicly reachable address to be useful. + </doc> + </option> + + <option name = "pubd_server_port" + value = "4402"> + <doc> + Server port number for pubd. This can be any legal TCP port + number that you're not using for something else. + </doc> + </option> + + <option name = "pubd_contact_info"> + <doc> + Contact information to include in offers of repository + service. This only matters when you're running pubd. This + should be a human readable string, perhaps containing an email + address or URL. + </doc> + </option> + + <option name = "run_rootd" + value = "no"> + <doc> + Whether you want to run your very own copy of rootd. Don't + enable this unless you really know what you're doing. + </doc> + </option> + + <option name = "rootd_server_host" + value = "localhost"> + <doc> + DNS hostname for rootd, if you're running it. This should be + localhost unless you really know what you are doing. + </doc> + </option> + + <option name = "rootd_server_port" + value = "4401"> + <doc> + Server port number for rootd, if you're running it. This can + be any legal TCP port number that you're not using for + something else. + </doc> + </option> + + <option name = "publication_base_directory" + value = "${autoconf::datarootdir}/rpki/publication"> + <doc> + Root of local directory tree where pubd should write out published + data. You need to configure this, and the configuration should + match up with the directory where you point rsyncd. Neither pubd + nor rsyncd much cares //where// you tell it to put this stuff, the + important thing is that the rsync URIs in generated + certificates match up with the published objects so that relying + parties can find and verify rpkid's published outputs. + </doc> + </option> + + <option name = "rrdp_publication_base_directory" + value = "${autoconf::datarootdir}/rpki/rrdp-publication"> + <doc> + Root of local directory tree where pubd should write out RRDP + files. You need to configure this, and the configuration + should match up with the directory where you point the web + server (usually Apache) that serves the RRDP files. Neither + pubd nor Apache much cares //where// you tell it to put this + stuff, the important thing is that all the URIs match up so + that relying parties can find and verify rpkid's published + outputs. + </doc> + </option> + + <option name = "publication_rsync_module" + value = "rpki"> + <doc> + rsyncd module name corresponding to publication_base_directory. + This has to match the module you configured into `rsyncd.conf`. + Leave this alone unless you have some need to change it. + </doc> + </option> + + <option name = "publication_rsync_server" + value = "${myrpki::pubd_server_host}"> + <doc> + Hostname and optional port number for rsync URIs. In most cases + this should just be the same value as pubd_server_host. + </doc> + </option> + + <option name = "publication_rrdp_base_uri" + value = "https://${myrpki::pubd_server_host}/rrdp/"> + <doc> + Base URI for RRDP notification, snapshot, and delta files. + In most cases this should be a HTTPS URL for the directory + on the publication server where the notify.xml lives. + </doc> + </option> + + <option name = "publication_rrdp_notification_uri" + value = "${myrpki::publication_rrdp_base_uri}notify.xml"> + <doc> + URI for RRDP notification file. You shouldn't need to change this. + </doc> + </option> + + <option name = "start_rpkid" + value = "${myrpki::run_rpkid}"> + <doc> + rpkid startup control. This should usually have the same value as + run_rpkid: the only case where you would want to change this is + when you are running the back-end code on a different machine from + one or more of the daemons, in which case you need finer control + over which daemons to start on which machines. In such cases, + run_rpkid controls whether the back-end code is doing things to + manage rpkid, while start_rpkid controls whether + rpki-start-servers attempts to start rpkid on this machine. + </doc> + </option> + + <option name = "start_irdbd" + value = "${myrpki::run_rpkid}"> + <doc> + irdbd startup control. This should usually have the same value as + run_rpkid: the only case where you would want to change this is + when you are running the back-end code on a different machine from + one or more of the daemons, in which case you need finer control + over which daemons to start on which machines. In such cases, + run_rpkid controls whether the back-end code is doing things to + manage rpkid, while start_irdbd controls whether + rpki-start-servers attempts to start irdbd on this machine. + </doc> + </option> + + <option name = "start_pubd" + value = "${myrpki::run_pubd}"> + <doc> + pubd startup control. This should usually have the same value as + run_pubd: the only case where you would want to change this is + when you are running the back-end code on a different machine from + one or more of the daemons, in which case you need finer control + over which daemons to start on which machines. In such cases, + run_pubd controls whether the back-end code is doing things to + manage pubd, while start_pubd controls whether + rpki-start-servers attempts to start pubd on this machine. + </doc> + </option> + + <option name = "start_rootd" + value = "${myrpki::run_rootd}"> + <doc> + rootd startup control. This should usually have the same value as + run_rootd: the only case where you would want to change this is + when you are running the back-end code on a different machine from + one or more of the daemons, in which case you need finer control + over which daemons to start on which machines. In such cases, + run_rootd controls whether the back-end code is doing things to + manage rootd, while start_rootd controls whether + rpki-start-servers attempts to start rootd on this machine. + </doc> + </option> + + <option name = "shared_sql_engine" + value = "mysql"> + <doc> + Database engine to use. Default is MySQL, because that's what + we've been using for years. Now that all runtime database + access is via Django ORM, changing to another engine supported + by Django is just a configuration issue. + </doc> + <doc> + Current supported values are "mysql" (the default), "sqlite3", + and "postgresql". In theory it should be straightforward to + add support for any SQL engine Django supports. + </doc> + </option> + + <option name = "shared_sql_username" + value = "rpki"> + <doc> + If you're comfortable with having all of the databases use the + same SQL username, set that value here. The default setting + of this variable should be fine. + </doc> + </option> + + <option name = "shared_sql_password"> + <doc> + If you're comfortable with having all of the databases use the + same SQL password, set that value here. You should use a + locally generated password either here or in the individual + settings below. The installation process generates a random + value for this option, which satisfies this requirement, so + ordinarily you should have no need to change this option. + </doc> + </option> + + <option name = "rcynic_sql_engine" + value = "${myrpki::shared_sql_engine}"> + <doc> + SQL engine to use for rcynic's database. The default setting + of this variable should be fine. + </doc> + </option> + + <option name = "rcynic_sql_database" + value = "rcynic"> + <doc> + SQL database name for rcynic's database. The default setting of + this variable should be fine. + </doc> + </option> + + <option name = "rcynic_sql_username" + value = "${myrpki::shared_sql_username}"> + <doc> + If you want to use a separate SQL username for rcynic's database, + set it here. + </doc> + </option> + + <option name = "rcynic_sql_password" + value = "${myrpki::shared_sql_password}"> + <doc> + If you want to use a separate SQL password for rcynic's database, + set it here. + </doc> + </option> + + <option name = "rpkid_sql_engine" + value = "${myrpki::shared_sql_engine}"> + <doc> + SQL engine to use for rpkid's database. The default setting + of this variable should be fine. + </doc> + </option> + + <option name = "rpkid_sql_database" + value = "rpkid"> + <doc> + SQL database name for rpkid's database. The default setting of + this variable should be fine. + </doc> + </option> + + <option name = "rpkid_sql_username" + value = "${myrpki::shared_sql_username}"> + <doc> + If you want to use a separate SQL username for rpkid's database, + set it here. + </doc> + </option> + + <option name = "rpkid_sql_password" + value = "${myrpki::shared_sql_password}"> + <doc> + If you want to use a separate SQL password for rpkid's database, + set it here. + </doc> + </option> + + <option name = "irdbd_sql_engine" + value = "${myrpki::shared_sql_engine}"> + <doc> + SQL engine to use for irdbd's database. The default setting + of this variable should be fine. + </doc> + </option> + + <option name = "irdbd_sql_database" + value = "irdbd"> + <doc> + SQL database for irdbd's database. The default setting of this + variable should be fine. + </doc> + </option> + + <option name = "irdbd_sql_username" + value = "${myrpki::shared_sql_username}"> + <doc> + If you want to use a separate SQL username for irdbd's database, + set it here. + </doc> + </option> + + <option name = "irdbd_sql_password" + value = "${myrpki::shared_sql_password}"> + <doc> + If you want to use a separate SQL password for irdbd's database, + set it here. + </doc> + </option> + + <option name = "pubd_sql_engine" + value = "${myrpki::shared_sql_engine}"> + <doc> + SQL engine to use for pubd's database. The default setting + of this variable should be fine. + </doc> + </option> + + <option name = "pubd_sql_database" + value = "pubd"> + <doc> + SQL database name for pubd's database. The default setting of + this variable should be fine. + </doc> + </option> + + <option name = "pubd_sql_username" + value = "${myrpki::shared_sql_username}"> + <doc> + If you want to use a separate SQL username for pubd's database, + set it here. + </doc> + </option> + + <option name = "pubd_sql_password" + value = "${myrpki::shared_sql_password}"> + <doc> + If you want to use a separate SQL password for pubd's database, + set it here. + </doc> + </option> + + </section> + + <section name = "rcynic"> + + <doc> + rcynicng, unlike it's predecessor, uses the same `rpki.conf` + file as all the other programs in the RPKI toolkit. Start + rcynicng with "`-c filename`" to choose a different + configuration file. All options are in the "`[rcynic]`" + section. + </doc> + + <doc> + This section isn't really fleshed out yet, and just contains the + settings needed for the new SQL code to work. This will change + as the stuff that's currently only configurable on rcynicng's + command line becomes integrated with the configuration file. + </doc> + + <option name = "sql-engine" + value = "${myrpki::rcynic_sql_engine}"> + <doc> + SQL engine for rcynic. + </doc> + </option> + + <option name = "sql-database" + value = "${myrpki::rcynic_sql_database}"> + <doc> + SQL database name for rcynic. + </doc> + </option> + + <option name = "sql-username" + value = "${myrpki::rcynic_sql_username}"> + <doc> + SQL user name for rcynic. + </doc> + </option> + + <option name = "sql-password" + value = "${myrpki::rcynic_sql_password}"> + <doc> + SQL password for rcynic. + </doc> + </option> + + </section> + + <section name = "rpkid"> + + <doc> + rpkid's default config file is the system `rpki.conf` file. + Start rpkid with "`-c filename`" to choose a different config + file. All options are in the "`[rpkid]`" section. BPKI + Certificates and keys may be in either DER or PEM format. + </doc> + + <option name = "sql-engine" + value = "${myrpki::rpkid_sql_engine}"> + <doc> + SQL engine for rpkid. + </doc> + </option> + + <option name = "sql-database" + value = "${myrpki::rpkid_sql_database}"> + <doc> + SQL database name for rpkid. + </doc> + </option> + + <option name = "sql-username" + value = "${myrpki::rpkid_sql_username}"> + <doc> + SQL user name for rpkid. + </doc> + </option> + + <option name = "sql-password" + value = "${myrpki::rpkid_sql_password}"> + <doc> + SQL password for rpkid. + </doc> + </option> + + <option name = "server-host" + value = "${myrpki::rpkid_server_host}"> + <doc> + Host on which rpkid should listen for HTTP service requests. + </doc> + </option> + + <option name = "server-port" + value = "${myrpki::rpkid_server_port}"> + <doc> + Port on which rpkid should listen for HTTP service requests. + </doc> + </option> + + <option name = "irdb-url" + value = "http://${myrpki::irdbd_server_host}:${myrpki::irdbd_server_port}/"> + <doc> + HTTP service URL rpkid should use to contact irdbd. If irdbd is + running on the same machine as rpkid, this can and probably should + be a loopback URL, since nobody but rpkid needs to talk to irdbd. + </doc> + </option> + + <option name = "bpki-ta" + value = "${myrpki::bpki_servers_directory}/ca.cer"> + <doc> + Where rpkid should look for the BPKI trust anchor. All BPKI + certificate verification within rpkid traces back to this + trust anchor. Don't change this unless you really know what + you are doing. + </doc> + </option> + + <option name = "rpkid-cert" + value = "${myrpki::bpki_servers_directory}/rpkid.cer"> + <doc> + Where rpkid should look for its own BPKI EE certificate. Don't + change this unless you really know what you are doing. + </doc> + </option> + + <option name = "rpkid-key" + value = "${myrpki::bpki_servers_directory}/rpkid.key"> + <doc> + Where rpkid should look for the private key corresponding to its + own BPKI EE certificate. Don't change this unless you really know + what you are doing. + </doc> + </option> + + <option name = "irdb-cert" + value = "${myrpki::bpki_servers_directory}/irdbd.cer"> + <doc> + Where rpkid should look for irdbd's BPKI EE certificate. + Don't change this unless you really know what you are doing. + </doc> + </option> + + <option name = "irbe-cert" + value = "${myrpki::bpki_servers_directory}/irbe.cer"> + <doc> + Where rpkid should look for the back-end control client's BPKI EE + certificate. Don't change this unless you really know what you + are doing. + </doc> + </option> + + </section> + + <section name = "irdbd"> + + <doc> + irdbd's default configuration file is the system `rpki.conf` + file. Start irdbd with "`-c filename`" to choose a different + configuration file. All options are in the "`[irdbd]`" section. + </doc> + + <doc> + Since irdbd is part of the back-end system, it has direct access to + the back-end's SQL database, and thus is able to pull its own BPKI + configuration directly from the database, and thus needs a bit less + configuration than the other daemons. + </doc> + + <option name = "sql-engine" + value = "${myrpki::irdbd_sql_engine}"> + <doc> + SQL engine for irdbd. + </doc> + </option> + + <option name = "sql-database" + value = "${myrpki::irdbd_sql_database}"> + <doc> + SQL database name for irdbd. + </doc> + </option> + + <option name = "sql-username" + value = "${myrpki::irdbd_sql_username}"> + <doc> + SQL user name for irdbd. + </doc> + </option> + + <option name = "sql-password" + value = "${myrpki::irdbd_sql_password}"> + <doc> + SQL password for irdbd. + </doc> + </option> + + <option name = "server-host" + value = "${myrpki::irdbd_server_host}"> + <doc> + Host on which irdbd should listen for HTTP service requests. + </doc> + </option> + + <option name = "server-port" + value = "${myrpki::irdbd_server_port}"> + <doc> + Port on which irdbd should listen for HTTP service requests. + </doc> + </option> + + <option name = "startup-message"> + <doc> + String to log on startup, useful when debugging a collection + of irdbd instances at once. + </doc> + </option> + + </section> + + <section name = "pubd"> + + <doc> + pubd's default configuration file is the system `rpki.conf` + file. Start pubd with "`-c filename`" to choose a different + configuration file. All options are in the "`[pubd]`" section. + BPKI certificates and keys may be either DER or PEM format. + </doc> + + <option name = "sql-engine" + value = "${myrpki::pubd_sql_engine}"> + <doc> + SQL engine for pubd. + </doc> + </option> + + <option name = "sql-database" + value = "${myrpki::pubd_sql_database}"> + <doc> + SQL database name for pubd. + </doc> + </option> + + <option name = "sql-username" + value = "${myrpki::pubd_sql_username}"> + <doc> + SQL user name for pubd. + </doc> + </option> + + <option name = "sql-password" + value = "${myrpki::pubd_sql_password}"> + <doc> + SQL password for pubd. + </doc> + </option> + + <option name = "publication-base" + value = "${myrpki::publication_base_directory}"> + <doc> + Root of directory tree where pubd should write out published data. + You need to configure this, and the configuration should match up + with the directory where you point rsyncd. Neither pubd nor rsyncd + much cares -where- you tell them to put this stuff, the important + thing is that the rsync URIs in generated certificates match up + with the published objects so that relying parties can find and + verify rpkid's published outputs. + </doc> + </option> + + <option name = "rrdp-publication-base" + value = "${myrpki::rrdp_publication_base_directory}"> + <doc> + Root of local directory tree where pubd should write out RRDP + files. You need to configure this, and the configuration + should match up with the directory where you point the web + server (usually Apache) that serves the RRDP files. Neither + pubd nor Apache much cares //where// you tell it to put this + stuff, the important thing is that all the URIs match up so + that relying parties can find and verify rpkid's published + outputs. + </doc> + </option> + + <option name = "server-host" + value = "${myrpki::pubd_server_host}"> + <doc> + Host on which pubd should listen for HTTP service requests. + </doc> + </option> + + <option name = "server-port" + value = "${myrpki::pubd_server_port}"> + <doc> + Port on which pubd should listen for HTTP service requests. + </doc> + </option> + + <option name = "bpki-ta" + value = "${myrpki::bpki_servers_directory}/ca.cer"> + <doc> + Where pubd should look for the BPKI trust anchor. All BPKI + certificate verification within pubd traces back to this + trust anchor. Don't change this unless you really know what + you are doing. + </doc> + </option> + + <option name = "pubd-cert" + value = "${myrpki::bpki_servers_directory}/pubd.cer"> + <doc> + Where pubd should look for its own BPKI EE certificate. Don't + change this unless you really know what you are doing. + </doc> + </option> + + <option name = "pubd-key" + value = "${myrpki::bpki_servers_directory}/pubd.key"> + <doc> + Where pubd should look for the private key corresponding to its + own BPKI EE certificate. Don't change this unless you really know + what you are doing. + </doc> + </option> + + <option name = "pubd-crl" + value = "${myrpki::bpki_servers_directory}/ca.crl"> + <doc> + Where pubd should look for the CRL covering its own BPKI EE + certificate. Don't change this unless you really know what + you are doing. + </doc> + </option> + + <option name = "irbe-cert" + value = "${myrpki::bpki_servers_directory}/irbe.cer"> + <doc> + Where pubd should look for the back-end control client's BPKI EE + certificate. Don't change this unless you really know what you + are doing. + </doc> + </option> + + <option name = "rrdp-base-uri" + value = "${myrpki::publication_rrdp_base_uri}"> + <doc> + RRDP base URI for naming snapshots and deltas. + </doc> + </option> + + </section> + + <section name = "rootd"> + + <doc> + You don't need to run rootd unless you're IANA, are certifying + private address space, or are an RIR which refuses to accept IANA as + the root of the public address hierarchy. + </doc> + + <doc> + Ok, if that wasn't enough to scare you off: rootd is a mess, + needs to be rewritten, or, better, merged into rpkid, and + requires far too many configuration parameters. + </doc> + + <doc> + rootd was originally intended to be a very simple program which + simplified rpkid enormously by moving one specific task (acting + as the root CA of an RPKI certificate hierarchy) out of rpkid. + As the specifications and code (mostly the latter) have evolved, + however, this task has become more complicated, and rootd would + have to become much more complicated to keep up. + </doc> + + <doc> + Don't run rootd unless you're sure that you need to do so. + </doc> + + <doc> + Still think you need to run rootd? OK, but remember, you have + been warned.... + </doc> + + <doc> + rootd's default configuration file is the system `rpki.conf` + file. Start rootd with "`-c filename`" to choose a different + configuration file. All options are in the "`[rootd]`" section. + Certificates and keys may be in either DER or PEM format. + </doc> + + <option name = "bpki-ta" + value = "${myrpki::bpki_servers_directory}/ca.cer"> + <doc> + Where rootd should look for the BPKI trust anchor. All BPKI + certificate verification within rootd traces back to this + trust anchor. Don't change this unless you really know what + you are doing. + </doc> + </option> + + <option name = "rootd-bpki-crl" + value = "${myrpki::bpki_servers_directory}/ca.crl"> + <doc> + BPKI CRL. Don't change this unless you really know what you are + doing. + </doc> + </option> + + <option name = "rootd-bpki-cert" + value = "${myrpki::bpki_servers_directory}/rootd.cer"> + <doc> + rootd's own BPKI EE certificate. Don't change this unless you + really know what you are doing. + </doc> + </option> + + <option name = "rootd-bpki-key" + value = "${myrpki::bpki_servers_directory}/rootd.key"> + <doc> + Private key corresponding to rootd's own BPKI EE certificate. + Don't change this unless you really know what you are doing. + </doc> + </option> + + <option name = "child-bpki-cert" + value = "${myrpki::bpki_servers_directory}/child.cer"> + <doc> + BPKI certificate for rootd's one and only up-down child (RPKI + engine to which rootd issues an RPKI certificate). Don't + change this unless you really know what you are doing. + </doc> + </option> + + <option name = "pubd-bpki-cert"> + <doc> + BPKI certificate for pubd. Don't set this unless you really + know what you are doing. + </doc> + </option> + + <option name = "server-host" + value = "${myrpki::rootd_server_host}"> + <doc> + Server host on which rootd should listen. + </doc> + </option> + + <option name = "server-port" + value = "${myrpki::rootd_server_port}"> + <doc> + Server port on which rootd should listen. + </doc> + </option> + + <option name = "rpki_data_dir" + value = "${myrpki::bpki_servers_directory}"> + <doc> + Directory where rootd should store its RPKI data files. This + is only used to construct other variables, rootd itself + doesn't read it. + </doc> + </option> + + <option name = "rpki_base_uri" + value = "rsync://${myrpki::publication_rsync_server}/${myrpki::publication_rsync_module}/${myrpki::handle}-root/root"> + <doc> + rsync URI corresponding to directory containing rootd's + outputs. This is only used to construct other variables, + rootd itself doesn't read it. + </doc> + </option> + + <option name = "rpki-root-cert-uri" + value = "${rootd::rpki_base_uri}.cer"> + <doc> + rsync URI for rootd's root (self-signed) RPKI certificate. + </doc> + </option> + + <option name = "rpki-root-cert-file" + value = "${rootd::rpki_data_dir}/root.cer"> + <doc> + Filename of rootd's root RPKI certificate. + </doc> + </option> + + <option name = "rpki-root-key-file" + value = "${rootd::rpki_data_dir}/root.key"> + <doc> + Private key corresponding to rootd's root RPKI certificate. + </doc> + </option> + + <option name = "rpki-root-crl-uri" + value = "${rootd::rpki_base_uri}/root.crl"> + <doc> + URI of the CRL for rootd's root RPKI certificate. + </doc> + </option> + + <option name = "rpki-root-crl-file" + value = "${rootd::rpki_data_dir}/root.crl"> + <doc> + Filename of the CRL for rootd's root RPKI certificate. + </doc> + </option> + + <option name = "rpki-root-manifest-uri" + value = "${rootd::rpki_base_uri}/root.mft"> + <doc> + URI of the manifest for rootd's root RPKI certificate. + </doc> + </option> + + <option name = "rpki-root-manifest-file" + value = "${rootd::rpki_data_dir}/root.mft"> + <doc> + Filename of the manifest for rootd's root RPKI certificate. + </doc> + </option> + + <option name = "rpki-subject-pkcs10-file" + value = "${rootd::rpki_data_dir}/subject.pkcs10"> + <doc> + Where rootd should stash a copy of the PKCS #10 request it gets + from its one (and only) child + </doc> + </option> + + <option name = "rpki-subject-lifetime" + value = "30d"> + <doc> + Lifetime of the one and only RPKI certificate rootd issues. + </doc> + </option> + + <option name = "rpki-class-name" + value = "${myrpki::handle}"> + <doc> + Up-down protocol class name for RPKI certificate rootd issues to its + one (and only) child. + </doc> + </option> + + <option name = "rpki-subject-cert-uri" + value = "${rootd::rpki_base_uri}/${myrpki::handle}.cer"> + <doc> + URI of the one (and only) RPKI certificate rootd issues. + </doc> + </option> + + <option name = "rpki-subject-cert-file" + value = "${rootd::rpki_data_dir}/${myrpki::handle}.cer"> + <doc> + Filename of the one (and only) RPKI certificate rootd issues. + </doc> + </option> + + <option name = "pubd-contact-uri" + value = "http://${myrpki::pubd_server_host}:${myrpki::pubd_server_port}/client/${myrpki::handle}-root"> + <doc> + URI at which rootd should contact pubd for service. + </doc> + </option> + + <option name = "rrdp-notification-uri" + value = "${myrpki::publication_rrdp_notification_uri"> + <doc> + RRDP URI for inclusion in generated objects. + </doc> + </option> + + </section> + + <section name = "web_portal"> + + <doc> + Glue to allow Django to pull user configuration from this file + rather than requiring the user to edit settings.py. + </doc> + + <!-- + We used to have SQL settings for the GUI here, but since + they're pretty much required to be identical to the ones for + irdbd at this point, the duplicate entries were just another + chance to misconfigure something, so I removed them. Not yet + sure whether this was the right approach. Too much historical + baggage in this file. + --> + + <option name = "secret-key"> + <doc> + Site-specific secret key for Django. + </doc> + </option> + + <option name = "allowed-hosts"> + <doc> + Name of virtual host that runs the Django GUI, if this is not + the same as the system hostname. Django's security code wants + to know the name of the virtual host on which Django is + running, and will fail when it thinks it's running on a + disallowed host. + </doc> + <doc> + If you get an error like "Invalid HTTP_HOST header (you may + need to set ALLOWED_HOSTS)", you will need to set this option. + </doc> + </option> + + <option name = "download-directory" + value = "/var/tmp"> + <doc> + A directory large enough to hold the RouteViews.org routing table dump + fetched by the rpkigui-import-routes script. + </doc> + </option> + + </section> + + <section name = "autoconf"> + + <doc> + rpki-confgen --autoconf records the current autoconf settings + here, so that other options can refer to them. The section name + "autoconf" is magic, don't change it. + </doc> + + <option name = "bindir"> + <doc> + Usually /usr/bin or /usr/local/bin. + </doc> + </option> + + <option name = "datarootdir"> + <doc> + Usually /usr/share or /usr/local/share. + </doc> + </option> + + <option name = "sbindir"> + <doc> + Usually /usr/sbin or /usr/local/sbin. + </doc> + </option> + + <option name = "sysconfdir"> + <doc> + Usually /etc or /usr/local/etc. + </doc> + </option> + + </section> + +</configuration> diff --git a/rp/config/rpki-manage b/rp/config/rpki-manage new file mode 100755 index 00000000..16d0990d --- /dev/null +++ b/rp/config/rpki-manage @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os + +# django-admin seems to have problems creating the superuser account when +# $LANG is unset or is set to something totally incompatible with UTF-8. + +if os.environ.get("LANG") in (None, "", "C"): + os.environ["LANG"] = "en_US.UTF-8" + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rpki.django_settings.gui") + +from django.core.management import execute_from_command_line + +execute_from_command_line() diff --git a/rp/config/rpki-sql-backup b/rp/config/rpki-sql-backup new file mode 100755 index 00000000..986e10b1 --- /dev/null +++ b/rp/config/rpki-sql-backup @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# Portions copyright (C) 2010-2013 Internet Systems Consortium ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notices and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL AND ISC DISCLAIM ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL OR +# ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Back up data from SQL databases, looking at config file to figure out +which databases and what credentials to use with them. +""" + +import subprocess +import os +import argparse +import sys +import time +import rpki.config + +os.environ["TZ"] = "UTC" +time.tzset() + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("-c", "--config", + help = "override default location of configuration file") +parser.add_argument("-o", "--output", + type = argparse.FileType("wb"), default = sys.stdout, + help = "destination for SQL dump (default: stdout)") +args = parser.parse_args() + +cfg = rpki.config.parser(set_filename = args.config, section = "myrpki") + +for name in ("rpkid", "irdbd", "pubd"): + if cfg.getboolean("start_" + name, False): + subprocess.check_call( + ("mysqldump", "--add-drop-database", + "-u", cfg.get("sql-username", section = name), + "-p" + cfg.get("sql-password", section = name), + "-B", cfg.get("sql-database", section = name)), + stdout = args.output) diff --git a/rp/config/rpki-sql-setup b/rp/config/rpki-sql-setup new file mode 100755 index 00000000..c72c97c5 --- /dev/null +++ b/rp/config/rpki-sql-setup @@ -0,0 +1,348 @@ +#!/usr/bin/env python + +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# Portions copyright (C) 2009-2013 Internet Systems Consortium ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notices and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL AND ISC DISCLAIM ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL OR +# ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Automated setup of SQL stuff used by the RPKI tools. Pulls +configuration from rpki.conf, prompts for SQL password when needed. +""" + +import os +import pwd +import sys +import getpass +import textwrap +import argparse +import rpki.config + + +class Abstract_Driver(object): + + # Kludge to make classes derived from this into singletons. Net + # of a Million Lies says this is Not Pythonic, but it seems to + # work, so long as one doesn't attempt to subclass the resulting + # driver classes. For our purposes, it will do. + + __instance = None + + def __new__(cls, *args, **kwargs): + if cls.__instance is None: + cls.__instance = object.__new__(cls, *args, **kwargs) + return cls.__instance + + def db_accessible(self, udb): + try: + self._db_accessible_test(udb) + except: + return False + else: + return True + + def db_exists(self, udb): + self.execute("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = %s", (udb.database,)) + return bool(self.fetchone()[0]) + + def fetchone(self): + return self._cur.fetchone() + + def fetchall(self): + return self._cur.fetchall() + + def close(self): + self._cur.close() + self._db.close() + + def log(self, msg): + if self.args.verbose: + sys.stderr.write(msg + "\n") + + +class MySQL_Driver(Abstract_Driver): + + _initialized = False + + def __init__(self, args): + try: + self.driver + except AttributeError: + from rpki.mysql_import import MySQLdb + self.driver = MySQLdb + self.args = args + + def _db_accessible_test(self, udb): + self.driver.connect(db = udb.database, user = udb.username, passwd = udb.password).close() + + def execute(*args): + try: + self._cur + except AttributeError: + self.log("MySQL driver initializing root connection") + if self.args.mysql_defaults: + mysql_cfg = rpki.config.parser(set_filename = self.args.mysql_defaults, section = "client") + self._db = self.driver.connect(db = "mysql", + user = mysql_cfg.get("user"), + passwd = mysql_cfg.get("password")) + else: + self._db = self.driver.connect(db = "mysql", + user = "root", + passwd = getpass.getpass("Please enter your MySQL root password: ")) + self._db.autocommit(True) + self._cur = self._db.cursor() + self.log("MySQL driver executing {}".format(", ".join(args))) + return self._cur.execute(*args) + + def create(self, udb): + self.execute("CREATE DATABASE IF NOT EXISTS {0.database}".format(udb)) + self.fix_grants(udb) + + def drop(self, udb): + self.execute("DROP DATABASE IF EXISTS {0.database}".format(udb)) + + def script_drop(self, udb): + self.args.script_output.write("DROP DATABASE IF EXISTS {};\n".format(udb.database)) + + def fix_grants(self, udb): + self.execute("GRANT ALL ON {0.database}.* TO {0.username}@localhost IDENTIFIED BY %s".format(udb), + (udb.password,)) + +class SQLite3_Driver(Abstract_Driver): + + def __init__(self, args): + try: + self.driver + except AttributeError: + import sqlite3 + self.driver = sqlite3 + self.args = args + + def _db_accessible_test(self, udb): + self.driver.connect(udb.database).close() + + def db_exists(self, udb): + return os.path.exists(udb.database) + + def _grant(self, udb): + if udb.username and os.geteuid() == 0: + pw = pwd.getpwnam(udb.username) + os.chown(udb.database, pw.pw_uid, pw.pw_gid) + + def create(self, udb): + self._db_accessible_test(udb.database) + self._grant(udb) + + def drop(self, udb): + os.unlink(udb.database) + + def script_drop(self, udb): + self.args.script_output.write("rm {}\n".format(udb.database)) + + def fix_grants(self, udb): + self._grant(udb) + + +class PostgreSQL_Driver(Abstract_Driver): + + def __init__(self, args): + try: + self.driver + except AttributeError: + import psycopg2 + self.driver = psycopg2 + self.args = args + if args.postgresql_root_username and (os.getuid() == 0 or os.geteuid() == 0): + self._pw = pwd.getpwnam(args.postgresql_root_username) + else: + self._pw = None + self.log("Initialized PostgreSQL driver, pw {!r}".format(self._pw)) + + def _seteuid(self, new_uid): + old_uid = os.geteuid() + if new_uid != old_uid: + self.log("PostgreSQL driver changing EUID from {} to {}".format(old_uid, new_uid)) + os.seteuid(new_uid) + return old_uid + + def execute(self, *args): + try: + self._cur + except AttributeError: + self.log("PostgreSQL driver opening connection to database {}".format(self.args.postgresql_root_database)) + if self._pw is not None: + euid = self._seteuid(self._pw.pw_uid) + try: + self._db = self.driver.connect(database = self.args.postgresql_root_database) + self._db.autocommit = True + self._cur = self._db.cursor() + finally: + if self._pw is not None: + self._seteuid(euid) + self.log("PostgreSQL driver executing {}".format(", ".join(args))) + return self._cur.execute(*args) + + def _db_accessible_test(self, udb): + pw = pwd.getpwnam(udb.username) + uid = self._seteuid(pw.pw_uid) + try: + self.driver.connect(database = udb.database, user = udb.username , password = usb.password).close() + finally: + self._seteuid(uid) + + def _role_in_use(self, udb): + self.execute('''\ + SELECT COUNT(*) FROM pg_database + JOIN pg_roles ON pg_database.datdba = pg_roles.oid + WHERE pg_roles.rolname = %s''', (udb.username,)) + return bool(self.fetchone()[0]) + + def create(self, udb): + self.execute('''\ + DO $$ BEGIN + IF NOT EXISTS (SELECT * FROM pg_catalog.pg_roles + WHERE rolname = '{0.username}') + THEN + CREATE ROLE {0.username} LOGIN PASSWORD '{0.password}'; + END IF; + END $$'''.format(udb)) + self.execute("CREATE DATABASE {0.database} OWNER {0.username}".format(udb)) + + def drop(self, udb): + self.execute("DROP DATABASE IF EXISTS {0.database}".format(udb)) + if not self._role_in_use(udb): + self.execute("DROP ROLE IF EXISTS {0.username}".format(udb)) + + def script_drop(self, udb): + self.args.script_output.write(textwrap.dedent('''\ + DROP DATABASE IF EXISTS {0.database}; + DO $$ BEGIN + IF NOT EXISTS (SELECT * FROM pg_database JOIN pg_roles + ON pg_database.datdba = pg_roles.oid + WHERE pg_roles.rolname = '{0.username}') + THEN + DROP ROLE IF EXISTS {0.username}; + END IF; + END $$; + '''.format(udb))) + + def fix_grants(self, udb): + self.execute("ALTER DATABASE {0.database} OWNER TO {0.username}".format(udb)) + self.execute("ALTER ROLE {0.username} WITH PASSWORD '{0.password}".format(udb)) + + +class UserDB(object): + """ + Class to wrap access parameters for a particular database. + """ + + drivers = dict(sqlite3 = SQLite3_Driver, + mysql = MySQL_Driver, + postgresql = PostgreSQL_Driver) + + def __init__(self, args, name): + self.database = cfg.get("sql-database", section = name) + self.username = cfg.get("sql-username", section = name) + self.password = cfg.get("sql-password", section = name) + self.engine = cfg.get("sql-engine", section = name) + self.driver = self.drivers[self.engine](args) + self.args = args + + def drop(self): + if self.args.force or self.driver.db_accessible(self): + self.driver.drop(self) + + def create(self): + if self.args.force or not self.driver.db_accessible(self): + self.driver.create(self) + + def script_drop(self): + self.driver.script_drop(self) + + def drop_and_create(self): + if self.args.force or self.driver.db_accessible(self): + self.driver.drop(self) + self.driver.create(self) + + def fix_grants(self): + if self.args.force or not self.driver.db_accessible(self): + self.driver.fix_grants(self) + + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("-c", "--config", + help = "specify alternate location for rpki.conf") +parser.add_argument("-d", "--debug", action = "store_true", + help = "enable debugging (eg, Python backtraces)") +parser.add_argument("-v", "--verbose", action = "store_true", + help = "whistle while you work") +parser.add_argument("-f", "--force", action = "store_true", + help = "force database create, drop, or grant regardless of current state") + +parser.add_argument("--mysql-defaults", + help = "specify MySQL root access credentials via a configuration file") + + +parser.add_argument("--postgresql-root-database", default = "postgres", + help = "name of PostgreSQL control database") +parser.add_argument("--postgresql-root-username", + help = "username of PostgreSQL control role") + +subparsers = parser.add_subparsers(title = "Commands", metavar = "", dest = "dispatch") + +subparsers.add_parser("create", + help = "create databases and load schemas") + +subparsers.add_parser("drop", + help = "drop databases") + +subparser = subparsers.add_parser("script-drop", + help = "show SQL commands to drop databases") +subparser.add_argument("script_output", + nargs = "?", type = argparse.FileType("w"), default = "-", + help = "destination for drop script") + +subparsers.add_parser("drop-and-create", + help = "drop databases then recreate them and load schemas") + +subparsers.add_parser("fix-grants", + help = "whack database to match configuration file") + +args = parser.parse_args() + +try: + + cfg = rpki.config.parser(set_filename = args.config, section = "myrpki") + + names = [name for name in ("irdbd", "rpkid", "pubd") + if cfg.getboolean("start_" + name, False)] + names.append("rcynic") + + # For now, we quietly ignore missing sections rather than throwing an exception. + # I could make a case either way for this, but ignoring missing sections is a + # lot easier to clean up while debugging the installation scripts. + + for name in names: + if cfg.has_section(name): + udb = UserDB(args = args, name = name) + method = args.dispatch.replace("-", "_") + getattr(udb, method)() + +except Exception, e: + if args.debug: + raise + else: + sys.exit(str(e)) diff --git a/rp/rcynic/Makefile.in b/rp/rcynic/Makefile.in index a2d844bd..ce19ab81 100644 --- a/rp/rcynic/Makefile.in +++ b/rp/rcynic/Makefile.in @@ -49,19 +49,15 @@ RCYNIC_CRON_USER = @RCYNIC_CRON_USER@ RCYNIC_DATA_DIR = ${RCYNIC_DIR}/data RCYNIC_DIR = @RCYNIC_DIR@ RCYNIC_DIRS = ${RCYNIC_TA_DIR} ${RCYNIC_JAIL_DIRS} ${RCYNIC_DATA_DIR} ${RPKIRTR_DIR} ${RPKIRTR_DIR}/sockets -RCYNIC_GECOS = RPKI Validation System -RCYNIC_GROUP = @RCYNIC_GROUP@ +RPKI_GECOS = RPKI System Software +RPKI_GROUP = @RPKI_GROUP@ RCYNIC_HTML_DIR = @RCYNIC_HTML_DIR@ RCYNIC_INSTALL_TARGETS = @RCYNIC_INSTALL_TARGETS@ RCYNIC_JAIL_DIRS = @RCYNIC_JAIL_DIRS@ RCYNIC_STATIC_RSYNC = @RCYNIC_STATIC_RSYNC@ RCYNIC_TA_DIR = @RCYNIC_TA_DIR@ -RCYNIC_USER = @RCYNIC_USER@ +RPKI_USER = @RPKI_USER@ RPKIRTR_DIR = ${RCYNIC_DIR}/rpki-rtr -RPKIRTR_GECOS = RPKI router server -RPKIRTR_GROUP = rpkirtr -RPKIRTR_MODE = 775 -RPKIRTR_USER = rpkirtr all: ${BIN} ${RCYNIC_STATIC_RSYNC} @@ -122,9 +118,7 @@ ${RCYNIC_DIRS} ${DESTDIR}${bindir} ${DESTDIR}${sysconfdir}: ${INSTALL} -v -d $@ install-directory-ownership: ${RCYNIC_DATA_DIR} ${RPKIRTR_DIR} ${RPKIRTR_DIR}/sockets - chown ${RCYNIC_USER}:${RCYNIC_GROUP} ${RCYNIC_DATA_DIR} ${RPKIRTR_DIR} - chown ${RPKIRTR_USER}:${RCYNIC_GROUP} ${RPKIRTR_DIR}/sockets - chmod ${RPKIRTR_MODE} ${RPKIRTR_DIR}/sockets + chown ${RPKI_USER}:${RPKI_GROUP} ${RCYNIC_DATA_DIR} ${RPKIRTR_DIR} ${RPKIRTR_DIR}/sockets install-rcynic-conf: ${RCYNIC_CONF_FILE} diff --git a/rp/rcynic/rcynic-cron b/rp/rcynic/rcynic-cron index d1f96422..fcf38e53 100755 --- a/rp/rcynic/rcynic-cron +++ b/rp/rcynic/rcynic-cron @@ -74,9 +74,9 @@ if args.chroot and not we_are_root: sys.exit("Only root can --chroot") try: - pw = pwd.getpwnam(rpki.autoconf.RCYNIC_USER) + pw = pwd.getpwnam(rpki.autoconf.RPKI_USER) except KeyError: - sys.exit("Could not find passwd entry for user %s" % rpki.autoconf.RCYNIC_USER) + sys.exit("Could not find passwd entry for user %s" % rpki.autoconf.RPKI_USER) try: lock = os.open(os.path.join(rpki.autoconf.RCYNIC_DIR, "data/lock"), diff --git a/rp/rcynic/rules.darwin.mk b/rp/rcynic/rules.darwin.mk index d37b0e75..b5979979 100644 --- a/rp/rcynic/rules.darwin.mk +++ b/rp/rcynic/rules.darwin.mk @@ -1,77 +1,41 @@ # $Id$ install-user-and-group: .FORCE - @if /usr/bin/dscl . -read "/Groups/${RCYNIC_GROUP}" >/dev/null 2>&1; \ + @if /usr/bin/dscl . -read "/Groups/${RPKI_GROUP}" >/dev/null 2>&1; \ then \ - echo "You already have a group \"${RCYNIC_GROUP}\", so I will use it."; \ + echo "You already have a group \"${RPKI_GROUP}\", so I will use it."; \ elif gid="$$(/usr/bin/dscl . -list /Groups PrimaryGroupID | /usr/bin/awk 'BEGIN {gid = 501} $$2 >= gid {gid = 1 + $$2} END {print gid}')" && \ - /usr/bin/dscl . -create "/Groups/${RCYNIC_GROUP}" && \ - /usr/bin/dscl . -create "/Groups/${RCYNIC_GROUP}" RealName "${RCYNIC_GECOS}" && \ - /usr/bin/dscl . -create "/Groups/${RCYNIC_GROUP}" PrimaryGroupID "$$gid" && \ - /usr/bin/dscl . -create "/Groups/${RCYNIC_GROUP}" GeneratedUID "$$(/usr/bin/uuidgen)" && \ - /usr/bin/dscl . -create "/Groups/${RCYNIC_GROUP}" Password "*"; \ + /usr/bin/dscl . -create "/Groups/${RPKI_GROUP}" && \ + /usr/bin/dscl . -create "/Groups/${RPKI_GROUP}" RealName "${RPKI_GECOS}" && \ + /usr/bin/dscl . -create "/Groups/${RPKI_GROUP}" PrimaryGroupID "$$gid" && \ + /usr/bin/dscl . -create "/Groups/${RPKI_GROUP}" GeneratedUID "$$(/usr/bin/uuidgen)" && \ + /usr/bin/dscl . -create "/Groups/${RPKI_GROUP}" Password "*"; \ then \ - echo "Added group \"${RCYNIC_GROUP}\"."; \ + echo "Added group \"${RPKI_GROUP}\"."; \ else \ - echo "Adding group \"${RCYNIC_GROUP}\" failed..."; \ + echo "Adding group \"${RPKI_GROUP}\" failed..."; \ echo "Please create it, then try again."; \ exit 1; \ fi; \ - if /usr/bin/dscl . -read "/Users/${RCYNIC_USER}" >/dev/null 2>&1; \ + if /usr/bin/dscl . -read "/Users/${RPKI_USER}" >/dev/null 2>&1; \ then \ - echo "You already have a user \"${RCYNIC_USER}\", so I will use it."; \ + echo "You already have a user \"${RPKI_USER}\", so I will use it."; \ elif uid="$$(/usr/bin/dscl . -list /Users UniqueID | /usr/bin/awk 'BEGIN {uid = 501} $$2 >= uid {uid = 1 + $$2} END {print uid}')" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" UserShell "/usr/bin/false" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" RealName "${RCYNIC_GECOS}" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" UniqueID "$$uid" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" PrimaryGroupID "$$gid" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" NFSHomeDirectory "/var/empty" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" GeneratedUID "$$(/usr/bin/uuidgen)" && \ - /usr/bin/dscl . -create "/Users/${RCYNIC_USER}" Password "*"; \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" && \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" UserShell "/usr/bin/false" && \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" RealName "${RPKI_GECOS}" && \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" UniqueID "$$uid" && \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" PrimaryGroupID "$$gid" && \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" NFSHomeDirectory "/var/empty" && \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" GeneratedUID "$$(/usr/bin/uuidgen)" && \ + /usr/bin/dscl . -create "/Users/${RPKI_USER}" Password "*"; \ then \ - echo "Added user \"${RCYNIC_USER}\"."; \ + echo "Added user \"${RPKI_USER}\"."; \ else \ - echo "Adding user \"${RCYNIC_USER}\" failed..."; \ + echo "Adding user \"${RPKI_USER}\" failed..."; \ echo "Please create it, then try again."; \ exit 1; \ fi - @if /usr/bin/dscl . -read "/Groups/${RPKIRTR_GROUP}" >/dev/null 2>&1; \ - then \ - echo "You already have a group \"${RPKIRTR_GROUP}\", so I will use it."; \ - elif gid="$$(/usr/bin/dscl . -list /Groups PrimaryGroupID | /usr/bin/awk 'BEGIN {gid = 501} $$2 >= gid {gid = 1 + $$2} END {print gid}')" && \ - /usr/bin/dscl . -create "/Groups/${RPKIRTR_GROUP}" && \ - /usr/bin/dscl . -create "/Groups/${RPKIRTR_GROUP}" RealName "${RPKIRTR_GECOS}" && \ - /usr/bin/dscl . -create "/Groups/${RPKIRTR_GROUP}" PrimaryGroupID "$$gid" && \ - /usr/bin/dscl . -create "/Groups/${RPKIRTR_GROUP}" GeneratedUID "$$(/usr/bin/uuidgen)" && \ - /usr/bin/dscl . -create "/Groups/${RPKIRTR_GROUP}" Password "*"; \ - then \ - echo "Added group \"${RPKIRTR_GROUP}\"."; \ - else \ - echo "Adding group \"${RPKIRTR_GROUP}\" failed..."; \ - echo "Please create it, then try again."; \ - exit 1; \ - fi; \ - if /usr/bin/dscl . -read "/Users/${RPKIRTR_USER}" >/dev/null 2>&1; \ - then \ - echo "You already have a user \"${RPKIRTR_USER}\", so I will use it."; \ - elif uid="$$(/usr/bin/dscl . -list /Users UniqueID | /usr/bin/awk 'BEGIN {uid = 501} $$2 >= uid {uid = 1 + $$2} END {print uid}')" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" UserShell "/usr/bin/false" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" RealName "${RPKIRTR_GECOS}" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" UniqueID "$$uid" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" PrimaryGroupID "$$gid" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" NFSHomeDirectory "/var/empty" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" GeneratedUID "$$(/usr/bin/uuidgen)" && \ - /usr/bin/dscl . -create "/Users/${RPKIRTR_USER}" Password "*"; \ - then \ - echo "Added user \"${RPKIRTR_USER}\"."; \ - else \ - echo "Adding user \"${RPKIRTR_USER}\" failed..."; \ - echo "Please create it, then try again."; \ - exit 1; \ - fi - install-shared-libraries: .FORCE @echo "Copying required shared libraries" diff --git a/rp/rcynic/rules.freebsd.mk b/rp/rcynic/rules.freebsd.mk index 5233386e..880ce3f4 100644 --- a/rp/rcynic/rules.freebsd.mk +++ b/rp/rcynic/rules.freebsd.mk @@ -1,51 +1,28 @@ # $Id$ install-user-and-group: .FORCE - @if /usr/sbin/pw groupshow "${RCYNIC_GROUP}" 2>/dev/null; \ + @if /usr/sbin/pw groupshow "${RPKI_GROUP}" 2>/dev/null; \ then \ - echo "You already have a group \"${RCYNIC_GROUP}\", so I will use it."; \ - elif /usr/sbin/pw groupadd ${RCYNIC_GROUP}; \ + echo "You already have a group \"${RPKI_GROUP}\", so I will use it."; \ + elif /usr/sbin/pw groupadd ${RPKI_GROUP}; \ then \ - echo "Added group \"${RCYNIC_GROUP}\"."; \ + echo "Added group \"${RPKI_GROUP}\"."; \ else \ - echo "Adding group \"${RCYNIC_GROUP}\" failed..."; \ + echo "Adding group \"${RPKI_GROUP}\" failed..."; \ echo "Please create it, then try again."; \ exit 1; \ fi - @if /usr/sbin/pw groupshow "${RPKIRTR_GROUP}" 2>/dev/null; \ + @if /usr/sbin/pw usershow "${RPKI_USER}" 2>/dev/null; \ then \ - echo "You already have a group \"${RPKIRTR_GROUP}\", so I will use it."; \ - elif /usr/sbin/pw groupadd ${RPKIRTR_GROUP}; \ + echo "You already have a user \"${RPKI_USER}\", so I will use it."; \ + elif /usr/sbin/pw useradd ${RPKI_USER} -g ${RPKI_GROUP} -h - -d /nonexistant -s /usr/sbin/nologin -c "${RPKI_GECOS}"; \ then \ - echo "Added group \"${RPKIRTR_GROUP}\"."; \ + echo "Added user \"${RPKI_USER}\"."; \ else \ - echo "Adding group \"${RPKIRTR_GROUP}\" failed..."; \ + echo "Adding user \"${RPKI_USER}\" failed..."; \ echo "Please create it, then try again."; \ exit 1; \ fi - @if /usr/sbin/pw usershow "${RCYNIC_USER}" 2>/dev/null; \ - then \ - echo "You already have a user \"${RCYNIC_USER}\", so I will use it."; \ - elif /usr/sbin/pw useradd ${RCYNIC_USER} -g ${RCYNIC_GROUP} -h - -d /nonexistant -s /usr/sbin/nologin -c "${RCYNIC_GECOS}" -G "${RPKIRTR_GROUP}"; \ - then \ - echo "Added user \"${RCYNIC_USER}\"."; \ - else \ - echo "Adding user \"${RCYNIC_USER}\" failed..."; \ - echo "Please create it, then try again."; \ - exit 1; \ - fi - @if /usr/sbin/pw usershow "${RPKIRTR_USER}" 2>/dev/null; \ - then \ - echo "You already have a user \"${RPKIRTR_USER}\", so I will use it."; \ - elif /usr/sbin/pw useradd ${RPKIRTR_USER} -g ${RPKIRTR_GROUP} -h - -d /nonexistant -s /usr/sbin/nologin -c "${RPKIRTR_GECOS}"; \ - then \ - echo "Added user \"${RPKIRTR_USER}\"."; \ - else \ - echo "Adding user \"${RPKIRTR_USER}\" failed..."; \ - echo "Please create it, then try again."; \ - exit 1; \ - fi - # We use static compilation on FreeBSD, so no need for shared libraries diff --git a/rp/rcynic/rules.linux.mk b/rp/rcynic/rules.linux.mk index 6a962cef..016b0582 100644 --- a/rp/rcynic/rules.linux.mk +++ b/rp/rcynic/rules.linux.mk @@ -1,55 +1,36 @@ # $Id$ install-user-and-group: .FORCE - @if getent group ${RCYNIC_GROUP} >/dev/null; \ + @if getent group ${RPKI_GROUP} >/dev/null; \ then \ - echo "You already have a group \"${RCYNIC_GROUP}\", so I will use it."; \ - elif /usr/sbin/groupadd ${RCYNIC_GROUP}; \ + echo "You already have a group \"${RPKI_GROUP}\", so I will use it."; \ + elif /usr/sbin/groupadd ${RPKI_GROUP}; \ then \ - echo "Added group \"${RCYNIC_GROUP}\"."; \ + echo "Added group \"${RPKI_GROUP}\"."; \ else \ - echo "Adding group \"${RCYNIC_GROUP}\" failed..."; \ + echo "Adding group \"${RPKI_GROUP}\" failed..."; \ echo "Please create it, then try again."; \ exit 1; \ fi @nogroup='-N'; \ if test -f /etc/redhat-release; then read vendor release version < /etc/redhat-release; if test $$vendor = CentOS; then nogroup='-n'; fi; fi; \ - if getent passwd ${RCYNIC_USER} >/dev/null; \ + if getent passwd ${RPKI_USER} >/dev/null; \ then \ - echo "You already have a user \"${RCYNIC_USER}\", so I will use it."; \ - elif /usr/sbin/useradd -g ${RCYNIC_GROUP} -M $$nogroup -d "${RCYNIC_DIR}" -s /sbin/nologin -c "${RCYNIC_GECOS}" ${RCYNIC_USER}; \ + echo "You already have a user \"${RPKI_USER}\", so I will use it."; \ + elif /usr/sbin/useradd -g ${RPKI_GROUP} -M $$nogroup -d "${RCYNIC_DIR}" -s /sbin/nologin -c "${RPKI_GECOS}" ${RPKI_USER}; \ then \ - echo "Added user \"${RCYNIC_USER}\"."; \ + echo "Added user \"${RPKI_USER}\"."; \ else \ - echo "Adding user \"${RCYNIC_USER}\" failed..."; \ + echo "Adding user \"${RPKI_USER}\" failed..."; \ echo "Please create it, then try again."; \ exit 1; \ fi - @if getent group ${RPKIRTR_GROUP} >/dev/null; \ - then \ - echo "You already have a group \"${RPKIRTR_GROUP}\", so I will use it."; \ - elif /usr/sbin/groupadd ${RPKIRTR_GROUP}; \ - then \ - echo "Added group \"${RPKIRTR_GROUP}\"."; \ - else \ - echo "Adding group \"${RPKIRTR_GROUP}\" failed..."; \ - echo "Please create it, then try again."; \ - exit 1; \ - fi - @nogroup='-N'; \ - if test -f /etc/redhat-release; then read vendor release version < /etc/redhat-release; if test $$vendor = CentOS; then nogroup='-n'; fi; fi; \ - if getent passwd ${RPKIRTR_USER} >/dev/null; \ - then \ - echo "You already have a user \"${RPKIRTR_USER}\", so I will use it."; \ - elif /usr/sbin/useradd -g ${RPKIRTR_GROUP} -M $$nogroup -d "${RPKIRTR_DIR}" -s /sbin/nologin -c "${RPKIRTR_GECOS}" ${RPKIRTR_USER}; \ - then \ - echo "Added user \"${RPKIRTR_USER}\"."; \ - else \ - echo "Adding user \"${RPKIRTR_USER}\" failed..."; \ - echo "Please create it, then try again."; \ - exit 1; \ - fi - usermod -a -G ${RPKIRTR_GROUP} ${RCYNIC_USER} + +# This all looks like a relic of the days when we still tried to support rcynic running in a chroot jail, which +# never really worked properly except on FreeBSD, and has since been overtaken by many other events. Do we +# still need this, even assuming anybody uses this installation instead of Debian packaging? +# +# Cleanup left for another day, but this looks pretty iffy. install-shared-libraries: .FORCE @echo "Copying required shared libraries" diff --git a/rp/rpki-rtr/rules.freebsd.mk b/rp/rpki-rtr/rules.freebsd.mk index f4d214a3..0f1546b2 100644 --- a/rp/rpki-rtr/rules.freebsd.mk +++ b/rp/rpki-rtr/rules.freebsd.mk @@ -18,7 +18,7 @@ install-listener: .FORCE @if /usr/bin/egrep -q "rpki-rtr[ ]+stream[ ]+tcp[ ]" /etc/inetd.conf; \ then \ echo "You already have an inetd.conf entry for rpki-rtr on TCPv4, so I will use it."; \ - elif echo >>/etc/inetd.conf "rpki-rtr stream tcp nowait rpkirtr /usr/local/bin/rpki-rtr rpki-rtr server /var/rcynic/rpki-rtr"; \ + elif echo >>/etc/inetd.conf "rpki-rtr stream tcp nowait rpki /usr/local/bin/rpki-rtr rpki-rtr server /var/rcynic/rpki-rtr"; \ then \ echo "Added rpki-rtr for TCPv4 to /etc/inetd.conf."; \ else \ @@ -28,7 +28,7 @@ install-listener: .FORCE @if /usr/bin/egrep -q "rpki-rtr[ ]+stream[ ]+tcp6[ ]" /etc/inetd.conf; \ then \ echo "You already have an inetd.conf entry for rpki-rtr on TCPv6, so I will use it."; \ - elif echo >>/etc/inetd.conf "rpki-rtr stream tcp6 nowait rpkirtr /usr/local/bin/rpki-rtr rpki-rtr server /var/rcynic/rpki-rtr"; \ + elif echo >>/etc/inetd.conf "rpki-rtr stream tcp6 nowait rpki /usr/local/bin/rpki-rtr rpki-rtr server /var/rcynic/rpki-rtr"; \ then \ echo "Added rpki-rtr for TCPv6 to /etc/inetd.conf."; \ else \ diff --git a/rp/rpki-rtr/rules.linux.mk b/rp/rpki-rtr/rules.linux.mk index d9b21590..bad35ace 100644 --- a/rp/rpki-rtr/rules.linux.mk +++ b/rp/rpki-rtr/rules.linux.mk @@ -19,7 +19,7 @@ ${DESTDIR}/etc/xinetd.d/rpki-rtr: print " protocol = tcp"; \ print " port = ${RPKI_RTR_PORT}"; \ print " wait = no"; \ - print " user = rpkirtr"; \ + print " user = rpki"; \ print " server = ${bindir}/${BIN}"; \ print " server_args = server /var/rcynic/rpki-rtr"; \ print "}"; \ |