1 /*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18 19 // Package credentials implements various credentials supported by gRPC library,
20 // which encapsulate all the state needed by a client to authenticate with a
21 // server and make various assertions, e.g., about the client's identity, role,
22 // or whether it is authorized to make a particular call.
23 package credentials // import "google.golang.org/grpc/credentials"
24 25 import (
26 "context"
27 "errors"
28 "fmt"
29 "net"
30 31 "google.golang.org/grpc/attributes"
32 icredentials "google.golang.org/grpc/internal/credentials"
33 "google.golang.org/protobuf/proto"
34 )
35 36 // PerRPCCredentials defines the common interface for the credentials which need to
37 // attach security information to every RPC (e.g., oauth2).
38 type PerRPCCredentials interface {
39 // GetRequestMetadata gets the current request metadata, refreshing tokens
40 // if required. This should be called by the transport layer on each
41 // request, and the data should be populated in headers or other
42 // context. If a status code is returned, it will be used as the status for
43 // the RPC (restricted to an allowable set of codes as defined by gRFC
44 // A54). uri is the URI of the entry point for the request. When supported
45 // by the underlying implementation, ctx can be used for timeout and
46 // cancellation. Additionally, RequestInfo data will be available via ctx
47 // to this call.
48 GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
49 // RequireTransportSecurity indicates whether the credentials requires
50 // transport security.
51 RequireTransportSecurity() bool
52 }
53 54 // SecurityLevel defines the protection level on an established connection.
55 //
56 // This API is experimental.
57 type SecurityLevel int
58 59 const (
60 // InvalidSecurityLevel indicates an invalid security level.
61 // The zero SecurityLevel value is invalid for backward compatibility.
62 InvalidSecurityLevel SecurityLevel = iota
63 // NoSecurity indicates a connection is insecure.
64 NoSecurity
65 // IntegrityOnly indicates a connection only provides integrity protection.
66 IntegrityOnly
67 // PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection.
68 PrivacyAndIntegrity
69 )
70 71 // String returns SecurityLevel in a string format.
72 func (s SecurityLevel) String() string {
73 switch s {
74 case NoSecurity:
75 return "NoSecurity"
76 case IntegrityOnly:
77 return "IntegrityOnly"
78 case PrivacyAndIntegrity:
79 return "PrivacyAndIntegrity"
80 }
81 return fmt.Sprintf("invalid SecurityLevel: %v", int(s))
82 }
83 84 // CommonAuthInfo contains authenticated information common to AuthInfo implementations.
85 // It should be embedded in a struct implementing AuthInfo to provide additional information
86 // about the credentials.
87 //
88 // This API is experimental.
89 type CommonAuthInfo struct {
90 SecurityLevel SecurityLevel
91 }
92 93 // GetCommonAuthInfo returns the pointer to CommonAuthInfo struct.
94 func (c CommonAuthInfo) GetCommonAuthInfo() CommonAuthInfo {
95 return c
96 }
97 98 // ProtocolInfo provides static information regarding transport credentials.
99 type ProtocolInfo struct {
100 // ProtocolVersion is the gRPC wire protocol version.
101 //
102 // Deprecated: this is unused by gRPC.
103 ProtocolVersion string
104 // SecurityProtocol is the security protocol in use.
105 SecurityProtocol string
106 // SecurityVersion is the security protocol version. It is a static version string from the
107 // credentials, not a value that reflects per-connection protocol negotiation. To retrieve
108 // details about the credentials used for a connection, use the Peer's AuthInfo field instead.
109 //
110 // Deprecated: please use Peer.AuthInfo.
111 SecurityVersion string
112 // ServerName is the user-configured server name. If set, this overrides
113 // the default :authority header used for all RPCs on the channel using the
114 // containing credentials, unless grpc.WithAuthority is set on the channel,
115 // in which case that setting will take precedence.
116 //
117 // This must be a valid `:authority` header according to
118 // [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2).
119 //
120 // Deprecated: Users should use grpc.WithAuthority to override the authority
121 // on a channel instead of configuring the credentials.
122 ServerName string
123 }
124 125 // AuthInfo defines the common interface for the auth information the users are interested in.
126 // A struct that implements AuthInfo should embed CommonAuthInfo by including additional
127 // information about the credentials in it.
128 type AuthInfo interface {
129 AuthType() string
130 }
131 132 // AuthorityValidator validates the authority used to override the `:authority`
133 // header. This is an optional interface that implementations of AuthInfo can
134 // implement if they support per-RPC authority overrides. It is invoked when the
135 // application attempts to override the HTTP/2 `:authority` header using the
136 // CallAuthority call option.
137 type AuthorityValidator interface {
138 // ValidateAuthority checks the authority value used to override the
139 // `:authority` header. The authority parameter is the override value
140 // provided by the application via the CallAuthority option. This value
141 // typically corresponds to the server hostname or endpoint the RPC is
142 // targeting. It returns non-nil error if the validation fails.
143 ValidateAuthority(authority string) error
144 }
145 146 // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
147 // and the caller should not close rawConn.
148 var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
149 150 // TransportCredentials defines the common interface for all the live gRPC wire
151 // protocols and supported transport security protocols (e.g., TLS, SSL).
152 type TransportCredentials interface {
153 // ClientHandshake does the authentication handshake specified by the
154 // corresponding authentication protocol on rawConn for clients. It returns
155 // the authenticated connection and the corresponding auth information
156 // about the connection. The auth information should embed CommonAuthInfo
157 // to return additional information about the credentials. Implementations
158 // must use the provided context to implement timely cancellation. gRPC
159 // will try to reconnect if the error returned is a temporary error
160 // (io.EOF, context.DeadlineExceeded or err.Temporary() == true). If the
161 // returned error is a wrapper error, implementations should make sure that
162 // the error implements Temporary() to have the correct retry behaviors.
163 // Additionally, ClientHandshakeInfo data will be available via the context
164 // passed to this call.
165 //
166 // The second argument to this method is the `:authority` header value used
167 // while creating new streams on this connection after authentication
168 // succeeds. Implementations must use this as the server name during the
169 // authentication handshake.
170 //
171 // If the returned net.Conn is closed, it MUST close the net.Conn provided.
172 ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
173 // ServerHandshake does the authentication handshake for servers. It returns
174 // the authenticated connection and the corresponding auth information about
175 // the connection. The auth information should embed CommonAuthInfo to return additional information
176 // about the credentials.
177 //
178 // If the returned net.Conn is closed, it MUST close the net.Conn provided.
179 ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
180 // Info provides the ProtocolInfo of this TransportCredentials.
181 Info() ProtocolInfo
182 // Clone makes a copy of this TransportCredentials.
183 Clone() TransportCredentials
184 // OverrideServerName specifies the value used for the following:
185 //
186 // - verifying the hostname on the returned certificates
187 // - as SNI in the client's handshake to support virtual hosting
188 // - as the value for `:authority` header at stream creation time
189 //
190 // The provided string should be a valid `:authority` header according to
191 // [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2).
192 //
193 // Deprecated: this method is unused by gRPC. Users should use
194 // grpc.WithAuthority to override the authority on a channel instead of
195 // configuring the credentials.
196 OverrideServerName(string) error
197 }
198 199 // Bundle is a combination of TransportCredentials and PerRPCCredentials.
200 //
201 // It also contains a mode switching method, so it can be used as a combination
202 // of different credential policies.
203 //
204 // Bundle cannot be used together with individual TransportCredentials.
205 // PerRPCCredentials from Bundle will be appended to other PerRPCCredentials.
206 //
207 // This API is experimental.
208 type Bundle interface {
209 // TransportCredentials returns the transport credentials from the Bundle.
210 //
211 // Implementations must return non-nil transport credentials. If transport
212 // security is not needed by the Bundle, implementations may choose to
213 // return insecure.NewCredentials().
214 TransportCredentials() TransportCredentials
215 216 // PerRPCCredentials returns the per-RPC credentials from the Bundle.
217 //
218 // May be nil if per-RPC credentials are not needed.
219 PerRPCCredentials() PerRPCCredentials
220 221 // NewWithMode should make a copy of Bundle, and switch mode. Modifying the
222 // existing Bundle may cause races.
223 //
224 // NewWithMode returns nil if the requested mode is not supported.
225 NewWithMode(mode string) (Bundle, error)
226 }
227 228 // RequestInfo contains request data attached to the context passed to GetRequestMetadata calls.
229 //
230 // This API is experimental.
231 type RequestInfo struct {
232 // The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method")
233 Method string
234 // AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake)
235 AuthInfo AuthInfo
236 }
237 238 // requestInfoKey is a struct to be used as the key to store RequestInfo in a
239 // context.
240 type requestInfoKey struct{}
241 242 // RequestInfoFromContext extracts the RequestInfo from the context if it exists.
243 //
244 // This API is experimental.
245 func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
246 ri, ok = ctx.Value(requestInfoKey{}).(RequestInfo)
247 return ri, ok
248 }
249 250 // NewContextWithRequestInfo creates a new context from ctx and attaches ri to it.
251 //
252 // This RequestInfo will be accessible via RequestInfoFromContext.
253 //
254 // Intended to be used from tests for PerRPCCredentials implementations (that
255 // often need to check connection's SecurityLevel). Should not be used from
256 // non-test code: the gRPC client already prepares a context with the correct
257 // RequestInfo attached when calling PerRPCCredentials.GetRequestMetadata.
258 //
259 // This API is experimental.
260 func NewContextWithRequestInfo(ctx context.Context, ri RequestInfo) context.Context {
261 return context.WithValue(ctx, requestInfoKey{}, ri)
262 }
263 264 // ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes
265 // it possible to pass arbitrary data to the handshaker from gRPC, resolver,
266 // balancer etc. Individual credential implementations control the actual
267 // format of the data that they are willing to receive.
268 //
269 // This API is experimental.
270 type ClientHandshakeInfo struct {
271 // Attributes contains the attributes for the address. It could be provided
272 // by the gRPC, resolver, balancer etc.
273 Attributes *attributes.Attributes
274 }
275 276 // ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored
277 // in ctx.
278 //
279 // This API is experimental.
280 func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {
281 chi, _ := icredentials.ClientHandshakeInfoFromContext(ctx).(ClientHandshakeInfo)
282 return chi
283 }
284 285 // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
286 // It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
287 // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
288 //
289 // This API is experimental.
290 func CheckSecurityLevel(ai AuthInfo, level SecurityLevel) error {
291 type internalInfo interface {
292 GetCommonAuthInfo() CommonAuthInfo
293 }
294 if ai == nil {
295 return errors.New("AuthInfo is nil")
296 }
297 if ci, ok := ai.(internalInfo); ok {
298 // CommonAuthInfo.SecurityLevel has an invalid value.
299 if ci.GetCommonAuthInfo().SecurityLevel == InvalidSecurityLevel {
300 return nil
301 }
302 if ci.GetCommonAuthInfo().SecurityLevel < level {
303 return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
304 }
305 }
306 // The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
307 return nil
308 }
309 310 // ChannelzSecurityInfo defines the interface that security protocols should implement
311 // in order to provide security info to channelz.
312 //
313 // This API is experimental.
314 type ChannelzSecurityInfo interface {
315 GetSecurityValue() ChannelzSecurityValue
316 }
317 318 // ChannelzSecurityValue defines the interface that GetSecurityValue() return value
319 // should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
320 // and *OtherChannelzSecurityValue.
321 //
322 // This API is experimental.
323 type ChannelzSecurityValue interface {
324 isChannelzSecurityValue()
325 }
326 327 // OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
328 // from GetSecurityValue(), which contains protocol specific security info. Note
329 // the Value field will be sent to users of channelz requesting channel info, and
330 // thus sensitive info should better be avoided.
331 //
332 // This API is experimental.
333 type OtherChannelzSecurityValue struct {
334 ChannelzSecurityValue
335 Name string
336 Value proto.Message
337 }
338