diff options
Diffstat (limited to 'rpki')
34 files changed, 395 insertions, 224 deletions
diff --git a/rpki/POW/__init__.py b/rpki/POW/__init__.py index 7fb445e0..7f18b548 100644 --- a/rpki/POW/__init__.py +++ b/rpki/POW/__init__.py @@ -17,7 +17,7 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# pylint: disable=W0622,W0401 +# pylint: disable=W0401,W0622 from rpki.POW._POW import * from rpki.POW._POW import __doc__ diff --git a/rpki/adns.py b/rpki/adns.py index b0f235e7..365e9803 100644 --- a/rpki/adns.py +++ b/rpki/adns.py @@ -22,6 +22,8 @@ Basic asynchronous DNS code, using asyncore and Bob Halley's excellent dnspython package. """ +# pylint: skip-file + import sys import time import socket diff --git a/rpki/cli.py b/rpki/cli.py index 9440ecb2..0fdccf8b 100644 --- a/rpki/cli.py +++ b/rpki/cli.py @@ -82,12 +82,12 @@ class Cmd(cmd.Cmd): self.last_command_failed = True return False - def do_EOF(self, arg): # pylint: disable=W0613 + def do_EOF(self, arg): if self.EOF_exits_command_loop and self.prompt: print return self.EOF_exits_command_loop - def do_exit(self, arg): # pylint: disable=W0613,R0201 + def do_exit(self, arg): """ Exit program. """ @@ -106,7 +106,7 @@ class Cmd(cmd.Cmd): if self.emptyline_repeats_last_command: cmd.Cmd.emptyline(self) - def filename_complete(self, text, line, begidx, endidx): # pylint: disable=W0613,R0201 + def filename_complete(self, text, line, begidx, endidx): """ Filename completion handler, with hack to restore what I consider the normal (bash-like) behavior when one hits the completion key diff --git a/rpki/django_settings/common.py b/rpki/django_settings/common.py index 13dcdcef..4aa3e119 100644 --- a/rpki/django_settings/common.py +++ b/rpki/django_settings/common.py @@ -57,6 +57,8 @@ if os.getenv("RPKI_DJANGO_DEBUG") == "yes": class DatabaseConfigurator(object): default_sql_engine = "mysql" + cfg = None + section = None def configure(self, cfg, section): # pylint: disable=W0621 self.cfg = cfg diff --git a/rpki/django_settings/gui.py b/rpki/django_settings/gui.py index 4e9ac0f3..2c664f91 100644 --- a/rpki/django_settings/gui.py +++ b/rpki/django_settings/gui.py @@ -20,7 +20,7 @@ This module contains GUI-specific configuration settings for Django libraries. # Pull in the irdb configuration, which in turn pulls in the common configuration. -from .irdb import * # pylint: disable=W0401 +from .irdb import * # pylint: disable=W0401,W0614 __version__ = "$Id$" diff --git a/rpki/django_settings/irdb.py b/rpki/django_settings/irdb.py index 2a49739b..da42a111 100644 --- a/rpki/django_settings/irdb.py +++ b/rpki/django_settings/irdb.py @@ -21,7 +21,7 @@ the GUI code also uses this but adds a bunch of other stuff, thus has its own settings file. """ -from .common import * # pylint: disable=W0401 +from .common import * # pylint: disable=W0401,W0614 __version__ = "$Id$" diff --git a/rpki/django_settings/pubd.py b/rpki/django_settings/pubd.py index 0df0ddb9..6bd9fdc0 100644 --- a/rpki/django_settings/pubd.py +++ b/rpki/django_settings/pubd.py @@ -19,7 +19,7 @@ This module contains configuration settings for Django libraries for the pubd program. """ -from .common import * # pylint: disable=W0401 +from .common import * # pylint: disable=W0401,W0614 __version__ = "$Id$" diff --git a/rpki/django_settings/rpkid.py b/rpki/django_settings/rpkid.py index 70987315..e34518bb 100644 --- a/rpki/django_settings/rpkid.py +++ b/rpki/django_settings/rpkid.py @@ -19,7 +19,7 @@ This module contains configuration settings for Django libraries for the rpkid program. """ -from .common import * # pylint: disable=W0401 +from .common import * # pylint: disable=W0401,W0614 __version__ = "$Id$" diff --git a/rpki/exceptions.py b/rpki/exceptions.py index cbdb9f83..d66ad00c 100644 --- a/rpki/exceptions.py +++ b/rpki/exceptions.py @@ -241,3 +241,9 @@ class UnexpectedUpDownResponse(RPKI_Exception): class BadContentType(RPKI_Exception): "Bad HTTP Content-Type." + +class ResourceClassMismatch(RPKI_Exception): + "Up-down resource class does not match." + +class IRDBExpired(RPKI_Exception): + "Back-end database record has expired." diff --git a/rpki/fields.py b/rpki/fields.py index f8ee8789..06f71259 100644 --- a/rpki/fields.py +++ b/rpki/fields.py @@ -143,7 +143,7 @@ class DERField(models.BinaryField): del kwargs["default"] return name, path, args, kwargs - def from_db_value(self, value, expression, connection, context): # pylint: disable=W0613 + def from_db_value(self, value, expression, connection, context): if value is not None: value = self.rpki_type(DER = str(value)) return value diff --git a/rpki/irdb/__init__.py b/rpki/irdb/__init__.py index 25dedfe3..64b0ea28 100644 --- a/rpki/irdb/__init__.py +++ b/rpki/irdb/__init__.py @@ -19,7 +19,5 @@ Django really wants its models packaged up in a "models" module within a Python package, so humor it. """ -# pylint: disable=W0401 - from rpki.irdb.zookeeper import Zookeeper from rpki.irdb.router import DBContextRouter, database diff --git a/rpki/irdb/models.py b/rpki/irdb/models.py index 4ff5734a..a663c36f 100644 --- a/rpki/irdb/models.py +++ b/rpki/irdb/models.py @@ -24,7 +24,7 @@ to be usable by command line programs and other scripts, not just Django GUI code, so be careful. """ -# pylint: disable=W0232,C1001 +# pylint: disable=W5101,W5103 import django.db.models import rpki.x509 @@ -98,6 +98,8 @@ class CertificateManager(django.db.models.Manager): anything has changed. """ + # pylint: disable=E1101 + changed = False try: @@ -120,6 +122,7 @@ class CertificateManager(django.db.models.Manager): return obj, changed def _get_or_certify_keys(self, kwargs): + # pylint: disable=E1101,W0212 assert len(self.model._meta.unique_together) == 1 return dict((k, kwargs[k]) for k in self.model._meta.unique_together[0]) @@ -154,6 +157,10 @@ class CA(django.db.models.Model): class Meta: abstract = True + @property + def subject_name(self): + raise NotImplementedError + def avow(self): if self.private_key is None: self.private_key = rpki.x509.RSA.generate(quiet = True) @@ -245,16 +252,17 @@ class Certificate(django.db.models.Model): unique_together = ("issuer", "handle") def revoke(self): - self.issuer.revoke(self) + self.issuer.revoke(self) # pylint: disable=E1101 class CrossCertification(Certificate): handle = HandleField() - ta = CertificateField() + ta = CertificateField() # pylint: disable=C0103 class Meta: abstract = True def avow(self): + # pylint: disable=E1101 self.certificate = self.issuer.certify( subject_name = self.ta.getSubject(), subject_key = self.ta.getPublicKey(), @@ -305,6 +313,7 @@ class EECertificate(Certificate): abstract = True def avow(self): + # pylint: disable=E1101 if self.private_key is None: self.private_key = rpki.x509.RSA.generate(quiet = True) self.certificate = self.issuer.certify( @@ -350,6 +359,7 @@ class BSC(Certificate): pkcs10 = PKCS10Field() def avow(self): + # pylint: disable=E1101 self.certificate = self.issuer.certify( subject_name = self.pkcs10.getSubject(), subject_key = self.pkcs10.getPublicKey(), @@ -365,6 +375,9 @@ class ResourceSet(django.db.models.Model): class Meta: abstract = True + def _select_resource_bag(self): + return (), () + @property def resource_bag(self): raw_asn, raw_net = self._select_resource_bag() @@ -491,8 +504,8 @@ class EECertificateRequest(ResourceSet): issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "ee_certificate_requests") pkcs10 = PKCS10Field() gski = django.db.models.CharField(max_length = 27) - cn = django.db.models.CharField(max_length = 64) - sn = django.db.models.CharField(max_length = 64) + cn = django.db.models.CharField(max_length = 64) # pylint: disable=C0103 + sn = django.db.models.CharField(max_length = 64) # pylint: disable=C0103 eku = django.db.models.TextField(null = True) def _select_resource_bag(self): diff --git a/rpki/irdb/router.py b/rpki/irdb/router.py index 3cbd52f9..a2ba81c7 100644 --- a/rpki/irdb/router.py +++ b/rpki/irdb/router.py @@ -26,6 +26,8 @@ passing database names everywhere. Using a database router accomplishes this. """ +# pylint: disable=W0212 + class DBContextRouter(object): """ A Django database router for use with multiple IRDBs. @@ -81,6 +83,7 @@ class database(object): self.name = name self.on_entry = on_entry self.on_exit = on_exit + self.former = None def __enter__(self): if self.on_entry is not None: diff --git a/rpki/irdb/zookeeper.py b/rpki/irdb/zookeeper.py index 514ff683..5508d64a 100644 --- a/rpki/irdb/zookeeper.py +++ b/rpki/irdb/zookeeper.py @@ -20,8 +20,6 @@ Management code for the IRDB. """ -# pylint: disable=W0612,C0325 - import os import copy @@ -135,7 +133,7 @@ class PEM_writer(object): try: if compare and pem == open(filename, "r").read(): return - except: # pylint: disable=W0702 + except: pass tempname += ".%s.tmp" % os.getpid() mode = 0400 if filename.endswith(".key") else 0444 @@ -295,7 +293,7 @@ class Zookeeper(object): """ if self.run_rpkid or self.run_pubd: - server_ca, created = rpki.irdb.models.ServerCA.objects.get_or_certify() + server_ca = rpki.irdb.models.ServerCA.objects.get_or_certify()[0] rpki.irdb.models.ServerEE.objects.get_or_certify(issuer = server_ca, purpose = "irbe") if self.run_rpkid: @@ -320,7 +318,7 @@ class Zookeeper(object): resource-holding BPKI idenity if needed. """ - resource_ca, created = rpki.irdb.models.ResourceHolderCA.objects.get_or_certify(handle = self.handle) + rpki.irdb.models.ResourceHolderCA.objects.get_or_certify(handle = self.handle) return self.generate_identity() @@ -476,7 +474,7 @@ class Zookeeper(object): @staticmethod - def _compose_left_right_query(): + def compose_left_right_query(): """ Compose top level element of a left-right query. """ @@ -506,7 +504,7 @@ class Zookeeper(object): """ if self.run_rpkid: - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() for ca in rpki.irdb.models.ResourceHolderCA.objects.all(): q_pdu = SubElement(q_msg, rpki.left_right.tag_tenant, @@ -598,11 +596,11 @@ class Zookeeper(object): self.log("Child calls itself %r, we call it %r" % (x.get("child_handle"), child_handle)) - child, created = rpki.irdb.models.Child.objects.get_or_certify( + child = rpki.irdb.models.Child.objects.get_or_certify( issuer = self.resource_ca, handle = child_handle, ta = rpki.x509.X509(Base64 = x.findtext(tag_oob_child_bpki_ta)), - valid_until = valid_until) + valid_until = valid_until)[0] return self.generate_parental_response(child), child_handle @@ -641,7 +639,7 @@ class Zookeeper(object): else: proposed_sia_base = repo.sia_base + child.handle + "/" - referral_cert, created = rpki.irdb.models.Referral.objects.get_or_certify(issuer = self.resource_ca) + referral_cert = rpki.irdb.models.Referral.objects.get_or_certify(issuer = self.resource_ca)[0] auth = rpki.x509.SignedReferral() auth.set_content(B64Element(None, tag_oob_authorization, child.ta, nsmap = oob_nsmap, version = oob_version, @@ -704,7 +702,7 @@ class Zookeeper(object): self.log("Parent calls itself %r, we call it %r" % (x.get("parent_handle"), parent_handle)) self.log("Parent calls us %r" % x.get("child_handle")) - parent, created = rpki.irdb.models.Parent.objects.get_or_certify( + parent = rpki.irdb.models.Parent.objects.get_or_certify( issuer = self.resource_ca, handle = parent_handle, child_handle = x.get("child_handle"), @@ -713,7 +711,7 @@ class Zookeeper(object): ta = rpki.x509.X509(Base64 = x.findtext(tag_oob_parent_bpki_ta)), repository_type = repository_type, referrer = referrer, - referral_authorization = referral_authorization) + referral_authorization = referral_authorization)[0] return self.generate_repository_request(parent), parent_handle @@ -761,6 +759,8 @@ class Zookeeper(object): and service URI. """ + # pylint: disable=E1124 + x = etree_read(filename) if x.tag != tag_oob_publisher_request: @@ -825,11 +825,11 @@ class Zookeeper(object): self.log("Client calls itself %r, we call it %r" % ( x.get("publisher_handle"), client_handle)) - client, created = rpki.irdb.models.Client.objects.get_or_certify( + client = rpki.irdb.models.Client.objects.get_or_certify( issuer = self.server_ca, handle = client_handle, ta = client_ta, - sia_base = sia_base) + sia_base = sia_base)[0] return self.generate_repository_response(client), client_handle @@ -900,11 +900,11 @@ class Zookeeper(object): turtles = [] for parent in self.resource_ca.parents.all(): try: - _ = parent.repository + _ = parent.repository # pylint: disable=W0612 except rpki.irdb.models.Repository.DoesNotExist: turtles.append(parent) try: - _ = self.resource_ca.rootd.repository + _ = self.resource_ca.rootd.repository # pylint: disable=W0612 except rpki.irdb.models.Repository.DoesNotExist: turtles.append(self.resource_ca.rootd) except rpki.irdb.models.Rootd.DoesNotExist: @@ -992,11 +992,11 @@ class Zookeeper(object): raise else: for prefix in rset(",".join(prefixes)): - obj, created = rpki.irdb.models.ChildNet.objects.get_or_create( + obj = rpki.irdb.models.ChildNet.objects.get_or_create( child = child, start_ip = str(prefix.min), end_ip = str(prefix.max), - version = version) + version = version)[0] primary_keys.append(obj.pk) q = rpki.irdb.models.ChildNet.objects @@ -1028,10 +1028,10 @@ class Zookeeper(object): raise else: for asn in rpki.resource_set.resource_set_as(",".join(asns)): - obj, created = rpki.irdb.models.ChildASN.objects.get_or_create( + obj = rpki.irdb.models.ChildASN.objects.get_or_create( child = child, start_as = str(asn.min), - end_as = str(asn.max)) + end_as = str(asn.max))[0] primary_keys.append(obj.pk) q = rpki.irdb.models.ChildASN.objects @@ -1131,7 +1131,7 @@ class Zookeeper(object): def _rpkid_tenant_control(self, *bools): assert all(isinstance(b, str) for b in bools) - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() q_pdu = SubElement(q_msg, rpki.left_right.tag_tenant, action = "set", tenant_handle = self.handle) for b in bools: q_pdu.set(b, "yes") @@ -1200,7 +1200,7 @@ class Zookeeper(object): """ if self.run_rpkid: - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() for ca in rpki.irdb.models.ResourceHolderCA.objects.all(): SubElement(q_msg, rpki.left_right.tag_tenant, action = "set", tenant_handle = ca.handle, clear_replay_protection = "yes") @@ -1324,6 +1324,8 @@ class Zookeeper(object): CA to the end of whatever other commands this method generates. """ + # pylint: disable=C0330 + # We can use a single BSC for everything -- except BSC key # rollovers. Drive off that bridge when we get to it. @@ -1349,7 +1351,7 @@ class Zookeeper(object): # See what rpkid already has on file for this entity. - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() SubElement(q_msg, rpki.left_right.tag_tenant, action = "get", tenant_handle = ca.handle) SubElement(q_msg, rpki.left_right.tag_bsc, action = "list", tenant_handle = ca.handle) SubElement(q_msg, rpki.left_right.tag_repository, action = "list", tenant_handle = ca.handle) @@ -1371,11 +1373,11 @@ class Zookeeper(object): child_pdus = dict((r_pdu.get("child_handle"), r_pdu) for r_pdu in r_msg.getiterator(rpki.left_right.tag_child)) - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() - tenant_cert, created = rpki.irdb.models.HostedCA.objects.get_or_certify( + tenant_cert = rpki.irdb.models.HostedCA.objects.get_or_certify( issuer = self.server_ca, - hosted = ca) + hosted = ca)[0] # There should be exactly one <tenant/> object per hosted entity, by definition @@ -1421,15 +1423,15 @@ class Zookeeper(object): if r_pdu.get("action") == "list") bsc_pdu = bsc_pdus.pop(bsc_handle, None) - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() bsc_pkcs10 = bsc_pdu.find(rpki.left_right.tag_pkcs10_request) assert bsc_pkcs10 is not None - bsc, created = rpki.irdb.models.BSC.objects.get_or_certify( + bsc = rpki.irdb.models.BSC.objects.get_or_certify( issuer = ca, handle = bsc_handle, - pkcs10 = rpki.x509.PKCS10(Base64 = bsc_pkcs10.text)) + pkcs10 = rpki.x509.PKCS10(Base64 = bsc_pkcs10.text))[0] if (bsc_pdu.findtext(rpki.left_right.tag_signing_cert, "").decode("base64") != bsc.certificate.get_DER() or bsc_pdu.findtext(rpki.left_right.tag_signing_cert_crl, "").decode("base64") != ca.latest_crl.get_DER()): @@ -1586,6 +1588,8 @@ class Zookeeper(object): related to pubd should call this when they're done. """ + # pylint: disable=C0330 + # If we're not running pubd, the rest of this is a waste of time if not self.run_pubd: @@ -1652,7 +1656,7 @@ class Zookeeper(object): inside a Django commit wrapper. """ - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() SubElement(q_msg, rpki.left_right.tag_tenant, action = "list") r_msg = self.call_rpkid(q_msg) @@ -1660,7 +1664,7 @@ class Zookeeper(object): ca_handles = set(ca.handle for ca in rpki.irdb.models.ResourceHolderCA.objects.all()) assert ca_handles <= tenant_handles - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() for handle in (tenant_handles - ca_handles): SubElement(q_msg, rpki.left_right.tag_tenant, action = "destroy", tenant_handle = handle) diff --git a/rpki/irdbd.py b/rpki/irdbd.py index 91859f5d..44628886 100644 --- a/rpki/irdbd.py +++ b/rpki/irdbd.py @@ -156,6 +156,8 @@ class main(object): self.cfg = rpki.config.parser(set_filename = args.config, section = "irdbd") self.cfg.set_global_flags() + self.cms_timestamp = None + if not args.foreground: rpki.daemonize.daemon(pidfile = args.pidfile) @@ -188,8 +190,6 @@ class main(object): self.http_server_host = self.cfg.get("server-host", "") self.http_server_port = self.cfg.getint("server-port") - self.cms_timestamp = None - rpki.http_simple.server( host = self.http_server_host, port = self.http_server_port, diff --git a/rpki/log.py b/rpki/log.py index 8afee4ba..dd3923a7 100644 --- a/rpki/log.py +++ b/rpki/log.py @@ -96,12 +96,12 @@ class Formatter(object): try: if not self.is_syslog: yield time.strftime("%Y-%m-%d %H:%M:%S ", time.gmtime(record.created)) - except: # pylint: disable=W0702 + except: yield "[$!$Time format failed]" try: yield "%s[%d]: " % (self.ident, record.process) - except: # pylint: disable=W0702 + except: yield "[$!$ident format failed]" try: @@ -111,12 +111,12 @@ class Formatter(object): yield repr(record.context) + " " except AttributeError: pass - except: # pylint: disable=W0702 + except: yield "[$!$context format failed]" try: yield record.getMessage() - except: # pylint: disable=W0702 + except: yield "[$!$record.getMessage() failed]" try: @@ -129,7 +129,7 @@ class Formatter(object): lines.insert(0, "\n") for line in lines: yield line - except: # pylint: disable=W0702 + except: yield "[$!$exception formatting failed]" @@ -218,8 +218,6 @@ def init(ident = None, args = None): Default logging destination is stderr if "args" is not specified. """ - # pylint: disable=E1103 - if ident is None: ident = os.path.basename(sys.argv[0]) @@ -227,12 +225,12 @@ def init(ident = None, args = None): args = argparse.Namespace(log_level = logging.WARNING, log_handler = logging.StreamHandler) - handler = args.log_handler() + handler = args.log_handler() # pylint: disable=E1101 handler.setFormatter(Formatter(ident, handler)) root_logger = logging.getLogger() root_logger.addHandler(handler) - root_logger.setLevel(args.log_level) + root_logger.setLevel(args.log_level) # pylint: disable=E1101 if ident and have_setproctitle and use_setproctitle: if proctitle_extra: @@ -262,8 +260,6 @@ def log_repr(obj, *tokens): IDs as needed, includes tenant_handle when available. """ - # pylint: disable=W0702 - words = ["%s.%s" % (obj.__class__.__module__, obj.__class__.__name__)] try: words.append("{%s}" % obj.tenant.tenant_handle) diff --git a/rpki/oids.py b/rpki/oids.py index abc928bc..b27be6f3 100644 --- a/rpki/oids.py +++ b/rpki/oids.py @@ -88,8 +88,7 @@ for _sym in dir(): raise ValueError("Bad OID definition: %s = %r" % (_sym, _val)) _oid2name[_val] = _sym.replace("_", "-") -# pylint: disable=W0631 -del _sym +del _sym # pylint: disable=W0631 del _val def oid2name(oid): diff --git a/rpki/old_irdbd.py b/rpki/old_irdbd.py index 4ebb33b0..b2dd42bd 100644 --- a/rpki/old_irdbd.py +++ b/rpki/old_irdbd.py @@ -25,6 +25,8 @@ and perhaps still useful as a minimal example. This does NOT work with the GUI, rpkic, or any of the other more recent tools. """ +# pylint: skip-file + import os import time import logging diff --git a/rpki/pubdb/models.py b/rpki/pubdb/models.py index 46dcf493..43600a5e 100644 --- a/rpki/pubdb/models.py +++ b/rpki/pubdb/models.py @@ -31,6 +31,8 @@ import rpki.relaxng logger = logging.getLogger(__name__) +# pylint: disable=W5101 + # Some of this probably ought to move into a rpki.rrdp module. rrdp_xmlns = rpki.relaxng.rrdp.xmlns @@ -93,6 +95,8 @@ class Session(models.Model): Construct a new delta associated with this session. """ + # pylint: disable=W0201 + delta = Delta(session = self, serial = self.serial + 1, expires = expires) @@ -261,7 +265,10 @@ class Delta(models.Model): def withdraw(self, client, uri, obj_hash): - obj = client.publishedobject_set.get(session = self.session, uri = uri) + try: + obj = client.publishedobject_set.get(session = self.session, uri = uri) + except rpki.pubdb.models.PublishedObject.DoesNotExist: + raise rpki.exceptions.NoObjectAtURI("No published object found at %s" % uri) if obj.hash != obj_hash: raise rpki.exceptions.DifferentObjectAtURI("Found different object at %s (old %s, new %s)" % (uri, obj.hash, obj_hash)) logger.debug("Withdrawing %s", uri) @@ -308,6 +315,6 @@ class PublishedObject(models.Model): client = models.ForeignKey(Client) session = models.ForeignKey(Session) - class Meta: # pylint: disable=C1001,W0232 + class Meta: unique_together = (("session", "hash"), ("session", "uri")) diff --git a/rpki/rcynic.py b/rpki/rcynic.py index 76d5d183..c6ad60d5 100644 --- a/rpki/rcynic.py +++ b/rpki/rcynic.py @@ -43,9 +43,10 @@ class rcynic_object(object): self.filename = filename for k, v in kwargs.iteritems(): setattr(self, k, v) - self.obj = self.obj_class(DER_file = filename) + self.obj = self.obj_class(DER_file = filename) # pylint: disable=E1101 def __repr__(self): + # pylint: disable=E1101 return "<%s %s %s at 0x%x>" % (self.__class__.__name__, self.uri, self.resources, id(self)) def show_attrs(self, *attrs): @@ -178,7 +179,8 @@ class rcynic_file_iterator(object): self.rcynic_dir = os.path.join(rcynic_root, authenticated_subdir) def __iter__(self): - for root, dirs, files in os.walk(self.rcynic_dir): # pylint: disable=W0612 + # pylint: disable=W0612 + for root, dirs, files in os.walk(self.rcynic_dir): for filename in files: filename = os.path.join(root, filename) ext = os.path.splitext(filename)[1] @@ -196,6 +198,7 @@ class validation_status_element(object): self._obj = None def get_obj(self): + # pylint: disable=E1101 if not self._obj: self._obj = self.file_class(filename=self.filename, uri=self.uri) return self._obj diff --git a/rpki/relaxng.py b/rpki/relaxng.py index 49ea88d8..aa1f58d4 100644 --- a/rpki/relaxng.py +++ b/rpki/relaxng.py @@ -1,5 +1,8 @@ # Automatically generated, do not edit. +# pylint: disable=I0013 +# pylint: skip-file + from rpki.relaxng_parser import RelaxNGParser ## @var left_right @@ -7,17 +10,17 @@ from rpki.relaxng_parser import RelaxNGParser left_right = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: left-right.rnc 6137 2015-10-20 19:21:37Z sra $ - + RelaxNG schema for RPKI left-right protocol. - + Copyright (C) 2012- -2014 Dragon Research Labs ("DRL") Portions copyright (C) 2009- -2011 Internet Systems Consortium ("ISC") Portions copyright (C) 2007- -2008 American Registry for Internet Numbers ("ARIN") - + 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, ISC, AND ARIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL, @@ -1106,23 +1109,23 @@ left_right = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> myrpki = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: myrpki.rnc 5876 2014-06-26 19:00:12Z sra $ - + RelaxNG schema for MyRPKI XML messages. - + This message protocol is on its way out, as we're in the process of moving on from the user interface model that produced it, but even after we finish replacing it we'll still need the schema for a while to validate old messages when upgrading. - + libxml2 (including xmllint) only groks the XML syntax of RelaxNG, so run the compact syntax through trang to get XML syntax. - + Copyright (C) 2009-2011 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, @@ -1661,17 +1664,17 @@ oob_setup = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> publication_control = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: publication-control.rnc 5903 2014-07-18 17:08:13Z sra $ - + RelaxNG schema for RPKI publication protocol. - + Copyright (C) 2012- -2014 Dragon Research Labs ("DRL") Portions copyright (C) 2009- -2011 Internet Systems Consortium ("ISC") Portions copyright (C) 2007- -2008 American Registry for Internet Numbers ("ARIN") - + 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, ISC, AND ARIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL, @@ -1735,7 +1738,7 @@ publication_control = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- Base64 encoded DER stuff base64 = xsd:base64Binary { maxLength="512000" } - + Sadly, it turns out that CRLs can in fact get longer than this for an active CA. Remove length limit for now, think about whether to put it back later. --> @@ -1945,29 +1948,29 @@ publication_control = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> publication = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: publication.rnc 5896 2014-07-15 19:34:32Z sra $ - + RelaxNG schema for RPKI publication protocol, from current I-D. - + Copyright (c) 2014 IETF Trust and the persons identified as authors of the code. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS @@ -2150,22 +2153,22 @@ publication = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> router_certificate = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: router-certificate.rnc 5881 2014-07-03 16:55:02Z sra $ - + RelaxNG schema for BGPSEC router certificate interchange format. - + At least for now, this is a trivial encapsulation of a PKCS #10 request, a set (usually containing exactly one member) of autonomous system numbers, and a router-id. Be warned that this could change radically by the time we have any real operational understanding of how these things will be used, this is just our current best guess to let us move forward on initial coding. - + Copyright (C) 2014 Dragon Research Labs ("DRL") - + 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 DRL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, @@ -2252,15 +2255,15 @@ router_certificate = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> rrdp = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: rrdp.rnc 6010 2014-11-08 18:01:58Z sra $ - + RelaxNG schema for RPKI Repository Delta Protocol (RRDP). - + Copyright (C) 2014 Dragon Research Labs ("DRL") - + 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 DRL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, @@ -2406,29 +2409,29 @@ rrdp = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> up_down = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: up-down.rnc 5881 2014-07-03 16:55:02Z sra $ - + RelaxNG schema for the up-down protocol, extracted from RFC 6492. - + Copyright (c) 2012 IETF Trust and the persons identified as authors of the code. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS diff --git a/rpki/resource_set.py b/rpki/resource_set.py index b8d1f658..319e2677 100644 --- a/rpki/resource_set.py +++ b/rpki/resource_set.py @@ -52,6 +52,11 @@ class resource_range(object): directly. """ + # Give pylint a little help here + + datum_type = int + parse_str = int + def __init__(self, range_min, range_max): assert range_min.__class__ is range_max.__class__, \ "Type mismatch, %r doesn't match %r" % (range_min.__class__, range_max.__class__) @@ -130,6 +135,9 @@ class resource_range_ip(resource_range): datum_type = rpki.POW.IPAddress + # Give pylint a little help here + version = None + def prefixlen(self): """ Determine whether a resource_range_ip can be expressed as a @@ -306,6 +314,9 @@ class resource_set(list): canonical = False + # Give pylint a little help here + range_type = resource_range + def __init__(self, ini = None, allow_overlap = False): """ Initialize a resource_set. @@ -316,7 +327,7 @@ class resource_set(list): ini = str(ini) if ini is inherit_token: self.inherit = True - elif isinstance(ini, str) and len(ini): + elif isinstance(ini, (str, unicode)) and len(ini): self.extend(self.parse_str(s) for s in ini.split(",")) elif isinstance(ini, list): self.extend(ini) @@ -542,22 +553,6 @@ class resource_set(list): return self.inherit or len(self) @classmethod - def from_sql(cls, sql, query, args = None): - """ - Create resource set from an SQL query. - - sql is an object that supports execute() and fetchall() methods - like a DB API 2.0 cursor object. - - query is an SQL query that returns a sequence of (min, max) pairs. - """ - - sql.execute(query, args) - return cls(ini = [cls.range_type(cls.range_type.datum_type(b), - cls.range_type.datum_type(e)) - for (b, e) in sql.fetchall()]) - - @classmethod def from_django(cls, iterable): """ Create resource set from a Django query. @@ -602,6 +597,7 @@ class resource_set_ip(resource_set): Convert from a resource set to a ROA prefix set. """ + # pylint: disable=E1101 prefix_ranges = [] for r in self: r.chop_into_prefixes(prefix_ranges) @@ -846,6 +842,9 @@ class roa_prefix(object): ## @var max_prefixlen # Maxmimum prefix length. + # Give pylint a little help + range_type = resource_range_ip + def __init__(self, prefix, prefixlen, max_prefixlen = None): """ Initialize a ROA prefix. max_prefixlen is optional and defaults @@ -949,13 +948,18 @@ class roa_prefix_set(list): Set of ROA prefixes, analogous to the resource_set_ip class. """ + # Give pylint a little help + + prefix_type = roa_prefix + resource_set_type = resource_set_ip + def __init__(self, ini = None): """ Initialize a ROA prefix set. """ list.__init__(self) - if isinstance(ini, str) and len(ini): + if isinstance(ini, (str, unicode)) and len(ini): self.extend(self.parse_str(s) for s in ini.split(",")) elif isinstance(ini, (list, tuple)): self.extend(ini) @@ -1103,21 +1107,21 @@ if __name__ == "__main__": return " (%s)" % v.to_roa_prefix_set() if isinstance(v, resource_set_ip) else "" def test1(t, s1, s2): - if isinstance(s1, str) and isinstance(s2, str): + if isinstance(s1, (str, unicode)) and isinstance(s2, (str, unicode)): print "x: ", s1 print "y: ", s2 r1 = t(s1) r2 = t(s2) print "x: ", r1, testprefix(r1) print "y: ", r2, testprefix(r2) - v1 = r1._comm(r2) - v2 = r2._comm(r1) + v1 = r1._comm(r2) # pylint: disable=W0212 + v2 = r2._comm(r1) # pylint: disable=W0212 assert v1[0] == v2[1] and v1[1] == v2[0] and v1[2] == v2[2] - for i in r1: assert i in r1 and i.min in r1 and i.max in r1 - for i in r2: assert i in r2 and i.min in r2 and i.max in r2 - for i in v1[0]: assert i in r1 and i not in r2 - for i in v1[1]: assert i not in r1 and i in r2 - for i in v1[2]: assert i in r1 and i in r2 + assert all(i in r1 and i.min in r1 and i.max in r1 for i in r1) + assert all(i in r2 and i.min in r2 and i.max in r2 for i in r2) + assert all(i in r1 and i not in r2 for i in v1[0]) + assert all(i not in r1 and i in r2 for i in v1[1]) + assert all(i in r1 and i in r2 for i in v1[2]) v1 = r1 | r2 v2 = r2 | r1 assert v1 == v2 diff --git a/rpki/rootd.py b/rpki/rootd.py index e3a460f4..08259a9a 100644 --- a/rpki/rootd.py +++ b/rpki/rootd.py @@ -369,7 +369,7 @@ class main(object): try: crl = rpki.x509.CRL(DER_file = self.rpki_root_crl_file) self.crl_number = crl.getCRLNumber() - except: # pylint: disable=W0702 + except: self.crl_number = 0 self.crl_number += 1 return self.crl_number diff --git a/rpki/rpkic.py b/rpki/rpkic.py index 9cde75fb..7d63bbe7 100644 --- a/rpki/rpkic.py +++ b/rpki/rpkic.py @@ -115,7 +115,10 @@ class main(Cmd): args.func(self, args) def read_config(self): - global rpki # pylint: disable=W0602 + + # pylint: disable=W0201,W0602,W0621 + + global rpki try: cfg = rpki.config.parser(set_filename = self.cfg_file, section = "myrpki") @@ -131,7 +134,7 @@ class main(Cmd): import django django.setup() - import rpki.irdb # pylint: disable=W0621 + import rpki.irdb try: rpki.irdb.models.ca_certificate_lifetime = rpki.sundial.timedelta.parse( @@ -582,7 +585,7 @@ class main(Cmd): Show resources received by this entity from its parent(s). """ - q_msg = self.zoo._compose_left_right_query() + q_msg = self.zoo.compose_left_right_query() SubElement(q_msg, rpki.left_right.tag_list_received_resources, tenant_handle = self.zoo.handle) for r_pdu in self.zoo.call_rpkid(q_msg): @@ -604,7 +607,7 @@ class main(Cmd): Show published objects. """ - q_msg = self.zoo._compose_left_right_query() + q_msg = self.zoo.compose_left_right_query() SubElement(q_msg, rpki.left_right.tag_list_published_objects, tenant_handle = self.zoo.handle) for r_pdu in self.zoo.call_rpkid(q_msg): diff --git a/rpki/rpkid.py b/rpki/rpkid.py index 001c36e2..96f3426f 100644 --- a/rpki/rpkid.py +++ b/rpki/rpkid.py @@ -252,7 +252,7 @@ class main(object): @tornado.gen.coroutine def cron_loop(self): """ - Asynchronous infinite loop to drive cron cycle. + Asynchronous infinite loop to drive internal cron cycle. """ logger.debug("cron_loop(): Starting") @@ -268,7 +268,7 @@ class main(object): @tornado.gen.coroutine def cron_run(self): """ - Schedule periodic tasks. + Schedule periodic tasks and wait for them to finish. """ now = rpki.sundial.now() @@ -296,7 +296,7 @@ class main(object): handler.set_status(500, "Running cron internally") else: logger.debug("Starting externally triggered cron") - yield self.cron() + yield self.cron_run() handler.set_status(200) handler.finish() @@ -340,7 +340,7 @@ class main(object): raise tornado.gen.Return(response) @staticmethod - def _compose_left_right_query(): + def compose_left_right_query(): """ Compose top level element of a left-right query to irdbd. """ @@ -393,7 +393,7 @@ class main(object): Ask IRDB about a child's resources. """ - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() SubElement(q_msg, rpki.left_right.tag_list_resources, tenant_handle = tenant_handle, child_handle = child_handle) r_msg = yield self.irdb_query(q_msg) @@ -415,7 +415,7 @@ class main(object): Ask IRDB about self's ROA requests. """ - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() SubElement(q_msg, rpki.left_right.tag_list_roa_requests, tenant_handle = tenant_handle) r_msg = yield self.irdb_query(q_msg) raise tornado.gen.Return(r_msg) @@ -426,7 +426,7 @@ class main(object): Ask IRDB about self's ghostbuster record requests. """ - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() for parent_handle in parent_handles: SubElement(q_msg, rpki.left_right.tag_list_ghostbuster_requests, tenant_handle = tenant_handle, parent_handle = parent_handle) @@ -439,7 +439,7 @@ class main(object): Ask IRDB about self's EE certificate requests. """ - q_msg = self._compose_left_right_query() + q_msg = self.compose_left_right_query() SubElement(q_msg, rpki.left_right.tag_list_ee_certificate_requests, tenant_handle = tenant_handle) r_msg = yield self.irdb_query(q_msg) raise tornado.gen.Return(r_msg) @@ -450,10 +450,12 @@ class main(object): Map element tag to rpkidb model. """ + # pylint: disable=W0621,W0201 + try: return self._left_right_models except AttributeError: - import rpki.rpkidb.models # pylint: disable=W0621 + import rpki.rpkidb.models self._left_right_models = { rpki.left_right.tag_tenant : rpki.rpkidb.models.Tenant, rpki.left_right.tag_bsc : rpki.rpkidb.models.BSC, @@ -468,6 +470,8 @@ class main(object): Map element tag to bound handler methods for trivial PDU types. """ + # pylint: disable=W0201 + try: return self._left_right_trivial_handlers except AttributeError: @@ -690,17 +694,20 @@ class publication_queue(object): old_pdu = self.uris.pop(uri) self.msgs[rid].remove(old_pdu) pdu_hash = old_pdu.get("hash") + if pdu_hash is None and new_obj is None: + logger.debug("Withdrawing object %r which was never published simplifies to no-op", old_pdu) + return elif old_hash is not None: - logger.debug("Old hash supplied") # XXX + logger.debug("Old hash supplied") # XXX Debug log pdu_hash = old_hash elif old_obj is None: - logger.debug("No old object present") # XXX + logger.debug("No old object present") # XXX Debug log pdu_hash = None else: - logger.debug("Calculating hash of old object") # XXX + logger.debug("Calculating hash of old object") # XXX Debug log pdu_hash = rpki.x509.sha256(old_obj.get_DER()).encode("hex") - logger.debug("uri %s old hash %s new hash %s", uri, pdu_hash, # XXX + logger.debug("uri %s old hash %s new hash %s", uri, pdu_hash, # XXX Debug log None if new_obj is None else rpki.x509.sha256(new_obj.get_DER()).encode("hex")) if new_obj is None: diff --git a/rpki/rpkid_tasks.py b/rpki/rpkid_tasks.py index 989042b9..3fd3a411 100644 --- a/rpki/rpkid_tasks.py +++ b/rpki/rpkid_tasks.py @@ -279,8 +279,8 @@ class UpdateROAsTask(AbstractTask): seen = set() orphans = [] updates = [] - self.publisher = rpki.rpkid.publication_queue(self.rpkid) - self.ca_details = set() + self.publisher = rpki.rpkid.publication_queue(self.rpkid) # pylint: disable=W0201 + self.ca_details = set() # pylint: disable=W0201 for roa in self.tenant.roas.all(): k = (roa.asn, str(roa.ipv4), str(roa.ipv6)) @@ -458,6 +458,8 @@ class UpdateEECertificatesTask(AbstractTask): ee.reissue(resources = resources, publisher = publisher) covering.remove(ee.ca_detail) else: + # This probably never happens, as the most likely cause would be a CA certificate + # being revoked, which should trigger automatic clean up of issued certificates. logger.debug("%r: Existing EE certificate for %s %s is no longer covered", self, gski, resources) ee.revoke(publisher = publisher) diff --git a/rpki/rpkidb/models.py b/rpki/rpkidb/models.py index ab89ba7b..527b81d4 100644 --- a/rpki/rpkidb/models.py +++ b/rpki/rpkidb/models.py @@ -26,6 +26,9 @@ from lxml.etree import Element, SubElement, tostring as ElementToString logger = logging.getLogger(__name__) +# pylint: disable=W5101 + + # XXX Temporary hack to help trace call chains so we can clear some of # the historical clutter out of this module. @@ -161,7 +164,7 @@ class XMLTemplate(object): setattr(obj, k, self.element_type[k](Base64 = v)) -class XMLManager(models.Manager): # pylint: disable=W0232 +class XMLManager(models.Manager): """ Add a few methods which locate or create an object or objects corresponding to the handles in an XML element, as appropriate. @@ -174,6 +177,8 @@ class XMLManager(models.Manager): # pylint: disable=W0232 debug = False + # pylint: disable=E1101 + def xml_get_or_create(self, xml): name = self.model.xml_template.name action = xml.get("action") @@ -382,6 +387,7 @@ class Tenant(models.Model): def cron_tasks(self, rpkid): trace_call_chain() + # pylint: disable=W0201 try: return self._cron_tasks except AttributeError: @@ -418,7 +424,7 @@ class BSC(models.Model): tenant = models.ForeignKey(Tenant, related_name = "bscs") objects = XMLManager() - class Meta: # pylint: disable=C1001,W0232 + class Meta: unique_together = ("tenant", "bsc_handle") xml_template = XMLTemplate( @@ -447,7 +453,7 @@ class Repository(models.Model): tenant = models.ForeignKey(Tenant, related_name = "repositories") objects = XMLManager() - class Meta: # pylint: disable=C1001,W0232 + class Meta: unique_together = ("tenant", "repository_handle") xml_template = XMLTemplate( @@ -542,7 +548,7 @@ class Parent(models.Model): repository = models.ForeignKey(Repository, related_name = "parents") objects = XMLManager() - class Meta: # pylint: disable=C1001,W0232 + class Meta: unique_together = ("tenant", "parent_handle") xml_template = XMLTemplate( @@ -668,7 +674,7 @@ class Parent(models.Model): """ trace_call_chain() - yield [ca.destroy(self) for ca in self.cas()] + yield [ca.destroy(self) for ca in self.cas()] # pylint: disable=E1101 yield self.serve_revoke_forgotten(rpkid = rpkid) if delete_parent: self.delete() @@ -806,6 +812,8 @@ class CA(models.Model): with the same key, etc. """ + # pylint: disable=C0330 + trace_call_chain() logger.debug("check_for_updates()") sia_uri = parent.construct_sia_uri(rc) @@ -1056,7 +1064,7 @@ class CADetail(models.Model): manifest_published = SundialField(null = True) state = EnumField(choices = ("pending", "active", "deprecated", "revoked")) ca_cert_uri = models.TextField(null = True) - ca = models.ForeignKey(CA, related_name = "ca_details") + ca = models.ForeignKey(CA, related_name = "ca_details") # pylint: disable=C0103 # Like the old ca_obj class, the old ca_detail_obj class had ten @@ -1079,6 +1087,7 @@ class CADetail(models.Model): Return tail (filename portion) of publication URI for this ca_detail's CRL. """ + # pylint: disable=E1101 return self.public_key.gSKI() + ".crl" @@ -1088,6 +1097,7 @@ class CADetail(models.Model): Return publication URI for this ca_detail's manifest. """ + # pylint: disable=E1101 return self.ca.sia_uri + self.public_key.gSKI() + ".mft" @@ -1179,7 +1189,7 @@ class CADetail(models.Model): - Request revocation of old keypair by parent. - - Revoke all child certs issued by the old keypair. + - Revoke all certificates issued by the old keypair. - Generate a final CRL, signed with the old keypair, listing all the revoked certs, with a next CRL time after the last cert or @@ -1234,6 +1244,10 @@ class CADetail(models.Model): nextUpdate = nextUpdate.later(ghostbuster.cert.getNotAfter()) ghostbuster.revoke(publisher = publisher) + for eecert in self.ee_certificates.all(): + nextUpdate = nextUpdate.later(eecert.cert.getNotAfter()) + eecert.revoke(publisher = publisher) + nextUpdate += crl_interval self.generate_crl(publisher = publisher, nextUpdate = nextUpdate) @@ -1463,8 +1477,8 @@ class CADetail(models.Model): if nextUpdate is None: nextUpdate = now + crl_interval if (self.latest_manifest_cert is None or - (self.latest_manifest_cert.getNotAfter() < nextUpdate and - self.latest_manifest_cert.getNotAfter() < self.latest_ca_cert.getNotAfter())): + (self.latest_manifest_cert.getNotAfter() < nextUpdate and + self.latest_manifest_cert.getNotAfter() < self.latest_ca_cert.getNotAfter())): logger.debug("Generating EE certificate for %s", uri) self.generate_manifest_cert() logger.debug("Latest CA cert notAfter %s, new %s EE notAfter %s", @@ -1616,7 +1630,7 @@ class Child(models.Model): bsc = models.ForeignKey(BSC, related_name = "children") objects = XMLManager() - class Meta: # pylint: disable=C1001,W0232 + class Meta: unique_together = ("tenant", "child_handle") xml_template = XMLTemplate( @@ -1861,6 +1875,7 @@ class ChildCert(models.Model): """ trace_call_chain() + # pylint: disable=E1101 ca = ca_detail.ca child = self.child old_resources = self.cert.get_3779resources() diff --git a/rpki/rtr/bgpdump.py b/rpki/rtr/bgpdump.py index 3336fb9f..1ca04803 100755 --- a/rpki/rtr/bgpdump.py +++ b/rpki/rtr/bgpdump.py @@ -91,6 +91,8 @@ class PrefixPDU(rpki.rtr.generator.PrefixPDU): class AXFRSet(rpki.rtr.generator.AXFRSet): + serial = None + @staticmethod def read_bgpdump(filename): assert filename.endswith(".bz2") @@ -101,6 +103,7 @@ class AXFRSet(rpki.rtr.generator.AXFRSet): @classmethod def parse_bgpdump_rib_dump(cls, filename): + # pylint: disable=W0201 assert os.path.basename(filename).startswith("ribs.") self = cls() self.serial = None @@ -212,7 +215,7 @@ def bgpdump_select_main(args): nonce = rpki.rtr.server.read_current(version)[1] if nonce is None: - nonce = rpki.rtr.generator.new_nonce() + nonce = rpki.rtr.generator.AXFRSet.new_nonce(force_zero_nonce = False) rpki.rtr.server.write_current(serial, nonce, version) rpki.rtr.generator.kick_all(serial) @@ -238,7 +241,7 @@ class BGPDumpReplayClock(object): self.timestamps = [Timestamp(int(f.split(".")[0])) for f in glob.iglob("*.ax.v*")] self.timestamps.sort() self.offset = self.timestamps[0] - int(time.time()) - self.nonce = rpki.rtr.generator.new_nonce() + self.nonce = rpki.rtr.generator.AXFRSet.new_nonce(force_zero_nonce = False) def __nonzero__(self): return len(self.timestamps) > 0 @@ -278,7 +281,7 @@ def bgpdump_server_main(args): You have been warned. """ - logger = logging.LoggerAdapter(logging.root, dict(connection = rpki.rtr.server._hostport_tag())) + logger = logging.LoggerAdapter(logging.root, dict(connection = rpki.rtr.server.hostport_tag())) logger.debug("[Starting]") diff --git a/rpki/rtr/channels.py b/rpki/rtr/channels.py index df96fa58..a4dccbc1 100644 --- a/rpki/rtr/channels.py +++ b/rpki/rtr/channels.py @@ -59,6 +59,8 @@ class ReadBuffer(object): def __init__(self): self.buffer = "" self.version = None + self.need = None + self.callback = None def update(self, need, callback): """ diff --git a/rpki/rtr/generator.py b/rpki/rtr/generator.py index e00e44b7..a879cc39 100644 --- a/rpki/rtr/generator.py +++ b/rpki/rtr/generator.py @@ -105,6 +105,11 @@ class RouterKeyPDU(rpki.rtr.pdus.RouterKeyPDU): Router Key PDU. """ + announce = None + ski = None + asn = None + key = None + @classmethod def from_text(cls, version, asn, gski, key): """ @@ -140,14 +145,15 @@ class ROA(rpki.POW.ROA): # pylint: disable=W0232 """ @classmethod - def derReadFile(cls, fn): # pylint: disable=E1002 + def derReadFile(cls, fn): + # pylint: disable=E1002 self = super(ROA, cls).derReadFile(fn) self.extractWithoutVerifying() return self @property def prefixes(self): - v4, v6 = self.getPrefixes() + v4, v6 = self.getPrefixes() # pylint: disable=E1101 if v4 is not None: for p in v4: yield p @@ -162,7 +168,7 @@ class X509(rpki.POW.X509): # pylint: disable=W0232 @property def asns(self): - resources = self.getRFC3779() + resources = self.getRFC3779() # pylint: disable=E1101 if resources is not None and resources[0] is not None: for min_asn, max_asn in resources[0]: for asn in xrange(min_asn, max_asn + 1): @@ -215,6 +221,8 @@ class AXFRSet(PDUSet): field set. """ + serial = None + @classmethod def parse_rcynic(cls, rcynic_dir, version, scan_roas = None, scan_routercerts = None): """ @@ -245,7 +253,7 @@ class AXFRSet(PDUSet): self.extend(PrefixPDU.from_roa(version = version, asn = asn, prefix_tuple = prefix_tuple) for prefix_tuple in roa.prefixes) if include_routercerts and scan_routercerts is None and fn.endswith(".cer"): - x = X509.derReadFile(os.path.join(root, fn)) + x = X509.derReadFile(os.path.join(root, fn)) # pylint: disable=E1101 eku = x.getEKU() if eku is not None and rpki.oids.id_kp_bgpsec_router in eku: ski = x.getSKI() @@ -415,6 +423,9 @@ class IXFRSet(PDUSet): indicate the changes. """ + from_serial = None + to_serial = None + @classmethod def load(cls, filename): """ diff --git a/rpki/rtr/pdus.py b/rpki/rtr/pdus.py index d355026c..3fb7457d 100644 --- a/rpki/rtr/pdus.py +++ b/rpki/rtr/pdus.py @@ -116,6 +116,8 @@ class PDU(object): header_struct = struct.Struct("!BB2xL") + pdu_type = None + def __init__(self, version): assert version in self.version_map self.version = version @@ -123,6 +125,9 @@ class PDU(object): def __cmp__(self, other): return cmp(self.to_pdu(), other.to_pdu()) + def to_pdu(self, announce = None): + return NotImplementedError + @property def default_version(self): return max(self.version_map.iterkeys()) @@ -170,11 +175,12 @@ class PDUWithSerial(PDU): def __str__(self): return "[%s, serial #%d nonce %d]" % (self.__class__.__name__, self.serial, self.nonce) - def to_pdu(self): + def to_pdu(self, announce = None): """ Generate the wire format PDU. """ + assert announce is None if self._pdu is None: self._pdu = self.header_struct.pack(self.version, self.pdu_type, self.nonce, self.header_struct.size, self.serial) @@ -208,11 +214,12 @@ class PDUWithNonce(PDU): def __str__(self): return "[%s, nonce %d]" % (self.__class__.__name__, self.nonce) - def to_pdu(self): + def to_pdu(self, announce = None): """ Generate the wire format PDU. """ + assert announce is None if self._pdu is None: self._pdu = self.header_struct.pack(self.version, self.pdu_type, self.nonce, self.header_struct.size) return self._pdu @@ -239,11 +246,12 @@ class PDUEmpty(PDU): def __str__(self): return "[%s]" % self.__class__.__name__ - def to_pdu(self): + def to_pdu(self, announce = None): """ Generate the wire format PDU for this prefix. """ + assert announce is None if self._pdu is None: self._pdu = self.header_struct.pack(self.version, self.pdu_type, 0, self.header_struct.size) return self._pdu @@ -370,11 +378,12 @@ class EndOfDataPDUv1(EndOfDataPDUv0): return "[%s, serial #%d nonce %d refresh %d retry %d expire %d]" % ( self.__class__.__name__, self.serial, self.nonce, self.refresh, self.retry, self.expire) - def to_pdu(self): + def to_pdu(self, announce = None): """ Generate the wire format PDU. """ + assert announce is None if self._pdu is None: self._pdu = self.header_struct.pack(self.version, self.pdu_type, self.nonce, self.header_struct.size, self.serial, @@ -416,6 +425,15 @@ class PrefixPDU(PDU): header_struct = struct.Struct("!BB2xLBBBx") asnum_struct = struct.Struct("!L") + address_byte_count = 0 + + def __init__(self, version): + super(PrefixPDU, self).__init__(version) + self.asn = None + self.prefix = None + self.prefixlen = None + self.max_prefixlen = None + self.announce = None def __str__(self): plm = "%s/%s-%s" % (self.prefix, self.prefixlen, self.max_prefixlen) @@ -511,6 +529,13 @@ class RouterKeyPDU(PDU): header_struct = struct.Struct("!BBBxL20sL") + def __init__(self, version): + super(RouterKeyPDU, self).__init__(version) + self.announce = None + self.ski = None + self.asn = None + self.key = None + def __str__(self): return "%s %8s %-32s %s" % ("+" if self.announce else "-", self.asn, base64.urlsafe_b64encode(self.ski).rstrip("="), @@ -596,6 +621,8 @@ class ErrorReportPDU(PDU): self.errno = errno self.errpdu = errpdu self.errmsg = errmsg if errmsg is not None or errno is None else self.errors[errno] + self.pdulen = None + self.errlen = None def __str__(self): return "[%s, error #%s: %r]" % (self.__class__.__name__, self.errno, self.errmsg) @@ -609,11 +636,12 @@ class ErrorReportPDU(PDU): assert remaining >= self.string_struct.size + n return n, reader.get(n), (remaining - self.string_struct.size - n) - def to_pdu(self): + def to_pdu(self, announce = None): """ Generate the wire format PDU for this error report. """ + assert announce is None if self._pdu is None: assert isinstance(self.errno, int) assert not isinstance(self.errpdu, ErrorReportPDU) diff --git a/rpki/rtr/server.py b/rpki/rtr/server.py index f57c3037..052aef2c 100644 --- a/rpki/rtr/server.py +++ b/rpki/rtr/server.py @@ -393,7 +393,7 @@ class KickmeChannel(asyncore.dispatcher, object): self.close() try: os.unlink(self.sockname) - except: # pylint: disable=W0702 + except: pass def log(self, msg): @@ -420,7 +420,7 @@ class KickmeChannel(asyncore.dispatcher, object): sys.exit(1) -def _hostport_tag(): +def hostport_tag(): """ Construct hostname/address + port when we're running under a protocol we understand well enough to do that. This is all @@ -433,28 +433,28 @@ def _hostport_tag(): try: host, port = socket.fromfd(0, socket.AF_INET, socket.SOCK_STREAM).getpeername() proto = "tcp" - except: # pylint: disable=W0702 + except: pass if proto is None: try: host, port = socket.fromfd(0, socket.AF_INET6, socket.SOCK_STREAM).getpeername()[0:2] proto = "tcp" - except: # pylint: disable=W0702 + except: pass if proto is None: try: host, port = os.environ["SSH_CONNECTION"].split()[0:2] proto = "ssh" - except: # pylint: disable=W0702 + except: pass if proto is None: try: host, port = os.environ["REMOTE_HOST"], os.getenv("REMOTE_PORT") proto = "ssl" - except: # pylint: disable=W0702 + except: pass if proto is None: @@ -476,7 +476,7 @@ def server_main(args): pass the results along to a client. """ - logger = logging.LoggerAdapter(logging.root, dict(connection = _hostport_tag())) + logger = logging.LoggerAdapter(logging.root, dict(connection = hostport_tag())) logger.debug("[Starting]") @@ -516,7 +516,7 @@ def listener_main(args): try: listener = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) listener.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) - except: # pylint: disable=W0702 + except: if listener is not None: listener.close() listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -536,8 +536,8 @@ def listener_main(args): logging.debug("[Received connection from %r]", ai) pid = os.fork() if pid == 0: - os.dup2(s.fileno(), 0) # pylint: disable=E1103 - os.dup2(s.fileno(), 1) # pylint: disable=E1103 + os.dup2(s.fileno(), 0) # pylint: disable=E1101 + os.dup2(s.fileno(), 1) # pylint: disable=E1101 s.close() #os.closerange(3, os.sysconf("SC_OPEN_MAX")) server_main(args) @@ -546,11 +546,11 @@ def listener_main(args): logging.debug("[Spawned server %d]", pid) while True: try: - pid, status = os.waitpid(0, os.WNOHANG) # pylint: disable=W0612 + pid, status = os.waitpid(0, os.WNOHANG) if pid: - logging.debug("[Server %s exited]", pid) + logging.debug("[Server %s exited with status 0x%x]", pid, status) continue - except: # pylint: disable=W0702 + except: pass break diff --git a/rpki/sundial.py b/rpki/sundial.py index 0381599f..1556d0bd 100644 --- a/rpki/sundial.py +++ b/rpki/sundial.py @@ -155,10 +155,17 @@ class datetime(pydatetime.datetime): return other if other < self else self - def __add__(self, y): return _cast(pydatetime.datetime.__add__(self, y)) - def __radd__(self, y): return _cast(pydatetime.datetime.__radd__(self, y)) - def __rsub__(self, y): return _cast(pydatetime.datetime.__rsub__(self, y)) - def __sub__(self, y): return _cast(pydatetime.datetime.__sub__(self, y)) + def __add__(self, y): + return _cast(pydatetime.datetime.__add__(self, y)) + + def __radd__(self, y): + return _cast(pydatetime.datetime.__radd__(self, y)) + + def __rsub__(self, y): + return _cast(pydatetime.datetime.__rsub__(self, y)) + + def __sub__(self, y): + return _cast(pydatetime.datetime.__sub__(self, y)) @classmethod def DateTime_or_None(cls, s): @@ -172,7 +179,7 @@ class datetime(pydatetime.datetime): if t: try: return cls(*[int(x) for x in d.split("-") + t.split(":")]) - except: # pylint: disable=W0702 + except: break from rpki.mysql_import import MySQLdb @@ -260,19 +267,44 @@ class timedelta(pydatetime.timedelta): return cls(days = x.days, seconds = x.seconds, microseconds = x.microseconds) - def __abs__(self): return _cast(pydatetime.timedelta.__abs__(self)) - def __add__(self, x): return _cast(pydatetime.timedelta.__add__(self, x)) - def __div__(self, x): return _cast(pydatetime.timedelta.__div__(self, x)) - def __floordiv__(self, x): return _cast(pydatetime.timedelta.__floordiv__(self, x)) - def __mul__(self, x): return _cast(pydatetime.timedelta.__mul__(self, x)) - def __neg__(self): return _cast(pydatetime.timedelta.__neg__(self)) - def __pos__(self): return _cast(pydatetime.timedelta.__pos__(self)) - def __radd__(self, x): return _cast(pydatetime.timedelta.__radd__(self, x)) - def __rdiv__(self, x): return _cast(pydatetime.timedelta.__rdiv__(self, x)) - def __rfloordiv__(self, x): return _cast(pydatetime.timedelta.__rfloordiv__(self, x)) - def __rmul__(self, x): return _cast(pydatetime.timedelta.__rmul__(self, x)) - def __rsub__(self, x): return _cast(pydatetime.timedelta.__rsub__(self, x)) - def __sub__(self, x): return _cast(pydatetime.timedelta.__sub__(self, x)) + def __abs__(self): + return _cast(pydatetime.timedelta.__abs__(self)) + + def __add__(self, x): + return _cast(pydatetime.timedelta.__add__(self, x)) + + def __div__(self, x): + return _cast(pydatetime.timedelta.__div__(self, x)) + + def __floordiv__(self, x): + return _cast(pydatetime.timedelta.__floordiv__(self, x)) + + def __mul__(self, x): + return _cast(pydatetime.timedelta.__mul__(self, x)) + + def __neg__(self): + return _cast(pydatetime.timedelta.__neg__(self)) + + def __pos__(self): + return _cast(pydatetime.timedelta.__pos__(self)) + + def __radd__(self, x): + return _cast(pydatetime.timedelta.__radd__(self, x)) + + def __rdiv__(self, x): + return _cast(pydatetime.timedelta.__rdiv__(self, x)) + + def __rfloordiv__(self, x): + return _cast(pydatetime.timedelta.__rfloordiv__(self, x)) + + def __rmul__(self, x): + return _cast(pydatetime.timedelta.__rmul__(self, x)) + + def __rsub__(self, x): + return _cast(pydatetime.timedelta.__rsub__(self, x)) + + def __sub__(self, x): + return _cast(pydatetime.timedelta.__sub__(self, x)) def _cast(x): """ diff --git a/rpki/x509.py b/rpki/x509.py index 32bedc6a..5286fabd 100644 --- a/rpki/x509.py +++ b/rpki/x509.py @@ -159,6 +159,10 @@ class X501DN(object): simple. """ + def __init__(self, dn): + assert isinstance(dn, tuple) + self.dn = dn + def __str__(self): return "".join("/" + "+".join("%s=%s" % (rpki.oids.oid2name(a[0]), a[1]) for a in rdn) @@ -181,19 +185,15 @@ class X501DN(object): elif isinstance(sn, (str, unicode)): assert all(c in "0123456789abcdefABCDEF" for c in sn) sn = str(sn) - self = cls() if sn is not None: - self.dn = (((rpki.oids.commonName, cn),), ((rpki.oids.serialNumber, sn),)) + dn = (((rpki.oids.commonName, cn),), ((rpki.oids.serialNumber, sn),)) else: - self.dn = (((rpki.oids.commonName, cn),),) - return self + dn = (((rpki.oids.commonName, cn),),) + return cls(dn) @classmethod - def from_POW(cls, t): - assert isinstance(t, tuple) - self = cls() - self.dn = t - return self + def from_POW(cls, dn): + return cls(dn) def get_POW(self): return self.dn @@ -320,6 +320,8 @@ class DER_object(object): Check for updates to a DER object that auto-updates from a file. """ + # pylint: disable=W0201 + if self.filename is None: return try: @@ -368,6 +370,7 @@ class DER_object(object): Subclasses may need to override this. """ + # pylint: disable=W0201 assert self.empty() self.POW = self.POW_class.pemRead(pem) @@ -391,8 +394,9 @@ class DER_object(object): Subclasses may need to override this method. """ + # pylint: disable=E0203,W0201 self.check() - if not self.POW: # pylint: disable=E0203 + if not self.POW: self.POW = self.POW_class.derRead(self.get_DER()) return self.POW @@ -566,7 +570,7 @@ class DER_object(object): resources = rpki.resource_set.resource_bag.from_POW_rfc3779(self.get_POW().getRFC3779()) try: - resources.valid_until = self.getNotAfter() + resources.valid_until = self.getNotAfter() # pylint: disable=E1101 except AttributeError: pass return resources @@ -615,11 +619,11 @@ class DER_object(object): this information at the start of the tracking line. """ + # pylint: disable=E1101 + try: - return "%s %s %s" % (uri, - self.creation_timestamp, - "".join(("%02X" % ord(b) for b in sha1(self.get_DER())))) - except: # pylint: disable=W0702 + return "%s %s %s" % (uri, self.creation_timestamp, "".join(("%02X" % ord(b) for b in sha1(self.get_DER())))) + except: return uri def __getstate__(self): @@ -995,8 +999,9 @@ class PKCS10(DER_object): Get the rpki.POW value of this certification request. """ + # pylint: disable=E0203,W0201 self.check() - if not self.POW: # pylint: disable=E0203 + if not self.POW: self.POW = rpki.POW.PKCS10.derRead(self.get_DER()) return self.POW @@ -1279,8 +1284,9 @@ class PrivateKey(DER_object): Get the rpki.POW value of this keypair. """ + # pylint: disable=E0203,W0201 self.check() - if not self.POW: # pylint: disable=E0203 + if not self.POW: self.POW = rpki.POW.Asymmetric.derReadPrivate(self.get_DER()) return self.POW @@ -1296,6 +1302,7 @@ class PrivateKey(DER_object): Set the POW value of this keypair from a PEM string. """ + # pylint: disable=W0201 assert self.empty() self.POW = self.POW_class.pemReadPrivate(pem) @@ -1345,8 +1352,9 @@ class PublicKey(DER_object): Get the rpki.POW value of this public key. """ + # pylint: disable=E0203,W0201 self.check() - if not self.POW: # pylint: disable=E0203 + if not self.POW: self.POW = rpki.POW.Asymmetric.derReadPublic(self.get_DER()) return self.POW @@ -1362,6 +1370,7 @@ class PublicKey(DER_object): Set the POW value of this public key from a PEM string. """ + # pylint: disable=W0201 assert self.empty() self.POW = self.POW_class.pemReadPublic(pem) @@ -1490,8 +1499,9 @@ class CMS_object(DER_object): Get the rpki.POW value of this CMS_object. """ + # pylint: disable=E0203,W0201 self.check() - if not self.POW: # pylint: disable=E0203 + if not self.POW: self.POW = self.POW_class.derRead(self.get_DER()) return self.POW @@ -1660,6 +1670,9 @@ class CMS_object(DER_object): [c.get_POW() for c in crls], rpki.POW.CMS_NOCERTS if no_certs else 0) + def _sign(self, cert, keypair, certs, crls, flags): + raise NotImplementedError + @property def creation_timestamp(self): """ @@ -1697,6 +1710,7 @@ class Wrapped_CMS_object(CMS_object): Set the (inner) content of this Wrapped_CMS_object, clearing the wrapper. """ + # pylint: disable=W0201 self.clear() self.content = content @@ -1740,10 +1754,17 @@ class Wrapped_CMS_object(CMS_object): different CMS-based POW classes handle the inner content. """ + # pylint: disable=W0201 cms = self.POW_class() cms.sign(cert, keypair, self.encode(), certs, crls, self.econtent_oid, flags) self.POW = cms + def decode(self, whatever): + raise NotImplementedError + + def encode(self): + raise NotImplementedError + class DER_CMS_object(CMS_object): """ @@ -1856,7 +1877,7 @@ class ROA(DER_CMS_object): text.append("%s/%s-%s" % (prefix, prefixlen, maxprefixlen)) text.sort() msg = "%s %s %s" % (msg, asn, ",".join(text)) - except: # pylint: disable=W0702 + except: pass return msg @@ -1897,6 +1918,8 @@ class XML_CMS_object(Wrapped_CMS_object): """ econtent_oid = rpki.oids.id_ct_xml + encoding = None + schema = None ## @var dump_outbound_cms # If set, we write all outbound XML-CMS PDUs to disk, for debugging. @@ -1935,6 +1958,7 @@ class XML_CMS_object(Wrapped_CMS_object): Decode XML and set inner content. """ + # pylint: disable=W0201 self.content = lxml.etree.fromstring(xml) def pretty_print_content(self): @@ -2047,6 +2071,7 @@ class Ghostbuster(Wrapped_CMS_object): the VCard as an opaque byte string, so no encoding needed here. """ + # pylint: disable=W0201 self.content = vcard @classmethod @@ -2086,8 +2111,9 @@ class CRL(DER_object): Get the rpki.POW value of this CRL. """ + # pylint: disable=W0201,E0203 self.check() - if not self.POW: # pylint: disable=E0203 + if not self.POW: self.POW = rpki.POW.CRL.derRead(self.get_DER()) return self.POW |