istio

Форк
0
/
mock.go 
188 строк · 4.5 Кб
1
// Copyright Istio Authors
2
//
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
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
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.
14

15
package security
16

17
import (
18
	"context"
19
	"errors"
20
	"fmt"
21
	"net/http"
22
	"sync"
23

24
	"go.uber.org/atomic"
25
	"google.golang.org/grpc/credentials"
26
	"google.golang.org/grpc/peer"
27

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"
32
)
33

34
type DirectSecretManager struct {
35
	items map[string]*SecretItem
36
	mu    sync.RWMutex
37
}
38

39
var _ SecretManager = &DirectSecretManager{}
40

41
func NewDirectSecretManager() *DirectSecretManager {
42
	return &DirectSecretManager{
43
		items: map[string]*SecretItem{},
44
	}
45
}
46

47
func (d *DirectSecretManager) GenerateSecret(resourceName string) (*SecretItem, error) {
48
	d.mu.RLock()
49
	defer d.mu.RUnlock()
50
	si, f := d.items[resourceName]
51
	if !f {
52
		return nil, fmt.Errorf("resource %v not found", resourceName)
53
	}
54
	return si, nil
55
}
56

57
func (d *DirectSecretManager) Set(resourceName string, secret *SecretItem) {
58
	d.mu.Lock()
59
	defer d.mu.Unlock()
60
	if secret == nil {
61
		delete(d.items, resourceName)
62
	} else {
63
		d.items[resourceName] = secret
64
	}
65
}
66

67
type FakeAuthenticator struct {
68
	AllowedToken string
69
	AllowedCert  string
70
	Name         string
71

72
	Successes *atomic.Int32
73
	Failures  *atomic.Int32
74

75
	mu sync.Mutex
76
}
77

78
func NewFakeAuthenticator(name string) *FakeAuthenticator {
79
	return &FakeAuthenticator{
80
		Name:      name,
81
		Successes: atomic.NewInt32(0),
82
		Failures:  atomic.NewInt32(0),
83
	}
84
}
85

86
func (f *FakeAuthenticator) Authenticate(authCtx AuthContext) (*Caller, error) {
87
	if authCtx.GrpcContext != nil {
88
		return f.authenticateGrpc(authCtx.GrpcContext)
89
	}
90
	if authCtx.Request != nil {
91
		return f.authenticateHTTP(authCtx.Request)
92
	}
93
	return nil, nil
94
}
95

96
func (f *FakeAuthenticator) authenticateHTTP(req *http.Request) (*Caller, error) {
97
	return nil, errors.New("not implemented")
98
}
99

100
func (f *FakeAuthenticator) authenticateGrpc(ctx context.Context) (*Caller, error) {
101
	f.mu.Lock()
102
	at := f.AllowedToken
103
	ac := f.AllowedCert
104
	f.mu.Unlock()
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",
111
	}.String()}
112
	log.WithLabels("name", f.Name, "cert", cert, "token", token).Infof("authentication complete")
113
	if cert == nil {
114
		f.Successes.Inc()
115
		return &Caller{
116
			AuthSource: AuthSourceClientCertificate,
117
			Identities: id,
118
		}, nil
119
	}
120
	if token == nil {
121
		f.Successes.Inc()
122
		return &Caller{
123
			AuthSource: AuthSourceIDToken,
124
			Identities: id,
125
		}, nil
126
	}
127
	f.Failures.Inc()
128
	return nil, fmt.Errorf("neither token (%v) nor cert (%v) succeeded", token, cert)
129
}
130

131
func (f *FakeAuthenticator) AuthenticatorType() string {
132
	return "fake"
133
}
134

135
func (f *FakeAuthenticator) Set(token string, identity string) *FakeAuthenticator {
136
	f.mu.Lock()
137
	defer f.mu.Unlock()
138
	f.AllowedToken = token
139
	f.AllowedCert = identity
140
	return f
141
}
142

143
var _ Authenticator = &FakeAuthenticator{}
144

145
func checkToken(ctx context.Context, expected string) error {
146
	if expected == "" {
147
		return fmt.Errorf("jwt authentication not allowed")
148
	}
149
	targetJWT, err := ExtractBearerToken(ctx)
150
	if err != nil {
151
		return fmt.Errorf("target JWT extraction error: %v", err)
152
	}
153
	if targetJWT != expected {
154
		return fmt.Errorf("expected token %q got %q", expected, targetJWT)
155
	}
156
	return nil
157
}
158

159
func checkCert(ctx context.Context, expected string) error {
160
	if expected == "" {
161
		return fmt.Errorf("cert authentication not allowed")
162
	}
163

164
	p, ok := peer.FromContext(ctx)
165
	if !ok || p.AuthInfo == nil {
166
		return fmt.Errorf("no client certificate is presented")
167
	}
168

169
	if authType := p.AuthInfo.AuthType(); authType != "tls" {
170
		return fmt.Errorf("unsupported auth type: %q", authType)
171
	}
172

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")
177
	}
178

179
	ids, err := util.ExtractIDs(chains[0][0].Extensions)
180
	if err != nil {
181
		return fmt.Errorf("failed to extract IDs")
182
	}
183
	if !sets.New(ids...).Contains(expected) {
184
		return fmt.Errorf("expected identity %q, got %v", expected, ids)
185
	}
186

187
	return nil
188
}
189

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.