コード例 #1
0
    def process_revocation(self, error, srev_info, meta, pld):
        rev_info = srev_info.rev_info()
        status = None
        if error is None:
            status = SCIONDRevReplyStatus.VALID
            self.rev_cache.add(srev_info)
            self.remove_revoked_segments(rev_info)
        else:
            if type(error) == RevInfoValidationError:
                logging.error("Failed to validate RevInfo %s from %s: %s",
                              srev_info.short_desc(), meta, error)
                status = SCIONDRevReplyStatus.INVALID
            if type(error) == RevInfoExpiredError:
                logging.info("Ignoring expired Revinfo, %s from %s", srev_info.short_desc(), meta)
                status = SCIONDRevReplyStatus.STALE
            if type(error) == SignedRevInfoCertFetchError:
                logging.error("Failed to fetch certificate for SignedRevInfo %s from %s: %s",
                              srev_info.short_desc(), meta, error)
                status = SCIONDRevReplyStatus.UNKNOWN
            if type(error) == SignedRevInfoVerificationError:
                logging.error("Failed to verify SRevInfo %s from %s: %s",
                              srev_info.short_desc(), meta, error)
                status = SCIONDRevReplyStatus.SIGFAIL
            if type(error) == SCIONBaseError:
                logging.error("Revocation check failed for %s from %s:\n%s",
                              srev_info.short_desc(), meta, error)
                status = SCIONDRevReplyStatus.UNKNOWN

        if pld:
            rev_reply = SCIONDMsg(SCIONDRevReply.from_values(status), pld.id)
            self.send_meta(rev_reply.pack(), meta)
コード例 #2
0
    def _api_handle_seg_type_request(self, pld, meta):
        request = pld.union
        assert isinstance(request, SCIONDSegTypeHopRequest), type(request)
        segmentType = request.p.type
        db = []
        if segmentType == PST.CORE:
            db = self.core_segments
        elif segmentType == PST.UP:
            db = self.up_segments
        elif segmentType == PST.DOWN:
            db = self.down_segments
        else:
            logging.error("Requesting segment type %s unrecognized.", segmentType)

        seg_entries = []
        for segment in db(full=True):
            if_list = []
            for asm in segment.iter_asms():
                isd_as = asm.isd_as()
                hof = asm.pcbm(0).hof()
                egress = hof.egress_if
                ingress = hof.ingress_if
                if ingress:
                    if_list.append(PathInterface.from_values(isd_as, ingress))
                if egress:
                    if_list.append(PathInterface.from_values(isd_as, egress))
            reply_entry = SCIONDSegTypeHopReplyEntry.from_values(
                if_list, segment.get_timestamp(), segment.get_expiration_time())
            seg_entries.append(reply_entry)
        seg_reply = SCIONDMsg(
            SCIONDSegTypeHopReply.from_values(seg_entries), pld.id)
        self.send_meta(seg_reply.pack(), meta)
コード例 #3
0
ファイル: sciond.py プロジェクト: tobi3988/netsec-scion
 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)
コード例 #4
0
ファイル: sciond.py プロジェクト: xabarass/scion
 def send_rev_notification(self, srev_info):  # pragma: no cover
     req_id = self._req_id.inc()
     rev_not = SCIONDMsg(SCIONDRevNotification.from_values(srev_info), req_id)
     with closing(self._create_socket()) as socket:
         if not socket.send(rev_not.pack()):
             raise SCIONDRequestError
         response = self._get_response(socket, req_id, SMT.REVOCATIONREPLY)
         return response.p.result
     return None
コード例 #5
0
 def get_segtype_hops(self, seg_type):
     req_id = self._req_id.inc()
     valid_pst = set([PST.CORE, PST.UP, PST.DOWN])
     assert seg_type in valid_pst, 'PathSegmentType %s is unrecognized.' % seg_type
     request = SCIONDMsg(SCIONDSegTypeHopRequest.from_values(seg_type), req_id)
     with closing(self._create_socket()) as socket:
         if not socket.send(request.pack()):
             raise SCIONDRequestError
         response = self._get_response(socket, req_id, SMT.SEGTYPEHOP_REPLY)
         return list(response.iter_entries())
