1
// Copyright Istio Authors
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
25
"google.golang.org/grpc/credentials"
26
"google.golang.org/grpc/peer"
28
"istio.io/istio/pkg/log"
29
"istio.io/istio/pkg/spiffe"
30
"istio.io/istio/pkg/util/sets"
31
"istio.io/istio/security/pkg/pki/util"
34
type DirectSecretManager struct {
35
items map[string]*SecretItem
39
var _ SecretManager = &DirectSecretManager{}
41
func NewDirectSecretManager() *DirectSecretManager {
42
return &DirectSecretManager{
43
items: map[string]*SecretItem{},
47
func (d *DirectSecretManager) GenerateSecret(resourceName string) (*SecretItem, error) {
50
si, f := d.items[resourceName]
52
return nil, fmt.Errorf("resource %v not found", resourceName)
57
func (d *DirectSecretManager) Set(resourceName string, secret *SecretItem) {
61
delete(d.items, resourceName)
63
d.items[resourceName] = secret
67
type FakeAuthenticator struct {
72
Successes *atomic.Int32
73
Failures *atomic.Int32
78
func NewFakeAuthenticator(name string) *FakeAuthenticator {
79
return &FakeAuthenticator{
81
Successes: atomic.NewInt32(0),
82
Failures: atomic.NewInt32(0),
86
func (f *FakeAuthenticator) Authenticate(authCtx AuthContext) (*Caller, error) {
87
if authCtx.GrpcContext != nil {
88
return f.authenticateGrpc(authCtx.GrpcContext)
90
if authCtx.Request != nil {
91
return f.authenticateHTTP(authCtx.Request)
96
func (f *FakeAuthenticator) authenticateHTTP(req *http.Request) (*Caller, error) {
97
return nil, errors.New("not implemented")
100
func (f *FakeAuthenticator) authenticateGrpc(ctx context.Context) (*Caller, error) {
105
token := checkToken(ctx, at)
106
cert := checkCert(ctx, ac)
107
id := []string{spiffe.Identity{
108
TrustDomain: "cluster.local",
109
Namespace: "fake-namespace",
110
ServiceAccount: "fake-sa",
112
log.WithLabels("name", f.Name, "cert", cert, "token", token).Infof("authentication complete")
116
AuthSource: AuthSourceClientCertificate,
123
AuthSource: AuthSourceIDToken,
128
return nil, fmt.Errorf("neither token (%v) nor cert (%v) succeeded", token, cert)
131
func (f *FakeAuthenticator) AuthenticatorType() string {
135
func (f *FakeAuthenticator) Set(token string, identity string) *FakeAuthenticator {
138
f.AllowedToken = token
139
f.AllowedCert = identity
143
var _ Authenticator = &FakeAuthenticator{}
145
func checkToken(ctx context.Context, expected string) error {
147
return fmt.Errorf("jwt authentication not allowed")
149
targetJWT, err := ExtractBearerToken(ctx)
151
return fmt.Errorf("target JWT extraction error: %v", err)
153
if targetJWT != expected {
154
return fmt.Errorf("expected token %q got %q", expected, targetJWT)
159
func checkCert(ctx context.Context, expected string) error {
161
return fmt.Errorf("cert authentication not allowed")
164
p, ok := peer.FromContext(ctx)
165
if !ok || p.AuthInfo == nil {
166
return fmt.Errorf("no client certificate is presented")
169
if authType := p.AuthInfo.AuthType(); authType != "tls" {
170
return fmt.Errorf("unsupported auth type: %q", authType)
173
tlsInfo := p.AuthInfo.(credentials.TLSInfo)
174
chains := tlsInfo.State.VerifiedChains
175
if len(chains) == 0 || len(chains[0]) == 0 {
176
return fmt.Errorf("no verified chain is found")
179
ids, err := util.ExtractIDs(chains[0][0].Extensions)
181
return fmt.Errorf("failed to extract IDs")
183
if !sets.New(ids...).Contains(expected) {
184
return fmt.Errorf("expected identity %q, got %v", expected, ids)