credentials.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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. // Package credentials implements various credentials supported by gRPC library,
  19. // which encapsulate all the state needed by a client to authenticate with a
  20. // server and make various assertions, e.g., about the client's identity, role,
  21. // or whether it is authorized to make a particular call.
  22. package credentials // import "google.golang.org/grpc/credentials"
  23. import (
  24. "context"
  25. "errors"
  26. "fmt"
  27. "net"
  28. "github.com/golang/protobuf/proto"
  29. "google.golang.org/grpc/internal"
  30. )
  31. // PerRPCCredentials defines the common interface for the credentials which need to
  32. // attach security information to every RPC (e.g., oauth2).
  33. type PerRPCCredentials interface {
  34. // GetRequestMetadata gets the current request metadata, refreshing
  35. // tokens if required. This should be called by the transport layer on
  36. // each request, and the data should be populated in headers or other
  37. // context. If a status code is returned, it will be used as the status
  38. // for the RPC. uri is the URI of the entry point for the request.
  39. // When supported by the underlying implementation, ctx can be used for
  40. // timeout and cancellation. Additionally, RequestInfo data will be
  41. // available via ctx to this call.
  42. // TODO(zhaoq): Define the set of the qualified keys instead of leaving
  43. // it as an arbitrary string.
  44. GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
  45. // RequireTransportSecurity indicates whether the credentials requires
  46. // transport security.
  47. RequireTransportSecurity() bool
  48. }
  49. // SecurityLevel defines the protection level on an established connection.
  50. //
  51. // This API is experimental.
  52. type SecurityLevel int
  53. const (
  54. // NoSecurity indicates a connection is insecure.
  55. // The zero SecurityLevel value is invalid for backward compatibility.
  56. NoSecurity SecurityLevel = iota + 1
  57. // IntegrityOnly indicates a connection only provides integrity protection.
  58. IntegrityOnly
  59. // PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection.
  60. PrivacyAndIntegrity
  61. )
  62. // String returns SecurityLevel in a string format.
  63. func (s SecurityLevel) String() string {
  64. switch s {
  65. case NoSecurity:
  66. return "NoSecurity"
  67. case IntegrityOnly:
  68. return "IntegrityOnly"
  69. case PrivacyAndIntegrity:
  70. return "PrivacyAndIntegrity"
  71. }
  72. return fmt.Sprintf("invalid SecurityLevel: %v", int(s))
  73. }
  74. // CommonAuthInfo contains authenticated information common to AuthInfo implementations.
  75. // It should be embedded in a struct implementing AuthInfo to provide additional information
  76. // about the credentials.
  77. //
  78. // This API is experimental.
  79. type CommonAuthInfo struct {
  80. SecurityLevel SecurityLevel
  81. }
  82. // GetCommonAuthInfo returns the pointer to CommonAuthInfo struct.
  83. func (c *CommonAuthInfo) GetCommonAuthInfo() *CommonAuthInfo {
  84. return c
  85. }
  86. // ProtocolInfo provides information regarding the gRPC wire protocol version,
  87. // security protocol, security protocol version in use, server name, etc.
  88. type ProtocolInfo struct {
  89. // ProtocolVersion is the gRPC wire protocol version.
  90. ProtocolVersion string
  91. // SecurityProtocol is the security protocol in use.
  92. SecurityProtocol string
  93. // SecurityVersion is the security protocol version. It is a static version string from the
  94. // credentials, not a value that reflects per-connection protocol negotiation. To retrieve
  95. // details about the credentials used for a connection, use the Peer's AuthInfo field instead.
  96. //
  97. // Deprecated: please use Peer.AuthInfo.
  98. SecurityVersion string
  99. // ServerName is the user-configured server name.
  100. ServerName string
  101. }
  102. // AuthInfo defines the common interface for the auth information the users are interested in.
  103. // A struct that implements AuthInfo should embed CommonAuthInfo by including additional
  104. // information about the credentials in it.
  105. type AuthInfo interface {
  106. AuthType() string
  107. }
  108. // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
  109. // and the caller should not close rawConn.
  110. var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
  111. // TransportCredentials defines the common interface for all the live gRPC wire
  112. // protocols and supported transport security protocols (e.g., TLS, SSL).
  113. type TransportCredentials interface {
  114. // ClientHandshake does the authentication handshake specified by the corresponding
  115. // authentication protocol on rawConn for clients. It returns the authenticated
  116. // connection and the corresponding auth information about the connection.
  117. // The auth information should embed CommonAuthInfo to return additional information about
  118. // the credentials. Implementations must use the provided context to implement timely cancellation.
  119. // gRPC will try to reconnect if the error returned is a temporary error
  120. // (io.EOF, context.DeadlineExceeded or err.Temporary() == true).
  121. // If the returned error is a wrapper error, implementations should make sure that
  122. // the error implements Temporary() to have the correct retry behaviors.
  123. //
  124. // If the returned net.Conn is closed, it MUST close the net.Conn provided.
  125. ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
  126. // ServerHandshake does the authentication handshake for servers. It returns
  127. // the authenticated connection and the corresponding auth information about
  128. // the connection. The auth information should embed CommonAuthInfo to return additional information
  129. // about the credentials.
  130. //
  131. // If the returned net.Conn is closed, it MUST close the net.Conn provided.
  132. ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
  133. // Info provides the ProtocolInfo of this TransportCredentials.
  134. Info() ProtocolInfo
  135. // Clone makes a copy of this TransportCredentials.
  136. Clone() TransportCredentials
  137. // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server.
  138. // gRPC internals also use it to override the virtual hosting name if it is set.
  139. // It must be called before dialing. Currently, this is only used by grpclb.
  140. OverrideServerName(string) error
  141. }
  142. // Bundle is a combination of TransportCredentials and PerRPCCredentials.
  143. //
  144. // It also contains a mode switching method, so it can be used as a combination
  145. // of different credential policies.
  146. //
  147. // Bundle cannot be used together with individual TransportCredentials.
  148. // PerRPCCredentials from Bundle will be appended to other PerRPCCredentials.
  149. //
  150. // This API is experimental.
  151. type Bundle interface {
  152. TransportCredentials() TransportCredentials
  153. PerRPCCredentials() PerRPCCredentials
  154. // NewWithMode should make a copy of Bundle, and switch mode. Modifying the
  155. // existing Bundle may cause races.
  156. //
  157. // NewWithMode returns nil if the requested mode is not supported.
  158. NewWithMode(mode string) (Bundle, error)
  159. }
  160. // RequestInfo contains request data attached to the context passed to GetRequestMetadata calls.
  161. //
  162. // This API is experimental.
  163. type RequestInfo struct {
  164. // The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method")
  165. Method string
  166. // AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake)
  167. AuthInfo AuthInfo
  168. }
  169. // requestInfoKey is a struct to be used as the key when attaching a RequestInfo to a context object.
  170. type requestInfoKey struct{}
  171. // RequestInfoFromContext extracts the RequestInfo from the context if it exists.
  172. //
  173. // This API is experimental.
  174. func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
  175. ri, ok = ctx.Value(requestInfoKey{}).(RequestInfo)
  176. return
  177. }
  178. // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
  179. // It returns success if 1) the condition is satisified or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
  180. // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
  181. //
  182. // This API is experimental.
  183. func CheckSecurityLevel(ctx context.Context, level SecurityLevel) error {
  184. type internalInfo interface {
  185. GetCommonAuthInfo() *CommonAuthInfo
  186. }
  187. ri, _ := RequestInfoFromContext(ctx)
  188. if ri.AuthInfo == nil {
  189. return errors.New("unable to obtain SecurityLevel from context")
  190. }
  191. if ci, ok := ri.AuthInfo.(internalInfo); ok {
  192. // CommonAuthInfo.SecurityLevel has an invalid value.
  193. if ci.GetCommonAuthInfo().SecurityLevel == 0 {
  194. return nil
  195. }
  196. if ci.GetCommonAuthInfo().SecurityLevel < level {
  197. return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
  198. }
  199. }
  200. // The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
  201. return nil
  202. }
  203. func init() {
  204. internal.NewRequestInfoContext = func(ctx context.Context, ri RequestInfo) context.Context {
  205. return context.WithValue(ctx, requestInfoKey{}, ri)
  206. }
  207. }
  208. // ChannelzSecurityInfo defines the interface that security protocols should implement
  209. // in order to provide security info to channelz.
  210. //
  211. // This API is experimental.
  212. type ChannelzSecurityInfo interface {
  213. GetSecurityValue() ChannelzSecurityValue
  214. }
  215. // ChannelzSecurityValue defines the interface that GetSecurityValue() return value
  216. // should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
  217. // and *OtherChannelzSecurityValue.
  218. //
  219. // This API is experimental.
  220. type ChannelzSecurityValue interface {
  221. isChannelzSecurityValue()
  222. }
  223. // OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
  224. // from GetSecurityValue(), which contains protocol specific security info. Note
  225. // the Value field will be sent to users of channelz requesting channel info, and
  226. // thus sensitive info should better be avoided.
  227. //
  228. // This API is experimental.
  229. type OtherChannelzSecurityValue struct {
  230. ChannelzSecurityValue
  231. Name string
  232. Value proto.Message
  233. }