コード例 #6
0
 def _api_handle_as_request(self, pld, meta):
     request = pld.union
     assert isinstance(request, SCIONDASInfoRequest), type(request)
     req_ia = request.isd_as()
     if not req_ia or req_ia.is_zero() or req_ia == self.addr.isd_as:
         # Request is for the local AS.
         reply_entry = SCIONDASInfoReplyEntry.from_values(
             self.addr.isd_as, self.is_core_as(), self.topology.mtu)
     else:
         # Request is for a remote AS.
         reply_entry = SCIONDASInfoReplyEntry.from_values(req_ia, self.is_core_as(req_ia))
     as_reply = SCIONDMsg(SCIONDASInfoReply.from_values([reply_entry]), pld.id)
     self.send_meta(as_reply.pack(), meta)
コード例 #7
0
ファイル: sciond.py プロジェクト: tobi3988/netsec-scion
 def _api_handle_as_request(self, pld, meta):
     request = pld.union
     assert isinstance(request, SCIONDASInfoRequest), type(request)
     remote_as = request.isd_as()
     if remote_as:
         reply_entry = SCIONDASInfoReplyEntry.from_values(
             remote_as, self.is_core_as(remote_as))
     else:
         reply_entry = SCIONDASInfoReplyEntry.from_values(
             self.addr.isd_as, self.is_core_as(), self.topology.mtu)
     as_reply = SCIONDMsg(SCIONDASInfoReply.from_values([reply_entry]),
                          pld.id)
     self.send_meta(as_reply.pack(), meta)
コード例 #8
0
 def get_paths(self, dst_ia, src_ia, max_paths, flags=None):
     if not flags:
         flags = PathRequestFlags(flush=False, sibra=False)
     req_id = self._req_id.inc()
     request = SCIONDMsg(SCIONDPathRequest.from_values(
         dst_ia, src_ia, max_paths, flags.flush, flags.sibra), req_id)
     with closing(self._create_socket()) as socket:
         if not socket.send(request.pack()):
             raise SCIONDRequestError
         response = self._get_response(socket, req_id, SMT.PATH_REPLY)
         if response.p.errorCode != SCIONDPathReplyError.OK:
             raise SCIONDResponseError(
                 SCIONDPathReplyError.describe(response.p.errorCode))
         return list(response.iter_entries())
コード例 #9
0
 def _api_handle_if_request(self, pld, meta):
     request = pld.union
     assert isinstance(request, SCIONDIFInfoRequest), type(request)
     all_brs = request.all_brs()
     if_list = []
     if not all_brs:
         if_list = list(request.iter_ids())
     if_entries = []
     for if_id, br in self.ifid2br.items():
         if all_brs or if_id in if_list:
             br_addr, br_port = br.int_addrs.public[0]
             info = HostInfo.from_values([br_addr], br_port)
             reply_entry = SCIONDIFInfoReplyEntry.from_values(if_id, info)
             if_entries.append(reply_entry)
     if_reply = SCIONDMsg(SCIONDIFInfoReply.from_values(if_entries), pld.id)
     self.send_meta(if_reply.pack(), meta)
コード例 #10
0
 def get_as_info(self, isd_as=None):
     q_ia = isd_as
     if not q_ia:
         q_ia = "local"
     with self._as_infos_lock:
         _, as_infos = self._try_cache(self._as_infos, [q_ia])
         as_info = as_infos.get(q_ia)
         if as_info:
             return as_info
         req_id = self._req_id.inc()
         as_req = SCIONDMsg(SCIONDASInfoRequest.from_values(isd_as), req_id)
         with closing(self._create_socket()) as socket:
             if not socket.send(as_req.pack()):
                 raise SCIONDRequestError
             response = self._get_response(socket, req_id, SMT.AS_REPLY)
         self._as_infos[q_ia] = list(response.iter_entries())
         return self._as_infos[q_ia]
