Exemplo n.º 1
0
 def get_paths_info(self, dst_isd_as):
     lib_sciond.init(get_sciond_api_addr(self.addr))
     paths = []
     for reply in lib_sciond.get_paths(dst_isd_as):
         paths.append((reply.path().fwd_path(), reply.first_hop().ipv4(),
                       reply.first_hop().p.port))
     return paths
Exemplo n.º 2
0
    def __init__(self, server_id, conf_dir):
        """
        :param str server_id: server identifier.
        :param str conf_dir: configuration directory.
        """
        super().__init__(server_id, conf_dir)
        self.cc_requests = RequestHandler.start(
            "CC Requests",
            self._check_cc,
            self._fetch_cc,
            self._reply_cc,
        )
        self.trc_requests = RequestHandler.start(
            "TRC Requests",
            self._check_trc,
            self._fetch_trc,
            self._reply_trc,
        )
        self.drkey_protocol_requests = RequestHandler.start(
            "DRKey Requests",
            self._check_drkey,
            self._fetch_drkey,
            self._reply_proto_drkey,
        )

        self.CTRL_PLD_CLASS_MAP = {
            PayloadClass.CERT: {
                CertMgmtType.CERT_CHAIN_REQ: self.process_cert_chain_request,
                CertMgmtType.CERT_CHAIN_REPLY: self.process_cert_chain_reply,
                CertMgmtType.TRC_REQ: self.process_trc_request,
                CertMgmtType.TRC_REPLY: self.process_trc_reply,
            },
            PayloadClass.DRKEY: {
                DRKeyMgmtType.FIRST_ORDER_REQUEST: self.process_drkey_request,
                DRKeyMgmtType.FIRST_ORDER_REPLY: self.process_drkey_reply,
            },
        }

        zkid = ZkID.from_values(self.addr.isd_as, self.id,
                                [(self.addr.host, self._port)]).pack()
        self.zk = Zookeeper(self.topology.isd_as, CERTIFICATE_SERVICE, zkid,
                            self.topology.zookeepers)
        self.zk.retry("Joining party", self.zk.party_setup)
        self.trc_cache = ZkSharedCache(self.zk, self.ZK_TRC_CACHE_PATH,
                                       self._cached_trcs_handler)
        self.cc_cache = ZkSharedCache(self.zk, self.ZK_CC_CACHE_PATH,
                                      self._cached_certs_handler)
        self.drkey_cache = ZkSharedCache(self.zk, self.ZK_DRKEY_PATH,
                                         self._cached_drkeys_handler)

        lib_sciond.init(
            os.path.join(SCIOND_API_SOCKDIR, "sd%s.sock" % self.addr.isd_as))
        self.signing_key = get_sig_key(self.conf_dir)
        self.private_key = get_enc_key(self.conf_dir)
        self.public_key = self.private_key.public_key
        self.drkey_secrets = ExpiringDict(DRKEY_MAX_SV, DRKEY_MAX_TTL)
        self.first_order_drkeys = ExpiringDict(DRKEY_MAX_KEYS, DRKEY_MAX_TTL)
Exemplo n.º 3
0
 def get_path(self, dst_isd_as):
     lib_sciond.init(get_sciond_api_addr(self.addr))
     replies = lib_sciond.get_paths(dst_isd_as)
     if not replies:
         return None
     # TODO(PSz): Very hacky to avoid changing scion_elem and/or giving topo files for
     # every element.
     path = replies[0].path().fwd_path()
     ifid = path.get_fwd_if()
     if ifid not in self.ifid2br:
         br = Element()
         br.addr = replies[0].first_hop().ipv4()
         br.port = replies[0].first_hop().p.port
         self.ifid2br[ifid] = br
     return path
Exemplo n.º 4
0
 def __init__(self, finished, addr):
     # We need the lib sciond here already.
     connector = lib_sciond.init(get_sciond_api_addr(addr))
     cs_info = lib_sciond.get_service_info(
         [ServiceType.CS], connector=connector)[ServiceType.CS]
     cs = cs_info.host_info(0)
     cs_addr = SCIONAddr.from_values(addr.isd_as, cs.ipv4() or cs.ipv6())
     self.cert_done = False
     super().__init__("", finished, addr, cs_addr, cs.p.port)
Exemplo n.º 5
0
 def __init__(self, data, finished, addr, timeout=1.0, api_addr=None):
     self.api_addr = api_addr or get_sciond_api_addr(addr)
     self.data = data
     self.finished = finished
     self.addr = addr
     self._timeout = timeout
     self.sock = self._create_socket(addr)
     assert self.sock
     self.success = None
     self._connector = lib_sciond.init(self.api_addr)
