krabka_verified/authz/
acl_decision.rs1use {
2 super::{
3 AclDecision, AclDefault, AclFacts, AclOperationKind, AclPatternKind, AclResourceFacts,
4 AclResourceTypeMatch, RequestAuthState,
5 },
6 creusot_std::prelude::*,
7};
8
9#[ensures(result == (wildcard || exact))]
11#[must_use]
12pub fn acl_identity_match(wildcard: bool, exact: bool) -> bool { wildcard || exact }
13
14#[ensures(result == (facts.resource_type == AclResourceTypeMatch::Same && match pattern {
21 AclPatternKind::Literal => facts.exact_name || facts.wildcard_name,
22 AclPatternKind::Prefixed => facts.name_has_prefix,
23}))]
24#[must_use]
25pub fn acl_resource_match(pattern: AclPatternKind, facts: AclResourceFacts) -> bool {
26 match (facts.resource_type, pattern) {
27 (AclResourceTypeMatch::Different, _) => false,
28 (AclResourceTypeMatch::Same, AclPatternKind::Literal) => {
29 facts.exact_name || facts.wildcard_name
30 }
31 (AclResourceTypeMatch::Same, AclPatternKind::Prefixed) => facts.name_has_prefix,
32 }
33}
34
35#[ensures(result == (stored == requested
42 || stored == AclOperationKind::All
43 || (is_allow && stored == AclOperationKind::Read && requested == AclOperationKind::Describe)
44 || (is_allow && stored == AclOperationKind::Write && requested == AclOperationKind::Describe)
45 || (is_allow && stored == AclOperationKind::Delete && requested == AclOperationKind::Describe)
46 || (is_allow && stored == AclOperationKind::Alter && requested == AclOperationKind::Describe)
47 || (is_allow
48 && stored == AclOperationKind::AlterConfigs
49 && requested == AclOperationKind::DescribeConfigs)))]
50#[must_use]
51pub fn acl_operation_match(
52 stored: AclOperationKind,
53 requested: AclOperationKind,
54 is_allow: bool,
55) -> bool {
56 match stored {
57 AclOperationKind::All => true,
58 AclOperationKind::Read => {
59 matches!(requested, AclOperationKind::Read)
60 || (is_allow && matches!(requested, AclOperationKind::Describe))
61 }
62 AclOperationKind::Write => {
63 matches!(requested, AclOperationKind::Write)
64 || (is_allow && matches!(requested, AclOperationKind::Describe))
65 }
66 AclOperationKind::Delete => {
67 matches!(requested, AclOperationKind::Delete)
68 || (is_allow && matches!(requested, AclOperationKind::Describe))
69 }
70 AclOperationKind::Alter => {
71 matches!(requested, AclOperationKind::Alter)
72 || (is_allow && matches!(requested, AclOperationKind::Describe))
73 }
74 AclOperationKind::AlterConfigs => {
75 matches!(requested, AclOperationKind::AlterConfigs)
76 || (is_allow && matches!(requested, AclOperationKind::DescribeConfigs))
77 }
78 AclOperationKind::Create => matches!(requested, AclOperationKind::Create),
79 AclOperationKind::Describe => matches!(requested, AclOperationKind::Describe),
80 AclOperationKind::ClusterAction => matches!(requested, AclOperationKind::ClusterAction),
81 AclOperationKind::DescribeConfigs => {
82 matches!(requested, AclOperationKind::DescribeConfigs)
83 }
84 AclOperationKind::IdempotentWrite => {
85 matches!(requested, AclOperationKind::IdempotentWrite)
86 }
87 AclOperationKind::TwoPhaseCommit => {
88 matches!(requested, AclOperationKind::TwoPhaseCommit)
89 }
90 AclOperationKind::CreateTokens => matches!(requested, AclOperationKind::CreateTokens),
91 AclOperationKind::DescribeTokens => {
92 matches!(requested, AclOperationKind::DescribeTokens)
93 }
94 }
95}
96
97#[ensures(state == RequestAuthState::Authenticated ==> result)]
99#[ensures(state == RequestAuthState::Failed ==> !result)]
100#[ensures(state == RequestAuthState::Exchanging ==>
101 result == (api_key@ == 36))]
102#[ensures(state == RequestAuthState::PreHandshake ==>
103 result == (api_key@ == 17 || api_key@ == 18))]
104#[must_use]
105pub fn request_auth_admission(state: RequestAuthState, api_key: i16) -> bool {
106 match state {
107 RequestAuthState::Authenticated => true,
108 RequestAuthState::Failed => false,
109 RequestAuthState::Exchanging => api_key == 36,
110 RequestAuthState::PreHandshake => matches!(api_key, 17 | 18),
111 }
112}
113
114#[ensures(match result {
123 AclDecision::AllowSuperuser => facts.super_user,
124 AclDecision::DenyExplicit => !facts.super_user && facts.saw_deny,
125 AclDecision::AllowAcl => !facts.super_user && !facts.saw_deny && facts.saw_allow,
126 AclDecision::AllowNoAcl => !facts.super_user && !facts.saw_deny && !facts.saw_allow
127 && facts.default_decision == AclDefault::Allow,
128 AclDecision::DenyDefault => !facts.super_user && !facts.saw_deny && !facts.saw_allow
129 && facts.default_decision == AclDefault::Deny,
130})]
131#[must_use]
132pub fn acl_decision(facts: AclFacts) -> AclDecision {
133 if facts.super_user {
134 AclDecision::AllowSuperuser
135 } else if facts.saw_deny {
136 AclDecision::DenyExplicit
137 } else if facts.saw_allow {
138 AclDecision::AllowAcl
139 } else {
140 match facts.default_decision {
141 AclDefault::Allow => AclDecision::AllowNoAcl,
142 AclDefault::Deny => AclDecision::DenyDefault,
143 }
144 }
145}