示例#1
0
 def _send_ifstate_update(self,
                          state_infos,
                          border_metas,
                          server_metas=None):
     server_metas = server_metas or []
     payload = CtrlPayload(PathMgmt(
         IFStatePayload.from_values(state_infos)))
     for meta in border_metas:
         self.send_meta(payload.copy(), meta, (meta.host, meta.port))
     for meta in server_metas:
         self.send_meta(payload.copy(), meta)
示例#2
0
 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)
示例#3
0
    def _resolve_not_core_failed(self, seg_req, req_id, meta, dst_ia, flags, logger):
        """
        Execute after _resolve_not_core() cannot resolve a new request, due to
        lack of corresponding down segment(s).
        This must not be executed for a pending request.
        """
        sibra = PATH_FLAG_SIBRA in flags
        with self.pen_req_lock:
            self.pending_req[(dst_ia, sibra)][str(meta)] = (seg_req, req_id, meta, logger)
        if dst_ia[0] == self.addr.isd_as[0]:
            # Master may know down segment as dst is in local ISD.
            self._query_master(dst_ia, logger, flags=flags)
            return

        # Dst is in a remote ISD, ask any core AS from there. Don't use a SIBRA
        # segment, even if the request has the SIBRA flag set, as this is just
        # for basic internal communication.
        csegs = self.core_segments(
            first_isd=dst_ia[0], last_ia=self.addr.isd_as)
        if csegs:
            cseg = csegs[0]
            path = cseg.get_path(reverse_direction=True)
            dst_ia = cseg.first_ia()
            logger.info("Down-Segment request for different ISD, "
                        "forwarding request to CPS in %s via %s" %
                        (dst_ia, cseg.short_desc()))
            meta = self._build_meta(ia=dst_ia, path=path,
                                    host=SVCType.PS_A, reuse=True)
            self.send_meta(CtrlPayload(PathMgmt(seg_req)), meta)
        else:
            # If no core segment was available, add request to waiting targets.
            logger.info("Waiting for core segment to ISD %s", dst_ia[0])
            self.waiting_targets[dst_ia[0]].append((seg_req, logger))
            # Ask for any segment to dst_isd
            self._query_master(dst_ia.any_as(), logger)
示例#4
0
 def _api_handle_rev_notification(self, pld, meta):
     request = pld.union
     assert isinstance(request, SCIONDRevNotification), type(request)
     status = self.handle_revocation(
         CtrlPayload(PathMgmt(request.rev_info())), meta)
     rev_reply = SCIONDMsg(SCIONDRevReply.from_values(status), pld.id)
     self.send_meta(rev_reply.pack(), meta)
示例#5
0
文件: base.py 项目: stschwar/scion
 def _send_path_segments(self,
                         req,
                         req_id,
                         meta,
                         logger,
                         up=None,
                         core=None,
                         down=None):
     """
     Sends path-segments to requester (depending on Path Server's location).
     """
     up = up or set()
     core = core or set()
     down = down or set()
     all_segs = up | core | down
     if not all_segs:
         logger.warning("No segments to send for request: %s from: %s" %
                        (req.short_desc(), meta))
         return
     revs_to_add = self._peer_revs_for_segs(all_segs)
     recs = PathSegmentRecords.from_values(
         {
             PST.UP: up,
             PST.CORE: core,
             PST.DOWN: down
         }, revs_to_add)
     pld = PathSegmentReply.from_values(req.copy(), recs)
     self.send_meta(CtrlPayload(PathMgmt(pld), req_id=req_id), meta)
     logger.info("Sending PATH_REPLY with %d segment(s).", len(all_segs))
示例#6
0
文件: main.py 项目: stschwar/scion
    def process_drkey_request(self, cpld, meta):
        """
        Process first order DRKey requests from other ASes.

        :param DRKeyRequest req: the DRKey request
        :param UDPMetadata meta: the metadata
        """
        dpld = cpld.union
        req = dpld.union
        assert isinstance(req, DRKeyRequest), type(req)
        logging.info("DRKeyRequest received from %s: %s [id: %s]", meta,
                     req.short_desc(), cpld.req_id_str())
        REQS_TOTAL.labels(**self._labels, type="drkey").inc()
        try:
            cert = self._verify_drkey_request(req, meta)
        except SCIONVerificationError as e:
            logging.warning("Invalid DRKeyRequest from %s. Reason %s: %s",
                            meta, e, req.short_desc())
            return
        sv = self._get_drkey_secret(get_drkey_exp_time(req.p.flags.prefetch))
        cert_version = self.trust_store.get_cert(
            self.addr.isd_as).certs[0].version
        trc_version = self.trust_store.get_trc(self.addr.isd_as[0]).version
        rep = get_drkey_reply(sv, self.addr.isd_as, meta.ia, self.private_key,
                              self.signing_key, cert_version, cert,
                              trc_version)
        self.send_meta(CtrlPayload(DRKeyMgmt(rep), req_id=cpld.req_id), meta)
        logging.info("DRKeyReply sent to %s: %s [id: %s]", meta,
                     req.short_desc(), cpld.req_id_str())
