RPKI Engine 1.0

pubd.py (3793)

Go to the documentation of this file.
00001 """
00002 RPKI publication engine.
00003 
00004 Usage: python pubd.py [ { -c | --config } configfile ]
00005                       [ { -h | --help } ]
00006                       [ { -p | --profile } outputfile ]
00007 
00008 $Id: pubd.py 3793 2011-04-27 04:34:52Z sra $
00009 
00010 Copyright (C) 2009--2010  Internet Systems Consortium ("ISC")
00011 
00012 Permission to use, copy, modify, and distribute this software for any
00013 purpose with or without fee is hereby granted, provided that the above
00014 copyright notice and this permission notice appear in all copies.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00017 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00018 AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00019 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00020 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00021 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00022 PERFORMANCE OF THIS SOFTWARE.
00023 
00024 Portions copyright (C) 2007--2008  American Registry for Internet Numbers ("ARIN")
00025 
00026 Permission to use, copy, modify, and distribute this software for any
00027 purpose with or without fee is hereby granted, provided that the above
00028 copyright notice and this permission notice appear in all copies.
00029 
00030 THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
00031 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00032 AND FITNESS.  IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
00033 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00034 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00035 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00036 PERFORMANCE OF THIS SOFTWARE.
00037 """
00038 
00039 import os, time, getopt, sys, re
00040 import rpki.resource_set, rpki.up_down, rpki.x509, rpki.sql
00041 import rpki.http, rpki.config, rpki.exceptions, rpki.relaxng
00042 import rpki.log, rpki.publication
00043 
00044 class main(object):
00045   """
00046   Main program for pubd.
00047   """
00048 
00049   def __init__(self):
00050 
00051     os.environ["TZ"] = "UTC"
00052     time.tzset()
00053 
00054     self.cfg_file = None
00055     self.profile = False
00056 
00057     opts, argv = getopt.getopt(sys.argv[1:], "c:dhp:?", ["config=", "debug", "help"])
00058     for o, a in opts:
00059       if o in ("-h", "--help", "-?"):
00060         print __doc__
00061         sys.exit(0)
00062       elif o in ("-c", "--config"):
00063         self.cfg_file = a
00064       elif o in ("-d", "--debug"):
00065         rpki.log.use_syslog = False
00066       elif o in ("-p", "--profile"):
00067         self.profile = a
00068     if argv:
00069       raise rpki.exceptions.CommandParseFailure, "Unexpected arguments %s" % argv
00070 
00071     rpki.log.init("pubd")
00072 
00073     if self.profile:
00074       import cProfile
00075       cProfile.run("self.main()", self.profile)
00076     else:
00077       self.main()
00078 
00079   def main(self):
00080 
00081     self.cfg = rpki.config.parser(self.cfg_file, "pubd")
00082 
00083     if self.profile:
00084       rpki.log.info("Running in profile mode with output to %s" % self.profile)
00085 
00086     self.cfg.set_global_flags()
00087 
00088     self.sql = rpki.sql.session(self.cfg)
00089 
00090     self.bpki_ta   = rpki.x509.X509(Auto_update = self.cfg.get("bpki-ta"))
00091     self.irbe_cert = rpki.x509.X509(Auto_update = self.cfg.get("irbe-cert"))
00092     self.pubd_cert = rpki.x509.X509(Auto_update = self.cfg.get("pubd-cert"))
00093     self.pubd_key  = rpki.x509.RSA( Auto_update = self.cfg.get("pubd-key"))
00094 
00095     self.http_server_host = self.cfg.get("server-host", "")
00096     self.http_server_port = int(self.cfg.get("server-port", "4434"))
00097 
00098     self.publication_base = self.cfg.get("publication-base", "publication/")
00099 
00100     self.publication_multimodule = self.cfg.getboolean("publication-multimodule", False)
00101 
00102     rpki.http.server(
00103       host                          = self.http_server_host,
00104       port                          = self.http_server_port,
00105       handlers                      = (("/control", self.control_handler),
00106                                        ("/client/", self.client_handler)))
00107 
00108   def handler_common(self, query, client, cb, certs, crl = None):
00109     """
00110     Common PDU handler code.
00111     """
00112 
00113     def done(r_msg):
00114       reply = rpki.publication.cms_msg().wrap(r_msg, self.pubd_key, self.pubd_cert, crl)
00115       self.sql.sweep()
00116       cb(reply)
00117 
00118     q_msg = rpki.publication.cms_msg(DER = query).unwrap(certs)
00119     q_msg.serve_top_level(self, client, done)
00120 
00121   def control_handler(self, query, path, cb):
00122     """
00123     Process one PDU from the IRBE.
00124     """
00125 
00126     def done(body):
00127       cb(200, body = body)
00128 
00129     rpki.log.trace()
00130     try:
00131       self.sql.ping()
00132       self.handler_common(query, None, done, (self.bpki_ta, self.irbe_cert))
00133     except (rpki.async.ExitNow, SystemExit):
00134       raise
00135     except Exception, data:
00136       rpki.log.traceback()
00137       cb(500, reason = "Unhandled exception %s" % data)
00138 
00139   client_url_regexp = re.compile("/client/([-A-Z0-9_/]+)$", re.I)
00140 
00141   def client_handler(self, query, path, cb):
00142     """
00143     Process one PDU from a client.
00144     """
00145 
00146     def done(body):
00147       cb(200, body = body)
00148 
00149     rpki.log.trace()
00150     try:
00151       self.sql.ping()
00152       match = self.client_url_regexp.search(path)
00153       if match is None:
00154         raise rpki.exceptions.BadContactURL, "Bad path: %s" % path
00155       client_handle = match.group(1)
00156       client = rpki.publication.client_elt.sql_fetch_where1(self, "client_handle = %s", (client_handle,))
00157       if client is None:
00158         raise rpki.exceptions.ClientNotFound, "Could not find client %s" % client_handle
00159       config = rpki.publication.config_elt.fetch(self)
00160       if config is None or config.bpki_crl is None:
00161         raise rpki.exceptions.CMSCRLNotSet
00162       self.handler_common(query, client, done, (self.bpki_ta, client.bpki_cert, client.bpki_glue), config.bpki_crl)
00163     except (rpki.async.ExitNow, SystemExit):
00164       raise
00165     except Exception, data:
00166       rpki.log.traceback()
00167       cb(500, reason = "Could not process PDU: %s" % data)
 All Classes Namespaces Files Functions Variables