google.golang.org/grpc@v1.74.2/credentials/credentials.go (about)

     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.  TODO(zhaoq): Define the set of the qualified keys instead
    48  	// of leaving it as an arbitrary string.
    49  	GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
    50  	// RequireTransportSecurity indicates whether the credentials requires
    51  	// transport security.
    52  	RequireTransportSecurity() bool
    53  }
    54  
    55  // SecurityLevel defines the protection level on an established connection.
    56  //
    57  // This API is experimental.
    58  type SecurityLevel int
    59  
    60  const (
    61  	// InvalidSecurityLevel indicates an invalid security level.
    62  	// The zero SecurityLevel value is invalid for backward compatibility.
    63  	InvalidSecurityLevel SecurityLevel = iota
    64  	// NoSecurity indicates a connection is insecure.
    65  	NoSecurity
    66  	// IntegrityOnly indicates a connection only provides integrity protection.
    67  	IntegrityOnly
    68  	// PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection.
    69  	PrivacyAndIntegrity
    70  )
    71  
    72  // String returns SecurityLevel in a string format.
    73  func (s SecurityLevel) String() string {
    74  	switch s {
    75  	case NoSecurity:
    76  		return "NoSecurity"
    77  	case IntegrityOnly:
    78  		return "IntegrityOnly"
    79  	case PrivacyAndIntegrity:
    80  		return "PrivacyAndIntegrity"
    81  	}
    82  	return fmt.Sprintf("invalid SecurityLevel: %v", int(s))
    83  }
    84  
    85  // CommonAuthInfo contains authenticated information common to AuthInfo implementations.
    86  // It should be embedded in a struct implementing AuthInfo to provide additional information
    87  // about the credentials.
    88  //
    89  // This API is experimental.
    90  type CommonAuthInfo struct {
    91  	SecurityLevel SecurityLevel
    92  }
    93  
    94  // GetCommonAuthInfo returns the pointer to CommonAuthInfo struct.
    95  func (c CommonAuthInfo) GetCommonAuthInfo() CommonAuthInfo {
    96  	return c
    97  }
    98  
    99  // ProtocolInfo provides information regarding the gRPC wire protocol version,
   100  // security protocol, security protocol version in use, server name, etc.
   101  type ProtocolInfo struct {
   102  	// ProtocolVersion is the gRPC wire protocol version.
   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.
   113  	ServerName string
   114  }
   115  
   116  // AuthInfo defines the common interface for the auth information the users are interested in.
   117  // A struct that implements AuthInfo should embed CommonAuthInfo by including additional
   118  // information about the credentials in it.
   119  type AuthInfo interface {
   120  	AuthType() string
   121  }
   122  
   123  // AuthorityValidator validates the authority used to override the `:authority`
   124  // header. This is an optional interface that implementations of AuthInfo can
   125  // implement if they support per-RPC authority overrides. It is invoked when the
   126  // application attempts to override the HTTP/2 `:authority` header using the
   127  // CallAuthority call option.
   128  type AuthorityValidator interface {
   129  	// ValidateAuthority checks the authority value used to override the
   130  	// `:authority` header. The authority parameter is the override value
   131  	// provided by the application via the CallAuthority option. This value
   132  	// typically corresponds to the server hostname or endpoint the RPC is
   133  	// targeting. It returns non-nil error if the validation fails.
   134  	ValidateAuthority(authority string) error
   135  }
   136  
   137  // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
   138  // and the caller should not close rawConn.
   139  var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
   140  
   141  // TransportCredentials defines the common interface for all the live gRPC wire
   142  // protocols and supported transport security protocols (e.g., TLS, SSL).
   143  type TransportCredentials interface {
   144  	// ClientHandshake does the authentication handshake specified by the
   145  	// corresponding authentication protocol on rawConn for clients. It returns
   146  	// the authenticated connection and the corresponding auth information
   147  	// about the connection.  The auth information should embed CommonAuthInfo
   148  	// to return additional information about the credentials. Implementations
   149  	// must use the provided context to implement timely cancellation.  gRPC
   150  	// will try to reconnect if the error returned is a temporary error
   151  	// (io.EOF, context.DeadlineExceeded or err.Temporary() == true).  If the
   152  	// returned error is a wrapper error, implementations should make sure that
   153  	// the error implements Temporary() to have the correct retry behaviors.
   154  	// Additionally, ClientHandshakeInfo data will be available via the context
   155  	// passed to this call.
   156  	//
   157  	// The second argument to this method is the `:authority` header value used
   158  	// while creating new streams on this connection after authentication
   159  	// succeeds. Implementations must use this as the server name during the
   160  	// authentication handshake.
   161  	//
   162  	// If the returned net.Conn is closed, it MUST close the net.Conn provided.
   163  	ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
   164  	// ServerHandshake does the authentication handshake for servers. It returns
   165  	// the authenticated connection and the corresponding auth information about
   166  	// the connection. The auth information should embed CommonAuthInfo to return additional information
   167  	// about the credentials.
   168  	//
   169  	// If the returned net.Conn is closed, it MUST close the net.Conn provided.
   170  	ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
   171  	// Info provides the ProtocolInfo of this TransportCredentials.
   172  	Info() ProtocolInfo
   173  	// Clone makes a copy of this TransportCredentials.
   174  	Clone() TransportCredentials
   175  	// OverrideServerName specifies the value used for the following:
   176  	// - verifying the hostname on the returned certificates
   177  	// - as SNI in the client's handshake to support virtual hosting
   178  	// - as the value for `:authority` header at stream creation time
   179  	//
   180  	// Deprecated: use grpc.WithAuthority instead. Will be supported
   181  	// throughout 1.x.
   182  	OverrideServerName(string) error
   183  }
   184  
   185  // Bundle is a combination of TransportCredentials and PerRPCCredentials.
   186  //
   187  // It also contains a mode switching method, so it can be used as a combination
   188  // of different credential policies.
   189  //
   190  // Bundle cannot be used together with individual TransportCredentials.
   191  // PerRPCCredentials from Bundle will be appended to other PerRPCCredentials.
   192  //
   193  // This API is experimental.
   194  type Bundle interface {
   195  	// TransportCredentials returns the transport credentials from the Bundle.
   196  	//
   197  	// Implementations must return non-nil transport credentials. If transport
   198  	// security is not needed by the Bundle, implementations may choose to
   199  	// return insecure.NewCredentials().
   200  	TransportCredentials() TransportCredentials
   201  
   202  	// PerRPCCredentials returns the per-RPC credentials from the Bundle.
   203  	//
   204  	// May be nil if per-RPC credentials are not needed.
   205  	PerRPCCredentials() PerRPCCredentials
   206  
   207  	// NewWithMode should make a copy of Bundle, and switch mode. Modifying the
   208  	// existing Bundle may cause races.
   209  	//
   210  	// NewWithMode returns nil if the requested mode is not supported.
   211  	NewWithMode(mode string) (Bundle, error)
   212  }
   213  
   214  // RequestInfo contains request data attached to the context passed to GetRequestMetadata calls.
   215  //
   216  // This API is experimental.
   217  type RequestInfo struct {
   218  	// The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method")
   219  	Method string
   220  	// AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake)
   221  	AuthInfo AuthInfo
   222  }
   223  
   224  // requestInfoKey is a struct to be used as the key to store RequestInfo in a
   225  // context.
   226  type requestInfoKey struct{}
   227  
   228  // RequestInfoFromContext extracts the RequestInfo from the context if it exists.
   229  //
   230  // This API is experimental.
   231  func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
   232  	ri, ok = ctx.Value(requestInfoKey{}).(RequestInfo)
   233  	return ri, ok
   234  }
   235  
   236  // NewContextWithRequestInfo creates a new context from ctx and attaches ri to it.
   237  //
   238  // This RequestInfo will be accessible via RequestInfoFromContext.
   239  //
   240  // Intended to be used from tests for PerRPCCredentials implementations (that
   241  // often need to check connection's SecurityLevel). Should not be used from
   242  // non-test code: the gRPC client already prepares a context with the correct
   243  // RequestInfo attached when calling PerRPCCredentials.GetRequestMetadata.
   244  //
   245  // This API is experimental.
   246  func NewContextWithRequestInfo(ctx context.Context, ri RequestInfo) context.Context {
   247  	return context.WithValue(ctx, requestInfoKey{}, ri)
   248  }
   249  
   250  // ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes
   251  // it possible to pass arbitrary data to the handshaker from gRPC, resolver,
   252  // balancer etc. Individual credential implementations control the actual
   253  // format of the data that they are willing to receive.
   254  //
   255  // This API is experimental.
   256  type ClientHandshakeInfo struct {
   257  	// Attributes contains the attributes for the address. It could be provided
   258  	// by the gRPC, resolver, balancer etc.
   259  	Attributes *attributes.Attributes
   260  }
   261  
   262  // ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored
   263  // in ctx.
   264  //
   265  // This API is experimental.
   266  func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {
   267  	chi, _ := icredentials.ClientHandshakeInfoFromContext(ctx).(ClientHandshakeInfo)
   268  	return chi
   269  }
   270  
   271  // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
   272  // It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
   273  // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
   274  //
   275  // This API is experimental.
   276  func CheckSecurityLevel(ai AuthInfo, level SecurityLevel) error {
   277  	type internalInfo interface {
   278  		GetCommonAuthInfo() CommonAuthInfo
   279  	}
   280  	if ai == nil {
   281  		return errors.New("AuthInfo is nil")
   282  	}
   283  	if ci, ok := ai.(internalInfo); ok {
   284  		// CommonAuthInfo.SecurityLevel has an invalid value.
   285  		if ci.GetCommonAuthInfo().SecurityLevel == InvalidSecurityLevel {
   286  			return nil
   287  		}
   288  		if ci.GetCommonAuthInfo().SecurityLevel < level {
   289  			return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
   290  		}
   291  	}
   292  	// The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
   293  	return nil
   294  }
   295  
   296  // ChannelzSecurityInfo defines the interface that security protocols should implement
   297  // in order to provide security info to channelz.
   298  //
   299  // This API is experimental.
   300  type ChannelzSecurityInfo interface {
   301  	GetSecurityValue() ChannelzSecurityValue
   302  }
   303  
   304  // ChannelzSecurityValue defines the interface that GetSecurityValue() return value
   305  // should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
   306  // and *OtherChannelzSecurityValue.
   307  //
   308  // This API is experimental.
   309  type ChannelzSecurityValue interface {
   310  	isChannelzSecurityValue()
   311  }
   312  
   313  // OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
   314  // from GetSecurityValue(), which contains protocol specific security info. Note
   315  // the Value field will be sent to users of channelz requesting channel info, and
   316  // thus sensitive info should better be avoided.
   317  //
   318  // This API is experimental.
   319  type OtherChannelzSecurityValue struct {
   320  	ChannelzSecurityValue
   321  	Name  string
   322  	Value proto.Message
   323  }