コード例 #11
0
 def _api_handle_service_request(self, pld, meta):
     request = pld.union
     assert isinstance(request, SCIONDServiceInfoRequest), type(request)
     all_svcs = request.all_services()
     svc_list = []
     if not all_svcs:
         svc_list = list(request.iter_service_types())
     svc_entries = []
     for svc_type in ServiceType.all():
         if all_svcs or svc_type in svc_list:
             lookup_res = self.dns_query_topo(svc_type)
             host_infos = []
             for addr, port in lookup_res:
                 host_infos.append(HostInfo.from_values([addr], port))
             reply_entry = SCIONDServiceInfoReplyEntry.from_values(
                 svc_type, host_infos)
             svc_entries.append(reply_entry)
     svc_reply = SCIONDMsg(SCIONDServiceInfoReply.from_values(svc_entries), pld.id)
     self.send_meta(svc_reply.pack(), meta)
コード例 #12
0
 def get_service_info(self, service_types=None):
     with self._svc_infos_lock:
         if service_types:
             service_types, svc_infos = self._try_cache(self._svc_infos, service_types)
             if not service_types:
                 # The request could be satisfied with cached IF infos.
                 return svc_infos
         else:
             svc_infos = {}
             service_types = set()
         # Request missing service infos.
         req_id = self._req_id.inc()
         svc_req = SCIONDMsg(SCIONDServiceInfoRequest.from_values(service_types), req_id)
         with closing(self._create_socket()) as socket:
             if not socket.send(svc_req.pack()):
                 raise SCIONDRequestError
             response = self._get_response(socket, req_id, SMT.SERVICE_REPLY)
         for entry in response.iter_entries():
             self._svc_infos[entry.service_type()] = entry
             svc_infos[entry.service_type()] = entry
         return svc_infos
コード例 #13
0
 def get_if_info(self, if_list=None):
     with self._if_infos_lock:
         if if_list:
             if_list, if_infos = self._try_cache(self._if_infos, if_list)
             if not if_list:
                 # The request could be satisfied with cached IF infos.
                 return if_infos
         else:
             if_infos = {}
             if_list = set()
         # Request missing IF infos.
         req_id = self._req_id.inc()
         if_req = SCIONDMsg(SCIONDIFInfoRequest.from_values(if_list), req_id)
         with closing(self._create_socket()) as socket:
             if not socket.send(if_req.pack()):
                 raise SCIONDRequestError
             response = self._get_response(socket, req_id, SMT.IF_REPLY)
         for entry in response.iter_entries():
             self._if_infos[entry.p.ifID] = entry
             if_infos[entry.p.ifID] = entry
         return if_infos
コード例 #14
0
 def handle_msg_meta(self, msg, meta):
     """
     Main routine to handle incoming SCION messages.
     """
     if isinstance(meta, SockOnlyMetadata):  # From SCIOND API
         try:
             sciond_msg = SCIONDMsg.from_raw(msg)
         except SCIONParseError as err:
             logging.error(str(err))
             return
         self.api_handle_request(sciond_msg, meta)
         return
     super().handle_msg_meta(msg, meta)
コード例 #15
0
 def _get_response(self, socket, expected_id, expected_type):  # pragma: no cover
     try:
         data = socket.recv()[0]
     except timeout:
         raise SCIONDResponseError("Socket timed out.")
     except SCIONIOError:
         raise SCIONDResponseError("Socket IO error.")
     if not data:
         raise SCIONDResponseError("Received empty response from SCIOND.")
     try:
         response = SCIONDMsg.from_raw(data)
     except SCIONParseError as e:
         raise SCIONDResponseError(str(e))
     if response.type() != expected_type:
         raise SCIONDResponseError(
             "Unexpected SCIOND msg type received: %s" % response.NAME)
     if response.id != expected_id:
         raise SCIONDResponseError("Wrong response ID: %d (expected %d)" %
                                   (response.id, expected_id))
     return response.union
コード例 #16
0
 def send_rev_notification(self, srev_info):  # pragma: no cover
     rev_not = SCIONDMsg(SCIONDRevNotification.from_values(srev_info),
                         self._req_id.inc())
     with closing(self._create_socket()) as socket:
         if not socket.send(rev_not.pack()):
             raise SCIONDRequestError
コード例 #17
0
 def _send_path_reply(self, req_id, reply_entries, error, meta):
     path_reply = SCIONDMsg(SCIONDPathReply.from_values(reply_entries, error), req_id)
     self.send_meta(path_reply.pack(), meta)