Exemplo n.º 6
0
def print_as_viewer_info(addr):
    '''
    Attempt sciond connection if needed, and print requested AS data.
    :param addr: Optional IP Address for sciond socket binding when not
        localhost.
    '''
    try:
        # init connection to sciond
        conf_dir = "%s/%s/ISD%s/AS%s/endhost" % (
            SCION_ROOT, GEN_PATH, s_isd_as.isd_str(), s_isd_as.as_file_fmt())
        sock_file = get_default_sciond_path(s_isd_as)
        if not pathlib.Path(sock_file).exists():
            sock_file = get_default_sciond_path(None)
        connector[s_isd_as] = lib_sciond.init(sock_file)
        logging.info(connector[s_isd_as]._api_addr)
        try:  # test if sciond is already running for this AS
            logging.info("Starting sciond at %s" % sock_file)
            lib_sciond.get_as_info(connector=connector[s_isd_as])
        except (SCIONDResponseError) as err:
            logging.error("%s: %s" % (err.__class__.__name__, err))
            return
        except (SCIONDConnectionError, FileNotFoundError) as err:
            logging.warning("%s: %s" % (err.__class__.__name__, err))
            # need to launch sciond, wait for uptime
            launch_sciond(sock_file, conf_dir, addr, s_isd_as)
        if args.t:  # as topology
            print_as_topology(s_isd_as, connector)
        if args.p:  # announced paths
            print_paths(s_isd_as, d_isd_as, connector)
        if args.c:  # config
            print_yml(os.path.join(conf_dir, AS_CONF_FILE))
        if args.pp:  # path policy
            print_yml(os.path.join(conf_dir, PATH_POLICY_FILE))
        if args.trc:  # TRC
            print_json_files(findCerts(conf_dir, ".trc"))
        if args.crt:  # cert chain
            print_json_files(findCerts(conf_dir, ".crt"))
        if args.s:  # segments
            print_segments_summary(s_isd_as, connector)
    except (SCIONBaseError, AttributeError) as err:
        logging.error("%s: %s" % (err.__class__.__name__, err))
Exemplo n.º 7
0
def index(request):
    '''
    Main index handler for index.html for main visualization page.
    Validates parameters, request scion data, returns formatted response.
    :param request: HTML request object containing url parameters.
    '''
    p = {}  # return param dictionary
    p['tab'] = set_param(request, 'tab', 'tab-pathtopo')
    p['data'] = set_param(request, 'data', 'sdapi')
    p['addr'] = set_param(request, 'addr', '')
    p['src'] = set_param(request, 'src', '')
    p['dst'] = set_param(request, 'dst', '')
    p['mp'] = set_param(request, 'mp', '5')
    p['err'] = ''
    if (p['src'] == '' and p['dst'] == ''):
        # use endhost gen/ia if no host specified
        if (p['src'] == ''):
            ia_file = "%s/%s/ia" % (SCION_ROOT, GEN_PATH)
            try:
                with open(ia_file, 'r') as fin:
                    # load and reformat
                    p['src'] = str(ISD_AS(fin.read().strip()))
            except (FileNotFoundError) as err:
                logging.warning("%s: %s" % (err.__class__.__name__, err))
        return fmt_err(request, p)
    s_isd_as = ISD_AS(p['src'])
    d_isd_as = ISD_AS(p['dst'])
    p['src'], p['dst'] = str(s_isd_as), str(d_isd_as)  # reformat
    csegs = dsegs = usegs = []
    paths = ''
    logging.info("Requesting sciond data from %s to %s" % (s_isd_as, d_isd_as))
    conf_dir = "%s/%s/ISD%s/AS%s/endhost" % (
        SCION_ROOT, GEN_PATH, s_isd_as.isd_str(), s_isd_as.as_file_fmt())
    sock_file = get_default_sciond_path(s_isd_as)
    if not pathlib.Path(sock_file).exists():
        sock_file = get_default_sciond_path(None)
    try:
        if (p['data'] == 'sdapi'):
            connector[s_isd_as] = lib_sciond.init(sock_file)
            logging.info(connector[s_isd_as]._api_addr)
            try:  # test if sciond is already running for this AS
                logging.info("Testing sciond at %s" % sock_file)
                lib_sciond.get_as_info(connector=connector[s_isd_as])
            except (SCIONDResponseError) as err:
                p['err'] = "%s: %s" % (err.__class__.__name__, err)
                return fmt_err(request, p)
            except (SCIONDConnectionError, FileNotFoundError) as err:
                logging.warning("%s: %s" % (err.__class__.__name__, err))
                # need to launch sciond, wait for uptime
                launch_sciond(sock_file, conf_dir, p['addr'], s_isd_as)

            if (p['dst'] != ''):  # PATHS
                try:
                    # get paths and keep segments
                    flags = lib_sciond.PathRequestFlags(flush=False,
                                                        sibra=False)
                    paths = lib_sciond.get_paths(d_isd_as,
                                                 max_paths=int(p['mp']),
                                                 flags=flags,
                                                 connector=connector[s_isd_as])
                    csegs = lib_sciond.get_segtype_hops(
                        PST.CORE, connector=connector[s_isd_as])
                    dsegs = lib_sciond.get_segtype_hops(
                        PST.DOWN, connector=connector[s_isd_as])
                    usegs = lib_sciond.get_segtype_hops(
                        PST.UP, connector=connector[s_isd_as])
                    # refresh old segments for next call
                    flags = lib_sciond.PathRequestFlags(flush=True,
                                                        sibra=False)
                    lib_sciond.get_paths(d_isd_as,
                                         max_paths=int(p['mp']),
                                         flags=flags,
                                         connector=connector[s_isd_as])
                except (SCIONDResponseError, SCIONDConnectionError,
                        AttributeError) as err:
                    # AttributeError handles backward-compatability
                    logging.error("%s: %s" % (err.__class__.__name__, err))
                    p['err'] = str(err)
            p['json_as_topo'] = json.dumps(
                get_json_as_topology_sciond(connector[s_isd_as], paths))
            p['json_trc'] = ("TRC information for sciond not yet implemented.")
            p['json_crt'] = (
                "Certificate information for sciond not yet implemented.")
        elif (p['data'] == 'file'):
            t = Topology.from_file(os.path.join(conf_dir, TOPO_FILE))
            topo = organize_topo(t)
            p['json_as_topo'] = json.dumps(get_json_as_topology(t, topo))
            p['json_trc'] = html_jsonfile(findCerts(conf_dir, ".trc"))
            p['json_crt'] = html_jsonfile(findCerts(conf_dir, ".crt"))
        p['path_info'] = get_as_view_html(paths, csegs, usegs, dsegs)
        p['json_path_topo'] = json.dumps(
            get_json_path_segs(paths, csegs, usegs, dsegs))
        p['json_seg_topo'] = json.dumps(
            get_json_all_segments(csegs, usegs, dsegs))
        p['json_paths'] = json.dumps(get_json_paths(paths))
    except (SCIONBaseError) as err:
        p['err'] = "%s: %s" % (err.__class__.__name__, err)
        return fmt_err(request, p)
    return render(request, 'asviz/index.html', p)
