def process_trc_reply(self, cpld, meta): """ Process the TRC reply. :param rep: TRC reply. :type rep: TRCReply. """ meta.close() cmgt = cpld.union rep = cmgt.union assert isinstance(rep, TRCReply), type(rep) isd, ver = rep.trc.get_isd_ver() logging.info("TRC reply received for %sv%s from %s [id: %s]", isd, ver, meta, cpld.req_id_str()) self.trust_store.add_trc(rep.trc, True) # Update core ases for isd this trc belongs to max_local_ver = self.trust_store.get_trc(rep.trc.isd) if max_local_ver.version == rep.trc.version: self._update_core_ases(rep.trc) with self.req_trcs_lock: self.requested_trcs.pop((isd, ver), None) if self._labels: PENDING_TRC_REQS_TOTAL.labels(**self._labels).set(len(self.requested_trcs)) # Send trc to CS if meta.get_addr().isd_as != self.addr.isd_as: cs_meta = self._get_cs() self.send_meta(CtrlPayload(CertMgmt(rep)), cs_meta) cs_meta.close() # Remove received TRC from map self._check_segs_with_rec_trc(isd, ver)
def _reply_trc(self, key, req_info): isd, ver = key ver = None if ver == TRCRequest.NEWEST_VERSION else ver meta = req_info[0] trc = self.trust_store.get_trc(isd, ver) self.send_meta(CtrlPayload(CertMgmt(TRCReply.from_values(trc))), meta) logging.info("TRC for %sv%s sent to %s", isd, ver, meta)
def _reply_cc(self, key, req_info): isd_as, ver = key ver = None if ver == CertChainRequest.NEWEST_VERSION else ver meta = req_info[0] cert_chain = self.trust_store.get_cert(isd_as, ver) self.send_meta(CtrlPayload(CertMgmt(CertChainReply.from_values(cert_chain))), meta) logging.info("Cert chain for %sv%s sent to %s", isd_as, ver, meta)
def _cached_certs_handler(self, raw_entries): """ Handles cached (through ZK) chains, passed as a list. """ for raw in raw_entries: cert = CertificateChain.from_raw(raw.decode('utf-8')) rep = CtrlPayload(CertMgmt(CertChainReply.from_values(cert))) self.process_cert_chain_reply(rep, None, from_zk=True) if len(raw_entries) > 0: logging.debug("Processed %s certs from ZK", len(raw_entries))
def _cached_trcs_handler(self, raw_entries): """ Handles cached (through ZK) TRCs, passed as a list. """ for raw in raw_entries: trc = TRC.from_raw(raw.decode('utf-8')) rep = CtrlPayload(CertMgmt(TRCReply.from_values(trc))) self.process_trc_reply(rep, None, from_zk=True) if len(raw_entries) > 0: logging.debug("Processed %s trcs from ZK", len(raw_entries))
def _reply_cc(self, key, req_info): isd_as, ver = key meta = req_info[0] req_id = req_info[2] cert_chain = self.trust_store.get_cert(isd_as, ver) self.send_meta( CtrlPayload(CertMgmt(CertChainReply.from_values(cert_chain)), req_id=req_id), meta) logging.info("Cert chain for %sv%s sent to %s [id: %016x]", isd_as, ver, meta, req_id)
def _send_trc_request(self, isd, ver): trc_req = TRCRequest.from_values(isd, ver, cache_only=True) path_meta = self._get_path_via_sciond(trc_req.isd_as()) if path_meta: meta = self._build_meta( path_meta.dst_ia(), host=SVCType.CS_A, path=path_meta.fwd_path()) self.send_meta(CtrlPayload(CertMgmt(trc_req)), meta) logging.info("TRC request sent to %s via [%s]: %s", meta, path_meta.short_desc(), trc_req.short_desc()) else: logging.warning("TRC request not sent for %s: no path found.", trc_req.short_desc())
def _send_cc_request(self, isd_as, ver): req = CertChainRequest.from_values(isd_as, ver, cache_only=True) path_meta = self._get_path_via_sciond(isd_as) if path_meta: meta = self._build_meta(isd_as, host=SVCType.CS_A, path=path_meta.fwd_path()) self.send_meta(CtrlPayload(CertMgmt(req)), meta) logging.info("Cert chain request sent to %s via [%s]: %s", meta, path_meta.short_desc(), req.short_desc()) else: logging.warning("Cert chain request (for %s) not sent: " "no path found", req.short_desc())
def process_cert_chain_request(self, cpld, meta): """Process a certificate chain request.""" cmgt = cpld.union req = cmgt.union assert isinstance(req, CertChainRequest), type(req) isd_as, ver = req.isd_as(), req.p.version logging.info("Cert chain request received for %sv%s from %s [id: %s]" % (isd_as, ver, meta, cpld.req_id_str())) cert = self.trust_store.get_cert(isd_as, ver) if cert: self.send_meta( CtrlPayload(CertMgmt(CertChainReply.from_values(cert)), req_id=cpld.req_id), meta) else: logging.warning("Could not find requested certificate %sv%s [id: %s]" % (isd_as, ver, cpld.req_id_str()))
def process_trc_request(self, cpld, meta): """Process a TRC request.""" cmgt = cpld.union req = cmgt.union assert isinstance(req, TRCRequest), type(req) isd, ver = req.isd_as()[0], req.p.version logging.info("TRC request received for %sv%s from %s [id: %s]" % (isd, ver, meta, cpld.req_id_str())) trc = self.trust_store.get_trc(isd, ver) if trc: self.send_meta( CtrlPayload(CertMgmt(TRCReply.from_values(trc)), req_id=cpld.req_id), meta) else: logging.warning("Could not find requested TRC %sv%s [id: %s]" % (isd, ver, cpld.req_id_str()))
def _check_local_cert(self): while self.run_flag.is_set(): chain = self._get_my_cert() exp = min(chain.as_cert.expiration_time, chain.core_as_cert.expiration_time) diff = exp - int(time.time()) if diff > self.config.segment_ttl: time.sleep(diff - self.config.segment_ttl) continue cs_meta = self._get_cs() req = CertChainRequest.from_values(self.addr.isd_as, chain.as_cert.version + 1, cache_only=True) logging.info("Request new certificate chain. Req: %s", req) self.send_meta(CtrlPayload(CertMgmt(req)), cs_meta) cs_meta.close() time.sleep(self.CERT_REQ_RATE)
def _check_trc_reqs(self): """ Checks if TRC requests timeout and resends requests if so. """ with self.req_trcs_lock: now = time.time() for (isd, ver), (req_time, meta) in self.requested_trcs.items(): if now - req_time >= self.TRC_CC_REQ_TIMEOUT: trc_req = TRCRequest.from_values(isd, ver, cache_only=True) meta = meta or self._get_cs() req_id = mk_ctrl_req_id() logging.info("Re-Requesting TRC from %s: %s [id: %016x]", meta, trc_req.short_desc(), req_id) self.send_meta(CtrlPayload(CertMgmt(trc_req), req_id=req_id), meta) self.requested_trcs[(isd, ver)] = (time.time(), meta) if self._labels: PENDING_TRC_REQS_TOTAL.labels(**self._labels).set(len(self.requested_trcs))
def _check_cert_reqs(self): """ Checks if certificate requests timeout and resends requests if so. """ with self.req_certs_lock: now = time.time() for (isd_as, ver), (req_time, meta) in self.requested_certs.items(): if now - req_time >= self.TRC_CC_REQ_TIMEOUT: cert_req = CertChainRequest.from_values(isd_as, ver, cache_only=True) meta = meta or self._get_cs() req_id = mk_ctrl_req_id() logging.info("Re-Requesting CERTCHAIN from %s: %s [id: %016x]", meta, cert_req.short_desc(), req_id) self.send_meta(CtrlPayload(CertMgmt(cert_req), req_id=req_id), meta) self.requested_certs[(isd_as, ver)] = (time.time(), meta) if self._labels: PENDING_CERT_REQS_TOTAL.labels(**self._labels).set( len(self.requested_certs))
def process_cert_chain_reply(self, cpld, meta): """Process a certificate chain reply.""" cmgt = cpld.union rep = cmgt.union assert isinstance(rep, CertChainReply), type(rep) meta.close() isd_as, ver = rep.chain.get_leaf_isd_as_ver() logging.info("Cert chain reply received for %sv%s from %s [id: %s]", isd_as, ver, meta, cpld.req_id_str()) self.trust_store.add_cert(rep.chain, True) with self.req_certs_lock: self.requested_certs.pop((isd_as, ver), None) if self._labels: PENDING_CERT_REQS_TOTAL.labels(**self._labels).set(len(self.requested_certs)) # Send cc to CS if meta.get_addr().isd_as != self.addr.isd_as: cs_meta = self._get_cs() self.send_meta(CtrlPayload(CertMgmt(rep)), cs_meta) cs_meta.close() # Remove received cert chain from map self._check_segs_with_rec_cert(isd_as, ver)
def _request_missing_certs(self, seg_meta): """ For all missing CCs which are missing to verify this pcb/path segment, request them. Request is sent to certificate server, if the pcb/path segment was received by zk. Otherwise the sender of this pcb/path segment is asked. """ missing_certs = set() with seg_meta.miss_cert_lock: missing_certs = seg_meta.missing_certs.copy() if not missing_certs: return for isd_as, ver in missing_certs: with self.req_certs_lock: req_time, meta = self.requested_certs.get((isd_as, ver), (None, None)) if meta: # There is already an outstanding request for the missing cert # from somewhere else than than the local CS if seg_meta.meta: # Update the stored meta with the latest known server that has the cert. self.requested_certs[(isd_as, ver)] = (req_time, seg_meta.meta) continue if req_time and not seg_meta.meta: # There is already an outstanding request for the missing cert # to the local CS and we don't have a new meta. continue cert_req = CertChainRequest.from_values(isd_as, ver, cache_only=True) meta = seg_meta.meta or self._get_cs() if not meta: logging.error("Couldn't find a CS to request CERTCHAIN for PCB %s", seg_meta.seg.short_id()) continue req_id = mk_ctrl_req_id() logging.info("Requesting %sv%s CERTCHAIN from %s for PCB %s [id: %016x]", isd_as, ver, meta, seg_meta.seg.short_id(), req_id) with self.req_certs_lock: self.requested_certs[(isd_as, ver)] = (time.time(), seg_meta.meta) if self._labels: PENDING_CERT_REQS_TOTAL.labels(**self._labels).set(len(self.requested_certs)) self.send_meta(CtrlPayload(CertMgmt(cert_req), req_id=req_id), meta)
def _create_payload(self, _): if not self.cert: return CtrlPayload(CertMgmt(CertChainRequest.from_values( self.dst_ia, CertChainRequest.NEWEST_VERSION))) return CtrlPayload( CertMgmt(TRCRequest.from_values(self.dst_ia[0], TRCRequest.NEWEST_VERSION)))