Beispiel #1
0
def match_filter(
    proxy_mode: ProxyMode,
    phase: Phase,
    flow: HTTPFlow,
    fltr: RuleEntry,
) -> bool:
    if fltr.phase != phase.value:
        # TODO: Should we emit filter audit logs when phases do not match?
        return False

    evaluated = []

    for rule in fltr.expression_snapshot['rules']:
        expression = rule['expression']
        expected_value = expression['values'][0].lower()
        extracted_value = extract_value(flow, expression['field']).lower()
        evaluated.append(extracted_value is not None
                         and expected_value == extracted_value)

    condition = fltr.expression_snapshot['condition']
    matched = all(evaluated) if condition == 'AND' else any(evaluated)

    audit_logs.emit(
        audit_logs.records.FilterEvaluationLogRecord(
            flow_id=flow.id,
            matched=matched,
            phase=phase,
            proxy_mode=proxy_mode,
            route_id=fltr.route_id,
            filter_id=fltr.id,
        ))

    return matched
Beispiel #2
0
def match_route(
    proxy_mode: ProxyMode,
    phase: Phase,
    flow: HTTPFlow,
) -> Tuple[Optional[Route], List[RuleEntry]]:
    request = flow.request
    is_outbound = proxy_mode == ProxyMode.FORWARD
    routes = route_manager.get_all_by_type(is_outbound)

    for route in routes:
        if is_outbound and not match_host(request.host, route.host_endpoint):
            continue

        match_filters = partial(match_filter, proxy_mode, phase, flow)
        filters = list(filter(match_filters, route.rule_entries_list))
        matched = bool(filters)
        audit_logs.emit(
            audit_logs.records.RouteEvaluationLogRecord(
                flow_id=flow.id,
                matched=matched,
                phase=phase,
                proxy_mode=proxy_mode,
                route_id=route.id,
            ))
        if matched:
            return route, filters

    return None, []
Beispiel #3
0
def match_route(
    proxy_mode: ProxyMode,
    phase: Phase,
    flow: HTTPFlow,
) -> Tuple[Optional[Route], List[RuleEntry]]:
    request = flow.request
    route_type = RouteType.INBOUND if proxy_mode == ProxyMode.REVERSE else RouteType.OUTBOUND
    routes = route_manager.get_all_by_type(route_type)
    request_host = request.host.replace('/', '').replace('.', '\\.')
    if proxy_mode == ProxyMode.FORWARD:
        routes = [
            route for route in routes if route.host_endpoint == request_host
        ]

    for route in routes:
        match_filters = partial(match_filter, proxy_mode, phase, flow)
        filters = list(filter(match_filters, route.rule_entries_list))
        matched = bool(filters)
        audit_logs.emit(
            audit_logs.records.RouteEvaluationLogRecord(
                flow_id=flow.id,
                matched=matched,
                phase=phase,
                proxy_mode=proxy_mode,
                route_id=route.id,
            ))
        if matched:
            return route, filters

    return None, []
def test_pubsub():
    records = []

    record = AuditLogTestRecord(
        flow_id='flow-id',
        proxy_mode=ProxyMode.REVERSE,
    )
    subscribe(lambda record: records.append(record))
    emit(record)

    assert records == [record]
Beispiel #5
0
    def request(self, flow: HTTPFlow):
        try:
            audit_logs.emit(
                audit_logs.records.VaultRequestAuditLogRecord(
                    flow_id=flow.id,
                    proxy_mode=ctx.get_proxy_context().mode,
                    method=flow.request.method,
                    uri=flow.request.url,
                ))
            flow.request_raw = flow.request.copy()
            self._process(flow, Phase.REQUEST)

        except (RedactFailed, RevealFailed) as exc:
            logger.error(exc)

        except Exception as exc:
            logger.exception(exc)
Beispiel #6
0
def match_filter(
    proxy_mode: ProxyMode,
    phase: Phase,
    flow: HTTPFlow,
    fltr: RuleEntry,
) -> bool:
    if fltr.phase != phase:
        # TODO: Should we emit filter audit logs when phases do not match?
        return False

    expr = CompositeExpression.build(fltr.expression_snapshot)
    matched = expr.evaluate(flow)

    audit_logs.emit(audit_logs.records.FilterEvaluationLogRecord(
        flow_id=flow.id,
        matched=matched,
        phase=phase,
        proxy_mode=proxy_mode,
        route_id=fltr.route_id,
        filter_id=fltr.id,
    ))

    return matched
Beispiel #7
0
    def response(self, flow: HTTPFlow):
        try:
            proxy_context = ctx.get_proxy_context()

            for sock, label in [
                (flow.server_conn.wfile,
                 audit_logs.records.TrafficLabel.TO_SERVER),
                (flow.server_conn.rfile,
                 audit_logs.records.TrafficLabel.FROM_SERVER),
            ]:
                if sock and sock.is_logging():
                    # TODO: (SAT-98) trigger TO_SERVER-event at the right time.
                    audit_logs.emit(
                        audit_logs.records.VaultTrafficLogRecord(
                            flow_id=flow.id,
                            proxy_mode=proxy_context.mode,
                            bytes=len(sock.get_log()),
                            label=label,
                        ))
                    sock.stop_log()

            audit_logs.emit(
                audit_logs.records.UpstreamResponseLogRecord(
                    flow_id=flow.id,
                    proxy_mode=proxy_context.mode,
                    upstream=flow.request.host,
                    status_code=flow.response.status_code,
                ))

            flow.response_raw = flow.response.copy()
            self._process(flow, Phase.RESPONSE)

        except (RedactFailed, RevealFailed) as exc:
            logger.error(exc)

        except Exception as exc:
            logger.exception(exc)