diff options
author | Rob Austein <sra@hactrn.net> | 2010-03-11 04:13:54 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2010-03-11 04:13:54 +0000 |
commit | 6cda9612ddf84c8f642e627c2d4c172eb6ce5bca (patch) | |
tree | 790595fe7a93dc2adb7a3294f5912188a92678fd /myrpki.rototill | |
parent | 179c68aed72e9a3f4aab6915c4e693b0020b6024 (diff) |
A start at internal doc.
svn path=/myrpki.rototill/myrpki.py; revision=3073
Diffstat (limited to 'myrpki.rototill')
-rw-r--r-- | myrpki.rototill/myrpki.py | 203 |
1 files changed, 118 insertions, 85 deletions
diff --git a/myrpki.rototill/myrpki.py b/myrpki.rototill/myrpki.py index 7946d005..7d039e89 100644 --- a/myrpki.rototill/myrpki.py +++ b/myrpki.rototill/myrpki.py @@ -6,70 +6,31 @@ provide a saner user interface is more urgent than internal code prettiness at the moment. In the long run, 90% of the code in this file probably ought to move to well-designed library modules. -The rest of the documentation in this module comment is lifted from -the previous scripts, and needs revision. Then again, all the -commands in this tool need documenting too.... - -=== - -Read an OpenSSL-style config file and a bunch of .csv files to find -out about parents and children and resources and ROA requests, oh my. -Run OpenSSL command line tool to construct BPKI certificates, -including cross-certification of other entities' BPKI certificates. - -Package up all of the above as a single XML file which user can then -ship off to the IRBE. If an XML file already exists, check it for -data coming back from the IRBE (principally PKCS #10 requests for our -BSC) and update it with current data. - -The general idea here is that this one XML file contains all of the -data that needs to be exchanged as part of ordinary update operations; -each party updates it as necessary, then ships it to the other via -some secure channel: carrier pigeon, USB stick, gpg-protected email, -we don't really care. - -This one program is written a little differently from all the other -Python RPKI programs. This one program is intended to run as a -stand-alone script, without the other programs present. It does -require a reasonably up-to-date version of the OpenSSL command line -tool (the one built as a side effect of building rcynic will do), but -it does -not- require POW or any Python libraries beyond what ships -with Python 2.5. So this script uses xml.etree from the Python -standard libraries instead of lxml.etree, which sacrifices XML schema -validation support in favor of portability, and so forth. - -To make things a little weirder, as a convenience to IRBE operators, -this script can itself be loaded as a Python module and invoked as -part of another program. This requires a few minor contortions, but -avoids duplicating common code. - -=== - -IRBE-side stuff for myrpki tools. - -The basic model here is that each entity with resources to certify -runs the myrpki tool, but not all of them necessarily run their own -RPKi engines. The entities that do run RPKI engines get data from the -entities they host via the XML files output by the myrpki tool. Those -XML files are the input to this script, which uses them to do all the -work of constructing certificates, populating SQL databases, and so -forth. A few operations (eg, BSC construction) generate data which -has to be shipped back to the resource holder, which we do by updating -the same XML file. - -In essence, the XML files are a sneakernet (or email, or carrier -pigeon) communication channel between the resource holders and the -RPKI engine operators. - -As a convenience, for the normal case where the RPKI engine operator -is itself a resource holder, this script also runs the myrpki script -directly to process the RPKI engine operator's own resources. - -Note that, due to the back and forth nature of some of these -operations, it may take several cycles for data structures to stablize -and everything to reach a steady state. This is normal. - -==== +Overall goal here is to build up the configuration necessary to run +rpkid and friends, by reading a config file, a collection of .CSV +files, and the results of a few out-of-band XML setup messages +exchanged with one's parents, children, and so forth. + +The config file is in an OpenSSL-compatible format, the CSV files are +simple tab-delimited text. The XML files are all generated by this +program, either the local instance or an instance being run by another +player in the system; the mechanism used to exchange these setup +messages is outside the scope of this program, feel free to use +PGP-signed mail, a web interface (not provided), USB stick, carrier +pigeons, whatever works. + +With one exception, the commands in this program avoid using any +third-party Python code other than the rpki libraries themselves; with +the same one exception, all OpenSSL work is done with the OpenSSL +command line tool (the one built as a side effect of building rcynic +will do, if your platform has no system copy or the system copy is too +old). This is all done in an attempt to make the code more portable, +so one can run most of the RPKI back end software on a laptop or +whatever. The one exception is the configure_daemons command, which +must, of necessity, use the same communication libraries as the +daemons with which it is conversing. So that one command will not +work if the correct Python modules are not available. + $Id$ @@ -794,7 +755,7 @@ def etree_read(filename, verbose = True, validate = True): class main(rpki.cli.Cmd): - prompt = "setup> " + prompt = "myrpki> " completedefault = rpki.cli.Cmd.filename_complete @@ -848,6 +809,13 @@ class main(rpki.cli.Cmd): def do_initialize(self, arg): + """ + Initialize an RPKI installation. This command reads the + configuration file, creates the BPKI and EntityDB directories, + generates the initial BPKI certificates, and creates an XML file + describing the resource-holding aspect of this RPKI installation. + """ + if arg: raise RuntimeError, "This command takes no arguments" @@ -920,7 +888,15 @@ class main(rpki.cli.Cmd): etree_write(e, self.entitydb("repositories", "%s.xml" % self.handle)) - def do_answer_child(self, arg): + def do_configure_child(self, arg): + """ + Configure a new child of this RPKI entity, given the child's XML + identity file as an input. This command extracts the child's data + from the XML, cross-certifies the child's resource-holding BPKI + certificate, and generates an XML file describing the relationship + between the child and this parent, including this parent's BPKI + data and up-down protocol service URI. + """ child_handle = None @@ -990,7 +966,17 @@ class main(rpki.cli.Cmd): etree_write(e, self.entitydb("children", "%s.xml" % child_handle)) - def do_process_parent_answer(self, arg): + def do_configure_parent(self, arg): + """ + Configure a new parent of this RPKI entity, given the output of + the parent's configure_child command as input. This command reads + the parent's response XML, extracts the parent's BPKI and service + URI information, cross-certifies the parent's BPKI data into this + entity's BPKI, and checks for offers or hints of publication + service. If a publication offer or hint is present, this command + generates a request-for-service message to that repository, in + case the user wants to avail herself of the hint or off. + """ parent_handle = None @@ -1027,7 +1013,14 @@ class main(rpki.cli.Cmd): print "Couldn't find repository offer or hint" - def do_answer_repository_client(self, arg): + def do_configure_publication_client(self, arg): + """ + Configure publication server to know about a new client, given the + client's request-for-service message as input. This command reads + the client's request for service, cross-certifies the client's + BPKI data, and generates a response message containing the + repository's BPKI data and service URI. + """ sia_base = None @@ -1099,7 +1092,15 @@ class main(rpki.cli.Cmd): etree_write(e, self.entitydb("pubclients", "%s.xml" % client_handle.replace("/", "."))) - def do_process_repository_answer(self, arg): + def do_configure_repository(self, arg): + """ + Configure a publication repository for this RPKI entity, given the + repository's response to our request-for-service message as input. + This command reads the repository's response, extracts and + cross-certifies the BPKI data and service URI, and links the + repository data with the corresponding parent data in our local + database. + """ argv = arg.split() @@ -1120,7 +1121,8 @@ class main(rpki.cli.Cmd): def myrpki_main(self): """ - Main program of old myrpki.py script. + Main program of old myrpki.py script. This remains separate + because it's called from more than one place. """ roa_csv_file = self.cfg.get("roa_csv") @@ -1172,28 +1174,63 @@ class main(rpki.cli.Cmd): etree_write(e, xml_filename) - def do_myrpki(self, arg): + def do_configure_resources(self, arg): + """ + Read CSV files and all the descriptions of parents and children + that we've built up, package the result up as a single XML file to + be shipped to a hosting rpkid. + """ + if arg: raise RuntimeError, "Unexpected argument %r" % arg self.myrpki_main() - def myirbe_main(self, argv = []): + def do_configure_daemons(self, arg): """ - Main program of old myirbe.py script. + Configure RPKI daemons with the data built up by the other + commands in this program. + + The basic model here is that each entity with resources to certify + runs the myrpki tool, but not all of them necessarily run their + own RPKI engines. The entities that do run RPKI engines get data + from the entities they host via the XML files output by the + configure_resources command. Those XML files are the input to + this command, which uses them to do all the work of configuring + daemons, populating SQL databases, and so forth. A few operations + (eg, BSC construction) generate data which has to be shipped back + to the resource holder, which we do by updating the same XML file. + + In essence, the XML files are a sneakernet (or email, or carrier + pigeon) communication channel between the resource holders and the + RPKI engine operators. + + As a convenience, for the normal case where the RPKI engine + operator is itself a resource holder, this command in effect runs + the configure_resources command automatically to process the RPKI + engine operator's own resources. + + Note that, due to the back and forth nature of some of these + operations, it may take several cycles for data structures to stablize + and everything to reach a steady state. This is normal. """ - import rpki.https, rpki.resource_set, rpki.relaxng, rpki.exceptions - import rpki.left_right, rpki.x509, rpki.async + argv = arg.split() - # Silence warning while loading MySQLdb in Python 2.6, sigh - if hasattr(warnings, "catch_warnings"): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) + try: + import rpki.https, rpki.resource_set, rpki.relaxng, rpki.exceptions + import rpki.left_right, rpki.x509, rpki.async + if hasattr(warnings, "catch_warnings"): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + import MySQLdb + else: import MySQLdb - else: - import MySQLdb + + except ImportError, e: + print "Sorry, you appear to be missing some of the Python modules needed to run this command" + print "[Error: %r]" % e def findbase64(tree, name, b64type = rpki.x509.X509): x = tree.findtext(name) @@ -1572,10 +1609,6 @@ class main(rpki.cli.Cmd): db.close() - - def do_myirbe(self, arg): - self.myirbe_main(arg.split()) - if __name__ == "__main__": |