示例#7
0
 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)
示例#8
0
 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)
示例#9
0
文件: main.py 项目: stschwar/scion
    def _fetch_drkey(self, drkey, _):
        """
        Fetch missing first order DRKey with the same (SrcIA, DstIA, expTime).

        :param FirstOrderDRKey drkey: The missing DRKey.
        """
        cert = self.trust_store.get_cert(self.addr.isd_as)
        trc = self.trust_store.get_trc(self.addr.isd_as[0])
        if not cert or not trc:
            logging.warning(
                "DRKeyRequest for %s not sent. Own CertChain/TRC not present.",
                drkey.src_ia)
            return
        req = get_drkey_request(drkey.src_ia, False, self.signing_key,
                                cert.certs[0].version, trc.version)
        path_meta = self._get_path_via_sciond(drkey.src_ia)
        if path_meta:
            meta = self._build_meta(drkey.src_ia,
                                    host=SVCType.CS_A,
                                    path=path_meta.fwd_path())
            req_id = mk_ctrl_req_id()
            self.send_meta(CtrlPayload(DRKeyMgmt(req)), meta)
            logging.info("DRKeyRequest (%s) sent to %s via %s [id: %016x]",
                         req.short_desc(), meta, path_meta, req_id)
        else:
            logging.warning("DRKeyRequest (for %s) not sent", req.short_desc())
示例#10
0
文件: steady.py 项目: xabarass/scion
 def _create_hdrs(self):
     """
     Create headers for a SCION packet
     """
     dest = SCIONAddr.from_values(self.remote, SVCType.SB_A)
     cmn_hdr, addr_hdr = build_base_hdrs(dest, self.addr)
     payload = CtrlPayload(SIBRAPayload.from_values())
     udp_hdr = SCIONUDPHeader.from_values(self.addr, self._port, dest, 0)
     return cmn_hdr, addr_hdr, udp_hdr, payload
示例#11
0
文件: base.py 项目: stschwar/scion
 def _handle_scmp_revocation(self, pld, meta):
     rev_info = RevocationInfo.from_raw(pld.info.rev_info)
     try:
         rev_info.validate()
     except SCIONBaseError as e:
         logging.warning("Failed to validate SCMP RevInfo from %s: %s\n%s",
                         meta, e, rev_info.short_desc())
         return
     self._handle_revocation(CtrlPayload(PathMgmt(rev_info)), meta)
示例#12
0
文件: main.py 项目: stschwar/scion
 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))
示例#13
0
文件: main.py 项目: stschwar/scion
 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))
示例#14
0
 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)
示例#15
0
 def register_down_segment(self, pcb):
     """
     Send down-segment to Core Path Server
     """
     pcb.sign(self.signing_key)
     core_path = pcb.get_path(reverse_direction=True)
     records = PathRecordsReg.from_values({PST.DOWN: [pcb]})
     dst_ia = pcb.asm(0).isd_as()
     meta = self._build_meta(ia=dst_ia, host=SVCType.PS_A, path=core_path, reuse=True)
     self.send_meta(CtrlPayload(PathMgmt(records)), meta)
     return meta
示例#16
0
 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())
示例#17
0
 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())
示例#18
0
    def sign(self, pld: CtrlPayload) -> SignedCtrlPayload:
        """
        Creates a signed version of the supplied control payload.

        :param CtrlPayload pld: The control payload to be signed
        :returns: the signed control payload
        :rtype: SignedCtrlPayload
        :raises: ProtoSignError
        """
        sig_pld = SignedCtrlPayload.from_values(pld.proto().to_bytes_packed(),
                                                self._sign.copy())
        sig_pld.sign(self._key)
        return sig_pld
示例#19
0
 def _fetch_segments(self, req):
     """
     Called to fetch the requested path.
     """
     try:
         addr, port = self.dns_query_topo(PATH_SERVICE)[0]
     except SCIONServiceLookupError:
         log_exception("Error querying path service:")
         return
     logging.debug("Sending path request (%s) to [%s]:%s", req.short_desc(),
                   addr, port)
     meta = self._build_meta(host=addr, port=port)
     self.send_meta(CtrlPayload(PathMgmt(req)), meta)
示例#20
0
    def handle_ifstate_infos(self, cpld, meta):
        """
        Handles IFStateInfos.

        :param IFStatePayload infos: The state info objects.
        """
        pmgt = cpld.union
        infos = pmgt.union
        assert isinstance(infos, IFStatePayload), type(infos)
        for info in infos.iter_infos():
            if not info.p.active and info.p.sRevInfo:
                self._handle_revocation(
                    CtrlPayload(PathMgmt(info.srev_info())), meta)
