gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/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 "gitee.com/ks-custle/core-gm/grpc/credentials"
    24  
    25  import (
    26  	"context"
    27  	"errors"
    28  	"fmt"
    29  	"net"
    30  
    31  	"gitee.com/ks-custle/core-gm/grpc/attributes"
    32  	icredentials "gitee.com/ks-custle/core-gm/grpc/internal/credentials"
    33  	"github.com/golang/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
    40  	// tokens if required. This should be called by the transport layer on
    41  	// each 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
    43  	// for the RPC. uri is the URI of the entry point for the request.
    44  	// When supported by the underlying implementation, ctx can be used for
    45  	// timeout and cancellation. Additionally, RequestInfo data will be
    46  	// available via ctx to this call.
    47  	// TODO(zhaoq): Define the set of the qualified keys instead of leaving
    48  	// 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  // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
   124  // and the caller should not close rawConn.
   125  var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
   126  
   127  // TransportCredentials defines the common interface for all the live gRPC wire
   128  // protocols and supported transport security protocols (e.g., TLS, SSL).
   129  type TransportCredentials interface {
   130  	// ClientHandshake does the authentication handshake specified by the
   131  	// corresponding authentication protocol on rawConn for clients. It returns
   132  	// the authenticated connection and the corresponding auth information
   133  	// about the connection.  The auth information should embed CommonAuthInfo
   134  	// to return additional information about the credentials. Implementations
   135  	// must use the provided context to implement timely cancellation.  gRPC
   136  	// will try to reconnect if the error returned is a temporary error
   137  	// (io.EOF, context.DeadlineExceeded or err.Temporary() == true).  If the
   138  	// returned error is a wrapper error, implementations should make sure that
   139  	// the error implements Temporary() to have the correct retry behaviors.
   140  	// Additionally, ClientHandshakeInfo data will be available via the context
   141  	// passed to this call.
   142  	//
   143  	// The second argument to this method is the `:authority` header value used
   144  	// while creating new streams on this connection after authentication
   145  	// succeeds. Implementations must use this as the server name during the
   146  	// authentication handshake.
   147  	//
   148  	// If the returned net.Conn is closed, it MUST close the net.Conn provided.
   149  	ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
   150  	// ServerHandshake does the authentication handshake for servers. It returns
   151  	// the authenticated connection and the corresponding auth information about
   152  	// the connection. The auth information should embed CommonAuthInfo to return additional information
   153  	// about the credentials.
   154  	//
   155  	// If the returned net.Conn is closed, it MUST close the net.Conn provided.
   156  	ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
   157  	// Info provides the ProtocolInfo of this TransportCredentials.
   158  	Info() ProtocolInfo
   159  	// Clone makes a copy of this TransportCredentials.
   160  	Clone() TransportCredentials
   161  	// OverrideServerName specifies the value used for the following:
   162  	// - verifying the hostname on the returned certificates
   163  	// - as SNI in the client's handshake to support virtual hosting
   164  	// - as the value for `:authority` header at stream creation time
   165  	//
   166  	// Deprecated: use grpc.WithAuthority instead. Will be supported
   167  	// throughout 1.x.
   168  	OverrideServerName(string) error
   169  }
   170  
   171  // Bundle is a combination of TransportCredentials and PerRPCCredentials.
   172  //
   173  // It also contains a mode switching method, so it can be used as a combination
   174  // of different credential policies.
   175  //
   176  // Bundle cannot be used together with individual TransportCredentials.
   177  // PerRPCCredentials from Bundle will be appended to other PerRPCCredentials.
   178  //
   179  // This API is experimental.
   180  type Bundle interface {
   181  	// TransportCredentials returns the transport credentials from the Bundle.
   182  	//
   183  	// Implementations must return non-nil transport credentials. If transport
   184  	// security is not needed by the Bundle, implementations may choose to
   185  	// return insecure.NewCredentials().
   186  	TransportCredentials() TransportCredentials
   187  
   188  	// PerRPCCredentials returns the per-RPC credentials from the Bundle.
   189  	//
   190  	// May be nil if per-RPC credentials are not needed.
   191  	PerRPCCredentials() PerRPCCredentials
   192  
   193  	// NewWithMode should make a copy of Bundle, and switch mode. Modifying the
   194  	// existing Bundle may cause races.
   195  	//
   196  	// NewWithMode returns nil if the requested mode is not supported.
   197  	NewWithMode(mode string) (Bundle, error)
   198  }
   199  
   200  // RequestInfo contains request data attached to the context passed to GetRequestMetadata calls.
   201  //
   202  // This API is experimental.
   203  type RequestInfo struct {
   204  	// The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method")
   205  	Method string
   206  	// AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake)
   207  	AuthInfo AuthInfo
   208  }
   209  
   210  // RequestInfoFromContext extracts the RequestInfo from the context if it exists.
   211  //
   212  // This API is experimental.
   213  func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
   214  	ri, ok = icredentials.RequestInfoFromContext(ctx).(RequestInfo)
   215  	return ri, ok
   216  }
   217  
   218  // ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes
   219  // it possible to pass arbitrary data to the handshaker from gRPC, resolver,
   220  // balancer etc. Individual credential implementations control the actual
   221  // format of the data that they are willing to receive.
   222  //
   223  // This API is experimental.
   224  type ClientHandshakeInfo struct {
   225  	// Attributes contains the attributes for the address. It could be provided
   226  	// by the gRPC, resolver, balancer etc.
   227  	Attributes *attributes.Attributes
   228  }
   229  
   230  // ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored
   231  // in ctx.
   232  //
   233  // This API is experimental.
   234  func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {
   235  	chi, _ := icredentials.ClientHandshakeInfoFromContext(ctx).(ClientHandshakeInfo)
   236  	return chi
   237  }
   238  
   239  // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
   240  // It returns success if 1) the condition is satisified or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
   241  // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
   242  //
   243  // This API is experimental.
   244  func CheckSecurityLevel(ai AuthInfo, level SecurityLevel) error {
   245  	type internalInfo interface {
   246  		GetCommonAuthInfo() CommonAuthInfo
   247  	}
   248  	if ai == nil {
   249  		return errors.New("AuthInfo is nil")
   250  	}
   251  	if ci, ok := ai.(internalInfo); ok {
   252  		// CommonAuthInfo.SecurityLevel has an invalid value.
   253  		if ci.GetCommonAuthInfo().SecurityLevel == InvalidSecurityLevel {
   254  			return nil
   255  		}
   256  		if ci.GetCommonAuthInfo().SecurityLevel < level {
   257  			return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
   258  		}
   259  	}
   260  	// The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
   261  	return nil
   262  }
   263  
   264  // ChannelzSecurityInfo defines the interface that security protocols should implement
   265  // in order to provide security info to channelz.
   266  //
   267  // This API is experimental.
   268  type ChannelzSecurityInfo interface {
   269  	GetSecurityValue() ChannelzSecurityValue
   270  }
   271  
   272  // ChannelzSecurityValue defines the interface that GetSecurityValue() return value
   273  // should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
   274  // and *OtherChannelzSecurityValue.
   275  //
   276  // This API is experimental.
   277  type ChannelzSecurityValue interface {
   278  	isChannelzSecurityValue()
   279  }
   280  
   281  // OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
   282  // from GetSecurityValue(), which contains protocol specific security info. Note
   283  // the Value field will be sent to users of channelz requesting channel info, and
   284  // thus sensitive info should better be avoided.
   285  //
   286  // This API is experimental.
   287  type OtherChannelzSecurityValue struct {
   288  	ChannelzSecurityValue
   289  	Name  string
   290  	Value proto.Message
   291  }