Exemplo n.º 8
0
 def __init__(self, server_id, conf_dir, public=None, bind=None, spki_cache_dir=GEN_CACHE_PATH,
              prom_export=None):
     """
     :param str server_id: server identifier.
     :param str conf_dir: configuration directory.
     :param list public:
         (host_addr, port) of the element's public address
         (i.e. the address visible to other network elements).
     :param list bind:
         (host_addr, port) of the element's bind address, if any
         (i.e. the address the element uses to identify itself to the local
         operating system, if it differs from the public address due to NAT).
     :param str spki_cache_dir:
         Path for caching TRCs and certificate chains.
     :param str prom_export:
         String of the form 'addr:port' specifying the prometheus endpoint.
         If no string is provided, no metrics are exported.
     """
     self.id = server_id
     self.conf_dir = conf_dir
     self.ifid2br = {}
     self.topology = Topology.from_file(
         os.path.join(self.conf_dir, TOPO_FILE))
     # Labels attached to every exported metric.
     self._labels = {"server_id": self.id, "isd_as": str(self.topology.isd_as)}
     # Must be over-ridden by child classes:
     self.CTRL_PLD_CLASS_MAP = {}
     self.SCMP_PLD_CLASS_MAP = {}
     self.public = public
     self.bind = bind
     if self.SERVICE_TYPE:
         own_config = self.topology.get_own_config(self.SERVICE_TYPE,
                                                   server_id)
         if public is None:
             self.public = own_config.public
         if bind is None:
             self.bind = own_config.bind
     self.init_ifid2br()
     self.trust_store = TrustStore(self.conf_dir, spki_cache_dir, self.id, self._labels)
     self.total_dropped = 0
     self._core_ases = defaultdict(list)  # Mapping ISD_ID->list of core ASes
     self.init_core_ases()
     self.run_flag = threading.Event()
     self.run_flag.set()
     self.stopped_flag = threading.Event()
     self.stopped_flag.clear()
     self._in_buf = queue.Queue(MAX_QUEUE)
     self._socks = SocketMgr()
     self._startup = time.time()
     if self.USE_TCP:
         self._DefaultMeta = TCPMetadata
     else:
         self._DefaultMeta = UDPMetadata
     self.unverified_segs = ExpiringDict(500, 60 * 60)
     self.unv_segs_lock = threading.RLock()
     self.requested_trcs = {}
     self.req_trcs_lock = threading.Lock()
     self.requested_certs = {}
     self.req_certs_lock = threading.Lock()
     # TODO(jonghoonkwon): Fix me to setup sockets for multiple public addresses
     host_addr, self._port = self.public[0]
     self.addr = SCIONAddr.from_values(self.topology.isd_as, host_addr)
     if prom_export:
         self._export_metrics(prom_export)
         self._init_metrics()
     self._setup_sockets(True)
     lib_sciond.init(os.path.join(SCIOND_API_SOCKDIR, "sd%s.sock" % self.addr.isd_as))