2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2021-03-16 00:06:04 +00:00
|
|
|
package connect
|
|
|
|
|
|
|
|
import (
|
2022-04-05 21:10:06 +00:00
|
|
|
"github.com/hashicorp/consul/acl"
|
2021-03-16 00:06:04 +00:00
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
|
|
)
|
|
|
|
|
|
|
|
// AuthorizeIntentionTarget determines whether the destination is covered by the given intention
|
|
|
|
// and whether the intention action allows a connection.
|
|
|
|
// This is a generalized version of the old CertURI.Authorize(), and can be evaluated against sources or destinations.
|
|
|
|
//
|
|
|
|
// The return value of `auth` is only valid if the second value `match` is true.
|
|
|
|
// If `match` is false, then the intention doesn't match this target and any result should be ignored.
|
|
|
|
func AuthorizeIntentionTarget(
|
2023-04-20 16:16:04 +00:00
|
|
|
target, targetNS, targetAP, targetPeer string,
|
2021-03-16 00:06:04 +00:00
|
|
|
ixn *structs.Intention,
|
|
|
|
matchType structs.IntentionMatchType,
|
2023-04-20 16:16:04 +00:00
|
|
|
) (bool, bool) {
|
|
|
|
|
|
|
|
match := IntentionMatch(target, targetNS, targetAP, targetPeer, ixn, matchType)
|
|
|
|
|
|
|
|
if match {
|
|
|
|
return ixn.Action == structs.IntentionActionAllow, true
|
|
|
|
} else {
|
|
|
|
return false, false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// IntentionMatch determines whether the target is covered by the given intention.
|
|
|
|
func IntentionMatch(
|
|
|
|
target, targetNS, targetAP, targetPeer string,
|
|
|
|
ixn *structs.Intention,
|
|
|
|
matchType structs.IntentionMatchType,
|
|
|
|
) bool {
|
2021-03-16 00:06:04 +00:00
|
|
|
|
|
|
|
switch matchType {
|
|
|
|
case structs.IntentionMatchDestination:
|
2022-04-05 21:10:06 +00:00
|
|
|
if acl.PartitionOrDefault(ixn.DestinationPartition) != acl.PartitionOrDefault(targetAP) {
|
2023-04-20 16:16:04 +00:00
|
|
|
return false
|
2021-09-16 19:31:19 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 00:06:04 +00:00
|
|
|
if ixn.DestinationNS != structs.WildcardSpecifier && ixn.DestinationNS != targetNS {
|
|
|
|
// Non-matching namespace
|
2023-04-20 16:16:04 +00:00
|
|
|
return false
|
2021-03-16 00:06:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ixn.DestinationName != structs.WildcardSpecifier && ixn.DestinationName != target {
|
|
|
|
// Non-matching name
|
2023-04-20 16:16:04 +00:00
|
|
|
return false
|
2021-03-16 00:06:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case structs.IntentionMatchSource:
|
2023-04-20 16:16:04 +00:00
|
|
|
if ixn.SourcePeer != targetPeer {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-04-05 21:10:06 +00:00
|
|
|
if acl.PartitionOrDefault(ixn.SourcePartition) != acl.PartitionOrDefault(targetAP) {
|
2023-04-20 16:16:04 +00:00
|
|
|
return false
|
2021-09-16 19:31:19 +00:00
|
|
|
}
|
|
|
|
|
2021-03-16 00:06:04 +00:00
|
|
|
if ixn.SourceNS != structs.WildcardSpecifier && ixn.SourceNS != targetNS {
|
|
|
|
// Non-matching namespace
|
2023-04-20 16:16:04 +00:00
|
|
|
return false
|
2021-03-16 00:06:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ixn.SourceName != structs.WildcardSpecifier && ixn.SourceName != target {
|
|
|
|
// Non-matching name
|
2023-04-20 16:16:04 +00:00
|
|
|
return false
|
2021-03-16 00:06:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Reject on any un-recognized match type
|
2023-04-20 16:16:04 +00:00
|
|
|
return false
|
2021-03-16 00:06:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// The name and namespace match, so the destination is covered
|
2023-04-20 16:16:04 +00:00
|
|
|
return true
|
2021-03-16 00:06:04 +00:00
|
|
|
}
|