RPKI Engine 1.0
|
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)