diff options
Diffstat (limited to 'rpki/pubd.py')
-rw-r--r-- | rpki/pubd.py | 59 |
1 files changed, 26 insertions, 33 deletions
diff --git a/rpki/pubd.py b/rpki/pubd.py index 14de1999..0ee4d38c 100644 --- a/rpki/pubd.py +++ b/rpki/pubd.py @@ -40,6 +40,8 @@ import rpki.publication import rpki.publication_control import rpki.daemonize +from lxml.etree import Element, SubElement, ElementTree, Comment + logger = logging.getLogger(__name__) class main(object): @@ -107,6 +109,9 @@ class main(object): self.publication_multimodule = self.cfg.getboolean("publication-multimodule", False) + self.rrdp_expiration_interval = rpki.sundial.timedelta.parse(self.cfg.get("rrdp-expiration-interval", "6h")) + self.rrdp_publication_base = self.cfg.get("rrdp-publication-base", "rrdp-publication/") + self.session = session_obj.fetch(self) rpki.http.server( @@ -187,11 +192,6 @@ class session_obj(rpki.sql.sql_persistent): "session_id", "uuid") - ## @var expiration_interval - # How long to wait after retiring a snapshot before purging it from the database. - - expiration_interval = rpki.sundial.timedelta(hours = 6) - def __repr__(self): return rpki.log.log_repr(self, self.uuid, self.serial) @@ -231,7 +231,7 @@ class session_obj(rpki.sql.sql_persistent): now = rpki.sundial.now() old_snapshot = self.current_snapshot if old_snapshot is not None: - old_snapshot.expires = now + self.expiration_interval + old_snapshot.expires = now + self.gctx.rrdp_expiration_interval old_snapshot.sql_store() new_snapshot.activated = now new_snapshot.sql_store() @@ -280,40 +280,27 @@ class snapshot_obj(rpki.sql.sql_persistent): Well, OK, only almost the right properties. auto-increment probably does not back up if we ROLLBACK, which could leave gaps - in the sequence. So may need to rework this. Ignore for now. + in the sequence. So may need to rework this, eg, to use a serial + field in the session object. Ignore the issue until we have the + rest of this working. """ return self.snapshot_id - def publish(self, client, obj, uri): - - # Still a bit confused as to what we should do here. The - # overwrite <publish/> with another <publish/> model doens't - # really match the IXFR model. Current proposal is an attribute - # on <publish/> to say that this is an overwrite, haven't - # implemented that yet. Would need to push knowledge of when - # we're overwriting all the way from rpkid code that decides to - # write each kind of object. In most cases it looks like we - # already know, a priori, might be a few corner cases. - - # Temporary kludge - if True: - try: - self.withdraw(client, uri) - except rpki.exceptions.NoObjectAtURI: - logger.debug("Withdrew %s", uri) - else: - logger.debug("No prior %s", uri) - + def publish(self, client, obj, uri, hash): + if hash is not None: + self.withdraw(client, uri, hash) + if object_obj.current_object_at_uri(client, self, uri) is not None: + raise rpki.exceptions.ExistingObjectAtURI("Object already published at %s" % uri) logger.debug("Publishing %s", uri) return object_obj.create(client, self, obj, uri) - def withdraw(self, client, uri): - obj = object_obj.sql_fetch_where1(self.gctx, - "session_id = %s AND client_id = %s AND withdrawn_snapshot_id IS NULL AND uri = %s", - (self.session_id, client.client_id, uri)) + def withdraw(self, client, uri, hash): + obj = object_obj.current_object_at_uri(client, self, uri) if obj is None: raise rpki.exceptions.NoObjectAtURI("No object published at %s" % uri) + if obj.hash != hash: + raise rpki.exceptions.DifferentObjectAtURI("Found different object at %s (%s, %s)" % (uri, obj.hash, hash)) logger.debug("Withdrawing %s", uri) obj.delete(self) @@ -354,8 +341,8 @@ class object_obj(rpki.sql.sql_persistent): self.gctx = snapshot.gctx self.uri = uri self.payload = obj - self.hash = rpki.x509.sha256(obj.get_Base64()) - logger.debug("Computed hash %s of %r", self.hash.encode("hex"), obj) + self.hash = rpki.x509.sha256(obj.get_Base64()).encode("hex") + logger.debug("Computed hash %s of %r", self.hash, obj) self.published_snapshot_id = snapshot.snapshot_id self.withdrawn_snapshot_id = None self.session_id = snapshot.session_id @@ -367,3 +354,9 @@ class object_obj(rpki.sql.sql_persistent): self.withdrawn_snapshot_id = snapshot.snapshot_id #self.sql_mark_dirty() self.sql_store() + + @classmethod + def current_object_at_uri(cls, client, snapshot, uri): + return cls.sql_fetch_where1(client.gctx, + "session_id = %s AND client_id = %s AND withdrawn_snapshot_id IS NULL AND uri = %s", + (snapshot.session_id, client.client_id, uri)) |