示例#21
0
    def register_up_segment(self, pcb, svc_type):
        """
        Send up-segment to Local Path Servers and Sibra Servers

        :raises:
            SCIONServiceLookupError: service type lookup failure
        """
        pcb.sign(self.signing_key)
        records = PathRecordsReg.from_values({PST.UP: [pcb]})
        addr, port = self.dns_query_topo(svc_type)[0]
        meta = self._build_meta(host=addr, port=port)
        self.send_meta(CtrlPayload(PathMgmt(records)), meta)
        return meta
示例#22
0
文件: base.py 项目: xabarass/scion
 def _handle_pcbs_from_zk(self, pcbs):
     """
     Handles cached pcbs through ZK, passed as a list.
     """
     for pcb in pcbs:
         try:
             pcb = PCB.from_raw(pcb)
         except SCIONParseError as e:
             logging.error("Unable to parse raw pcb: %s", e)
             continue
         self.handle_pcb(CtrlPayload(pcb))
     if pcbs:
         logging.debug("Processed %s PCBs from ZK", len(pcbs))
示例#23
0
 def _send_ifstate_update(self, border_metas, server_metas=None):
     server_metas = server_metas or []
     with self.ifid_state_lock:
         infos = []
         for (ifid, state) in self.ifid_state.items():
             # Don't include inactive interfaces in update.
             if state.is_inactive():
                 continue
             rev_info = self._get_ht_proof(
                 ifid) if state.is_revoked() else None
             info = IFStateInfo.from_values(ifid, state.is_active(),
                                            rev_info)
             infos.append(info)
         if not infos and not self._quiet_startup():
             logging.warning(
                 "No IF state info to put in IFState update for %s.",
                 ", ".join([str(m) for m in border_metas + server_metas]))
             return
         payload = CtrlPayload(PathMgmt(IFStatePayload.from_values(infos)))
     for meta in border_metas:
         self.send_meta(payload.copy(), meta, (meta.host, meta.port))
     for meta in server_metas:
         self.send_meta(payload.copy(), meta)
示例#24
0
    def register_core_segment(self, pcb, svc_type):
        """
        Send core-segment to Local Path Servers and Sibra Servers

        :raises:
            SCIONServiceLookupError: service type lookup failure
        """
        pcb.sign(self.signing_key)
        # Register core path with local core path server.
        addr, port = self.dns_query_topo(svc_type)[0]
        records = PathRecordsReg.from_values({PST.CORE: [pcb]})
        meta = self._build_meta(host=addr, port=port, reuse=True)
        self.send_meta(CtrlPayload(PathMgmt(records.copy())), meta)
        return meta
示例#25
0
 def _fetch_segments(self, req):
     """
     Called to fetch the requested path.
     """
     try:
         addr, port = self.dns_query_topo(ServiceType.PS)[0]
     except SCIONServiceLookupError:
         log_exception("Error querying path service:")
         return
     req_id = mk_ctrl_req_id()
     logging.debug("Sending path request (%s) to [%s]:%s [id: %016x]",
                   req.short_desc(), addr, port, req_id)
     meta = self._build_meta(host=addr, port=port)
     self.send_meta(CtrlPayload(PathMgmt(req), req_id=req_id), meta)
示例#26
0
 def _send_waiting_queries(self, dst_isd, pcb):
     targets = self.waiting_targets[dst_isd]
     if not targets:
         return
     path = pcb.get_path(reverse_direction=True)
     src_ia = pcb.first_ia()
     while targets:
         (seg_req, logger) = targets.pop(0)
         meta = self._build_meta(ia=src_ia,
                                 path=path,
                                 host=SVCType.PS_A,
                                 reuse=True)
         self.send_meta(CtrlPayload(PathMgmt(seg_req)), meta)
         logger.info("Waiting request (%s) sent to %s via %s",
                     seg_req.short_desc(), meta, pcb.short_desc())
示例#27
0
 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()))
示例#28
0
 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()))
示例#29
0
 def _handle_pending_requests(self):
     rem_keys = []
     # Serve pending requests.
     with self.pen_req_lock:
         for key in self.pending_req:
             for req_id, (req, meta,
                          logger) in self.pending_req[key].items():
                 if self.path_resolution(CtrlPayload(PathMgmt(req)),
                                         meta,
                                         new_request=False,
                                         logger=logger):
                     meta.close()
                     del self.pending_req[key][req_id]
             if not self.pending_req[key]:
                 rem_keys.append(key)
         for key in rem_keys:
             del self.pending_req[key]
示例#30
0
文件: base.py 项目: xabarass/scion
 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)