RPKI Engine  1.0
irbe_cli.py (4092)
Go to the documentation of this file.
00001 """
00002 Command line IR back-end control program for rpkid and pubd.
00003 
00004 $Id: irbe_cli.py 4092 2011-11-14 10:47:25Z sra $
00005 
00006 Copyright (C) 2009--2010  Internet Systems Consortium ("ISC")
00007 
00008 Permission to use, copy, modify, and distribute this software for any
00009 purpose with or without fee is hereby granted, provided that the above
00010 copyright notice and this permission notice appear in all copies.
00011 
00012 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00013 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00014 AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00015 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00016 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00017 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00018 PERFORMANCE OF THIS SOFTWARE.
00019 
00020 Portions copyright (C) 2007--2008  American Registry for Internet Numbers ("ARIN")
00021 
00022 Permission to use, copy, modify, and distribute this software for any
00023 purpose with or without fee is hereby granted, provided that the above
00024 copyright notice and this permission notice appear in all copies.
00025 
00026 THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
00027 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00028 AND FITNESS.  IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
00029 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00030 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00031 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00032 PERFORMANCE OF THIS SOFTWARE.
00033 """
00034 
00035 import getopt, sys, textwrap
00036 import rpki.left_right, rpki.http, rpki.x509, rpki.config, rpki.log
00037 import rpki.publication, rpki.async
00038 
00039 pem_out = None
00040 
00041 class UsageWrapper(textwrap.TextWrapper):
00042   """
00043   Call interface around Python textwrap.Textwrapper class.
00044   """
00045 
00046   def __call__(self, *args):
00047     """
00048     Format arguments, with TextWrapper indentation.
00049     """
00050     return self.fill(textwrap.dedent(" ".join(args)))
00051 
00052 usage_fill = UsageWrapper(subsequent_indent = " " * 4)
00053 
00054 class reply_elt_mixin(object):
00055   """
00056   Protocol mix-in for printout of reply PDUs.
00057   """
00058 
00059   is_cmd = False
00060 
00061   def client_reply_decode(self):
00062     pass
00063 
00064   def client_reply_show(self):
00065     print self.element_name
00066     for i in self.attributes + self.elements:
00067       if getattr(self, i) is not None:
00068         print "  %s: %s" % (i, getattr(self, i))
00069 
00070 class cmd_elt_mixin(reply_elt_mixin):
00071   """
00072   Protocol mix-in for command line client element PDUs.
00073   """
00074 
00075   is_cmd = True
00076 
00077   ## @var excludes
00078   # XML attributes and elements that should not be allowed as command
00079   # line arguments.
00080   excludes = ()
00081 
00082   @classmethod
00083   def usage(cls):
00084     """
00085     Generate usage message for this PDU.
00086     """
00087     args = " ".join("--" + x + "=" for x in cls.attributes + cls.elements if x not in cls.excludes)
00088     bools = " ".join("--" + x for x in cls.booleans)
00089     if args and bools:
00090       return args + " " + bools
00091     else:
00092       return args or bools
00093 
00094   def client_getopt(self, argv):
00095     """
00096     Parse options for this class.
00097     """
00098     opts, argv = getopt.getopt(argv, "", [x + "=" for x in self.attributes + self.elements if x not in self.excludes] + list(self.booleans))
00099     for o, a in opts:
00100       o = o[2:]
00101       handler = getattr(self, "client_query_" + o, None)
00102       if handler is not None:
00103         handler(a)
00104       elif o in self.booleans:
00105         setattr(self, o, True)
00106       else:
00107         assert o in self.attributes
00108         setattr(self, o, a)
00109     return argv
00110 
00111   def client_query_bpki_cert(self, arg):
00112     """
00113     Special handler for --bpki_cert option.
00114     """
00115     self.bpki_cert = rpki.x509.X509(Auto_file = arg)
00116 
00117   def client_query_glue(self, arg):
00118     """
00119     Special handler for --bpki_glue option.
00120     """
00121     self.bpki_glue = rpki.x509.X509(Auto_file = arg)
00122 
00123   def client_query_bpki_cms_cert(self, arg):
00124     """
00125     Special handler for --bpki_cms_cert option.
00126     """
00127     self.bpki_cms_cert = rpki.x509.X509(Auto_file = arg)
00128 
00129   def client_query_cms_glue(self, arg):
00130     """
00131     Special handler for --bpki_cms_glue option.
00132     """
00133     self.bpki_cms_glue = rpki.x509.X509(Auto_file = arg)
00134 
00135 class cmd_msg_mixin(object):
00136   """
00137   Protocol mix-in for command line client message PDUs.
00138   """
00139 
00140   @classmethod
00141   def usage(cls):
00142     """
00143     Generate usage message for this PDU.
00144     """
00145     for k, v in cls.pdus.items():
00146       if v.is_cmd:
00147         print usage_fill(k, v.usage())
00148 
00149 # left-right protcol
00150 
00151 class self_elt(cmd_elt_mixin, rpki.left_right.self_elt):
00152   pass
00153 
00154 class bsc_elt(cmd_elt_mixin, rpki.left_right.bsc_elt):
00155 
00156   excludes = ("pkcs10_request",)
00157 
00158   def client_query_signing_cert(self, arg):
00159     """--signing_cert option."""
00160     self.signing_cert = rpki.x509.X509(Auto_file = arg)
00161 
00162   def client_query_signing_cert_crl(self, arg):
00163     """--signing_cert_crl option."""
00164     self.signing_cert_crl = rpki.x509.CRL(Auto_file = arg)
00165 
00166   def client_reply_decode(self):
00167     global pem_out
00168     if pem_out is not None and self.pkcs10_request is not None:
00169       if isinstance(pem_out, str):
00170         pem_out = open(pem_out, "w")
00171       pem_out.write(self.pkcs10_request.get_PEM())
00172 
00173 class parent_elt(cmd_elt_mixin, rpki.left_right.parent_elt):
00174   pass
00175 
00176 class child_elt(cmd_elt_mixin, rpki.left_right.child_elt):
00177   pass
00178 
00179 class repository_elt(cmd_elt_mixin, rpki.left_right.repository_elt):
00180   pass
00181 
00182 class list_published_objects_elt(cmd_elt_mixin, rpki.left_right.list_published_objects_elt):
00183   excludes = ("uri",)
00184 
00185 class list_received_resources_elt(cmd_elt_mixin, rpki.left_right.list_received_resources_elt):
00186   excludes = ("parent_handle", "notBefore", "notAfter", "uri", "sia_uri", "aia_uri", "asn", "ipv4", "ipv6")
00187 
00188 class report_error_elt(reply_elt_mixin, rpki.left_right.report_error_elt):
00189   pass
00190 
00191 class left_right_msg(cmd_msg_mixin, rpki.left_right.msg):
00192   pdus = dict((x.element_name, x)
00193               for x in (self_elt, bsc_elt, parent_elt, child_elt, repository_elt,
00194                         list_published_objects_elt, list_received_resources_elt, report_error_elt))
00195 
00196 class left_right_sax_handler(rpki.left_right.sax_handler):
00197   pdu = left_right_msg
00198 
00199 class left_right_cms_msg(rpki.left_right.cms_msg):
00200   saxify = left_right_sax_handler.saxify
00201 
00202 # Publication protocol
00203 
00204 class config_elt(cmd_elt_mixin, rpki.publication.config_elt):
00205 
00206   def client_query_bpki_crl(self, arg):
00207     """
00208     Special handler for --bpki_crl option.
00209     """
00210     self.bpki_crl = rpki.x509.CRL(Auto_file = arg)
00211 
00212 class client_elt(cmd_elt_mixin, rpki.publication.client_elt):
00213   pass
00214 
00215 class certificate_elt(cmd_elt_mixin, rpki.publication.certificate_elt):
00216   pass
00217 
00218 class crl_elt(cmd_elt_mixin, rpki.publication.crl_elt):
00219   pass
00220 
00221 class manifest_elt(cmd_elt_mixin, rpki.publication.manifest_elt):
00222   pass
00223 
00224 class roa_elt(cmd_elt_mixin, rpki.publication.roa_elt):
00225   pass
00226 
00227 class report_error_elt(reply_elt_mixin, rpki.publication.report_error_elt):
00228   pass
00229 
00230 class publication_msg(cmd_msg_mixin, rpki.publication.msg):
00231   pdus = dict((x.element_name, x)
00232               for x in (config_elt, client_elt, certificate_elt, crl_elt, manifest_elt, roa_elt, report_error_elt))
00233 
00234 class publication_sax_handler(rpki.publication.sax_handler):
00235   pdu = publication_msg
00236 
00237 class publication_cms_msg(rpki.publication.cms_msg):
00238   saxify = publication_sax_handler.saxify
00239 
00240 # Usage
00241 
00242 top_opts = ["config=", "help", "pem_out=", "quiet", "verbose"]
00243 
00244 def usage(code = 1):
00245   if __doc__ is not None:
00246     print __doc__.strip()
00247     print
00248   print "Usage:"
00249   print
00250   print "# Top-level options:"
00251   print usage_fill(*["--" + x for x in top_opts])
00252   print
00253   print "# left-right protocol:"
00254   left_right_msg.usage()
00255   print
00256   print "# publication protocol:"
00257   publication_msg.usage()
00258   sys.exit(code)
00259 
00260 # Main program
00261 
00262 rpki.log.init("irbe_cli")
00263 
00264 argv = sys.argv[1:]
00265 
00266 if not argv:
00267   usage(0)
00268 
00269 cfg_file = None
00270 verbose = True
00271 
00272 opts, argv = getopt.getopt(argv, "c:hpqv?", top_opts)
00273 for o, a in opts:
00274   if o in ("-?", "-h", "--help"):
00275     usage(0)
00276   elif o in ("-c", "--config"):
00277     cfg_file = a
00278   elif o in ("-p", "--pem_out"):
00279     pem_out = a
00280   elif o in ("-q", "--quiet"):
00281     verbose = False
00282   elif o in ("-v", "--verbose"):
00283     verbose = True
00284 
00285 if not argv:
00286   usage(1)
00287 
00288 cfg = rpki.config.parser(cfg_file, "irbe_cli")
00289 
00290 q_msg_left_right  = []
00291 q_msg_publication = []
00292 
00293 while argv:
00294   if argv[0] in left_right_msg.pdus:
00295     q_pdu = left_right_msg.pdus[argv[0]]()
00296     q_msg = q_msg_left_right
00297   elif argv[0] in publication_msg.pdus:
00298     q_pdu = publication_msg.pdus[argv[0]]()
00299     q_msg = q_msg_publication
00300   else:
00301     usage(1)
00302   argv = q_pdu.client_getopt(argv[1:])
00303   q_msg.append(q_pdu)
00304 
00305 if q_msg_left_right:
00306 
00307   class left_right_proto(object):
00308     cms_msg = left_right_cms_msg
00309     msg     = left_right_msg
00310 
00311   call_rpkid = rpki.async.sync_wrapper(rpki.http.caller(
00312     proto       = left_right_proto,
00313     client_key  = rpki.x509.RSA( Auto_file = cfg.get("rpkid-irbe-key")),
00314     client_cert = rpki.x509.X509(Auto_file = cfg.get("rpkid-irbe-cert")),
00315     server_ta   = rpki.x509.X509(Auto_file = cfg.get("rpkid-bpki-ta")),
00316     server_cert = rpki.x509.X509(Auto_file = cfg.get("rpkid-cert")),
00317     url         = cfg.get("rpkid-url"),
00318     debug       = verbose))
00319 
00320   call_rpkid(*q_msg_left_right)
00321 
00322 if q_msg_publication:
00323 
00324   class publication_proto(object):
00325     msg     = publication_msg
00326     cms_msg = publication_cms_msg
00327 
00328   call_pubd = rpki.async.sync_wrapper(rpki.http.caller(
00329     proto       = publication_proto,
00330     client_key  = rpki.x509.RSA( Auto_file = cfg.get("pubd-irbe-key")),
00331     client_cert = rpki.x509.X509(Auto_file = cfg.get("pubd-irbe-cert")),
00332     server_ta   = rpki.x509.X509(Auto_file = cfg.get("pubd-bpki-ta")),
00333     server_cert = rpki.x509.X509(Auto_file = cfg.get("pubd-cert")),
00334     url         = cfg.get("pubd-url"),
00335     debug       = verbose))
00336 
00337   call_pubd(*q_msg_publication)
 All Classes Namespaces Files Functions Variables Properties