credentials.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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/attributes"
  30. icredentials "google.golang.org/grpc/internal/credentials"
  31. )
  32. // PerRPCCredentials defines the common interface for the credentials which need to
  33. // attach security information to every RPC (e.g., oauth2).
  34. type PerRPCCredentials interface {
  35. // GetRequestMetadata gets the current request metadata, refreshing tokens
  36. // if required. This should be called by the transport layer on each
  37. // request, and the data should be populated in headers or other
  38. // context. If a status code is returned, it will be used as the status for
  39. // the RPC (restricted to an allowable set of codes as defined by gRFC
  40. // A54). uri is the URI of the entry point for the request. When supported
  41. // by the underlying implementation, ctx can be used for timeout and
  42. // cancellation. Additionally, RequestInfo data will be available via ctx
  43. // to this call. TODO(zhaoq): Define the set of the qualified keys instead
  44. // of leaving it as an arbitrary string.
  45. GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
  46. // RequireTransportSecurity indicates whether the credentials requires
  47. // transport security.
  48. RequireTransportSecurity() bool
  49. }
  50. // SecurityLevel defines the protection level on an established connection.
  51. //
  52. // This API is experimental.
  53. type SecurityLevel int
  54. const (
  55. // InvalidSecurityLevel indicates an invalid security level.
  56. // The zero SecurityLevel value is invalid for backward compatibility.
  57. InvalidSecurityLevel SecurityLevel = iota
  58. // NoSecurity indicates a connection is insecure.
  59. NoSecurity
  60. // IntegrityOnly indicates a connection only provides integrity protection.
  61. IntegrityOnly
  62. // PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection.
  63. PrivacyAndIntegrity
  64. )
  65. // String returns SecurityLevel in a string format.
  66. func (s SecurityLevel) String() string {
  67. switch s {
  68. case NoSecurity:
  69. return "NoSecurity"
  70. case IntegrityOnly:
  71. return "IntegrityOnly"
  72. case PrivacyAndIntegrity:
  73. return "PrivacyAndIntegrity"
  74. }
  75. return fmt.Sprintf("invalid SecurityLevel: %v", int(s))
  76. }
  77. // CommonAuthInfo contains authenticated information common to AuthInfo implementations.
  78. // It should be embedded in a struct implementing AuthInfo to provide additional information
  79. // about the credentials.
  80. //
  81. // This API is experimental.
  82. type CommonAuthInfo struct {
  83. SecurityLevel SecurityLevel
  84. }
  85. // GetCommonAuthInfo returns the pointer to CommonAuthInfo struct.
  86. func (c CommonAuthInfo) GetCommonAuthInfo() CommonAuthInfo {
  87. return c
  88. }
  89. // ProtocolInfo provides information regarding the gRPC wire protocol version,
  90. // security protocol, security protocol version in use, server name, etc.
  91. type ProtocolInfo struct {
  92. // ProtocolVersion is the gRPC wire protocol version.
  93. ProtocolVersion string
  94. // SecurityProtocol is the security protocol in use.
  95. SecurityProtocol string
  96. // SecurityVersion is the security protocol version. It is a static version string from the
  97. // credentials, not a value that reflects per-connection protocol negotiation. To retrieve
  98. // details about the credentials used for a connection, use the Peer's AuthInfo field instead.
  99. //
  100. // Deprecated: please use Peer.AuthInfo.
  101. SecurityVersion string
  102. // ServerName is the user-configured server name.
  103. ServerName string
  104. }
  105. // AuthInfo defines the common interface for the auth information the users are interested in.
  106. // A struct that implements AuthInfo should embed CommonAuthInfo by including additional
  107. // information about the credentials in it.
  108. type AuthInfo interface {
  109. AuthType() string
  110. }
  111. // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
  112. // and the caller should not close rawConn.
  113. var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
  114. // TransportCredentials defines the common interface for all the live gRPC wire
  115. // protocols and supported transport security protocols (e.g., TLS, SSL).
  116. type TransportCredentials interface {
  117. // ClientHandshake does the authentication handshake specified by the
  118. // corresponding authentication protocol on rawConn for clients. It returns
  119. // the authenticated connection and the corresponding auth information
  120. // about the connection. The auth information should embed CommonAuthInfo
  121. // to return additional information about the credentials. Implementations
  122. // must use the provided context to implement timely cancellation. gRPC
  123. // will try to reconnect if the error returned is a temporary error
  124. // (io.EOF, context.DeadlineExceeded or err.Temporary() == true). If the
  125. // returned error is a wrapper error, implementations should make sure that
  126. // the error implements Temporary() to have the correct retry behaviors.
  127. // Additionally, ClientHandshakeInfo data will be available via the context
  128. // passed to this call.
  129. //
  130. // The second argument to this method is the `:authority` header value used
  131. // while creating new streams on this connection after authentication
  132. // succeeds. Implementations must use this as the server name during the
  133. // authentication handshake.
  134. //
  135. // If the returned net.Conn is closed, it MUST close the net.Conn provided.
  136. ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
  137. // ServerHandshake does the authentication handshake for servers. It returns
  138. // the authenticated connection and the corresponding auth information about
  139. // the connection. The auth information should embed CommonAuthInfo to return additional information
  140. // about the credentials.
  141. //
  142. // If the returned net.Conn is closed, it MUST close the net.Conn provided.
  143. ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
  144. // Info provides the ProtocolInfo of this TransportCredentials.
  145. Info() ProtocolInfo
  146. // Clone makes a copy of this TransportCredentials.
  147. Clone() TransportCredentials
  148. // OverrideServerName specifies the value used for the following:
  149. // - verifying the hostname on the returned certificates
  150. // - as SNI in the client's handshake to support virtual hosting
  151. // - as the value for `:authority` header at stream creation time
  152. //
  153. // Deprecated: use grpc.WithAuthority instead. Will be supported
  154. // throughout 1.x.
  155. OverrideServerName(string) error
  156. }
  157. // Bundle is a combination of TransportCredentials and PerRPCCredentials.
  158. //
  159. // It also contains a mode switching method, so it can be used as a combination
  160. // of different credential policies.
  161. //
  162. // Bundle cannot be used together with individual TransportCredentials.
  163. // PerRPCCredentials from Bundle will be appended to other PerRPCCredentials.
  164. //
  165. // This API is experimental.
  166. type Bundle interface {
  167. // TransportCredentials returns the transport credentials from the Bundle.
  168. //
  169. // Implementations must return non-nil transport credentials. If transport
  170. // security is not needed by the Bundle, implementations may choose to
  171. // return insecure.NewCredentials().
  172. TransportCredentials() TransportCredentials
  173. // PerRPCCredentials returns the per-RPC credentials from the Bundle.
  174. //
  175. // May be nil if per-RPC credentials are not needed.
  176. PerRPCCredentials() PerRPCCredentials
  177. // NewWithMode should make a copy of Bundle, and switch mode. Modifying the
  178. // existing Bundle may cause races.
  179. //
  180. // NewWithMode returns nil if the requested mode is not supported.
  181. NewWithMode(mode string) (Bundle, error)
  182. }
  183. // RequestInfo contains request data attached to the context passed to GetRequestMetadata calls.
  184. //
  185. // This API is experimental.
  186. type RequestInfo struct {
  187. // The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method")
  188. Method string
  189. // AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake)
  190. AuthInfo AuthInfo
  191. }
  192. // RequestInfoFromContext extracts the RequestInfo from the context if it exists.
  193. //
  194. // This API is experimental.
  195. func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
  196. ri, ok = icredentials.RequestInfoFromContext(ctx).(RequestInfo)
  197. return ri, ok
  198. }
  199. // ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes
  200. // it possible to pass arbitrary data to the handshaker from gRPC, resolver,
  201. // balancer etc. Individual credential implementations control the actual
  202. // format of the data that they are willing to receive.
  203. //
  204. // This API is experimental.
  205. type ClientHandshakeInfo struct {
  206. // Attributes contains the attributes for the address. It could be provided
  207. // by the gRPC, resolver, balancer etc.
  208. Attributes *attributes.Attributes
  209. }
  210. // ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored
  211. // in ctx.
  212. //
  213. // This API is experimental.
  214. func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {
  215. chi, _ := icredentials.ClientHandshakeInfoFromContext(ctx).(ClientHandshakeInfo)
  216. return chi
  217. }
  218. // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
  219. // It returns success if 1) the condition is satisified or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
  220. // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
  221. //
  222. // This API is experimental.
  223. func CheckSecurityLevel(ai AuthInfo, level SecurityLevel) error {
  224. type internalInfo interface {
  225. GetCommonAuthInfo() CommonAuthInfo
  226. }
  227. if ai == nil {
  228. return errors.New("AuthInfo is nil")
  229. }
  230. if ci, ok := ai.(internalInfo); ok {
  231. // CommonAuthInfo.SecurityLevel has an invalid value.
  232. if ci.GetCommonAuthInfo().SecurityLevel == InvalidSecurityLevel {
  233. return nil
  234. }
  235. if ci.GetCommonAuthInfo().SecurityLevel < level {
  236. return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
  237. }
  238. }
  239. // The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
  240. return nil
  241. }
  242. // ChannelzSecurityInfo defines the interface that security protocols should implement
  243. // in order to provide security info to channelz.
  244. //
  245. // This API is experimental.
  246. type ChannelzSecurityInfo interface {
  247. GetSecurityValue() ChannelzSecurityValue
  248. }
  249. // ChannelzSecurityValue defines the interface that GetSecurityValue() return value
  250. // should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
  251. // and *OtherChannelzSecurityValue.
  252. //
  253. // This API is experimental.
  254. type ChannelzSecurityValue interface {
  255. isChannelzSecurityValue()
  256. }
  257. // OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
  258. // from GetSecurityValue(), which contains protocol specific security info. Note
  259. // the Value field will be sent to users of channelz requesting channel info, and
  260. // thus sensitive info should better be avoided.
  261. //
  262. // This API is experimental.
  263. type OtherChannelzSecurityValue struct {
  264. ChannelzSecurityValue
  265. Name string
  266. Value proto.Message
  267. }