OSDN Git Service

new repo
[bytom/vapor.git] / vendor / google.golang.org / grpc / credentials / credentials.go
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         "crypto/tls"
27         "crypto/x509"
28         "errors"
29         "fmt"
30         "io/ioutil"
31         "net"
32         "strings"
33
34         "golang.org/x/net/context"
35 )
36
37 // alpnProtoStr are the specified application level protocols for gRPC.
38 var alpnProtoStr = []string{"h2"}
39
40 // PerRPCCredentials defines the common interface for the credentials which need to
41 // attach security information to every RPC (e.g., oauth2).
42 type PerRPCCredentials interface {
43         // GetRequestMetadata gets the current request metadata, refreshing
44         // tokens if required. This should be called by the transport layer on
45         // each request, and the data should be populated in headers or other
46         // context. uri is the URI of the entry point for the request. When
47         // supported by the underlying implementation, ctx can be used for
48         // timeout and cancellation.
49         // TODO(zhaoq): Define the set of the qualified keys instead of leaving
50         // it as an arbitrary string.
51         GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
52         // RequireTransportSecurity indicates whether the credentials requires
53         // transport security.
54         RequireTransportSecurity() bool
55 }
56
57 // ProtocolInfo provides information regarding the gRPC wire protocol version,
58 // security protocol, security protocol version in use, server name, etc.
59 type ProtocolInfo struct {
60         // ProtocolVersion is the gRPC wire protocol version.
61         ProtocolVersion string
62         // SecurityProtocol is the security protocol in use.
63         SecurityProtocol string
64         // SecurityVersion is the security protocol version.
65         SecurityVersion string
66         // ServerName is the user-configured server name.
67         ServerName string
68 }
69
70 // AuthInfo defines the common interface for the auth information the users are interested in.
71 type AuthInfo interface {
72         AuthType() string
73 }
74
75 // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
76 // and the caller should not close rawConn.
77 var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
78
79 // TransportCredentials defines the common interface for all the live gRPC wire
80 // protocols and supported transport security protocols (e.g., TLS, SSL).
81 type TransportCredentials interface {
82         // ClientHandshake does the authentication handshake specified by the corresponding
83         // authentication protocol on rawConn for clients. It returns the authenticated
84         // connection and the corresponding auth information about the connection.
85         // Implementations must use the provided context to implement timely cancellation.
86         // gRPC will try to reconnect if the error returned is a temporary error
87         // (io.EOF, context.DeadlineExceeded or err.Temporary() == true).
88         // If the returned error is a wrapper error, implementations should make sure that
89         // the error implements Temporary() to have the correct retry behaviors.
90         ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
91         // ServerHandshake does the authentication handshake for servers. It returns
92         // the authenticated connection and the corresponding auth information about
93         // the connection.
94         ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
95         // Info provides the ProtocolInfo of this TransportCredentials.
96         Info() ProtocolInfo
97         // Clone makes a copy of this TransportCredentials.
98         Clone() TransportCredentials
99         // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server.
100         // gRPC internals also use it to override the virtual hosting name if it is set.
101         // It must be called before dialing. Currently, this is only used by grpclb.
102         OverrideServerName(string) error
103 }
104
105 // TLSInfo contains the auth information for a TLS authenticated connection.
106 // It implements the AuthInfo interface.
107 type TLSInfo struct {
108         State tls.ConnectionState
109 }
110
111 // AuthType returns the type of TLSInfo as a string.
112 func (t TLSInfo) AuthType() string {
113         return "tls"
114 }
115
116 // tlsCreds is the credentials required for authenticating a connection using TLS.
117 type tlsCreds struct {
118         // TLS configuration
119         config *tls.Config
120 }
121
122 func (c tlsCreds) Info() ProtocolInfo {
123         return ProtocolInfo{
124                 SecurityProtocol: "tls",
125                 SecurityVersion:  "1.2",
126                 ServerName:       c.config.ServerName,
127         }
128 }
129
130 func (c *tlsCreds) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) {
131         // use local cfg to avoid clobbering ServerName if using multiple endpoints
132         cfg := cloneTLSConfig(c.config)
133         if cfg.ServerName == "" {
134                 colonPos := strings.LastIndex(authority, ":")
135                 if colonPos == -1 {
136                         colonPos = len(authority)
137                 }
138                 cfg.ServerName = authority[:colonPos]
139         }
140         conn := tls.Client(rawConn, cfg)
141         errChannel := make(chan error, 1)
142         go func() {
143                 errChannel <- conn.Handshake()
144         }()
145         select {
146         case err := <-errChannel:
147                 if err != nil {
148                         return nil, nil, err
149                 }
150         case <-ctx.Done():
151                 return nil, nil, ctx.Err()
152         }
153         return conn, TLSInfo{conn.ConnectionState()}, nil
154 }
155
156 func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) {
157         conn := tls.Server(rawConn, c.config)
158         if err := conn.Handshake(); err != nil {
159                 return nil, nil, err
160         }
161         return conn, TLSInfo{conn.ConnectionState()}, nil
162 }
163
164 func (c *tlsCreds) Clone() TransportCredentials {
165         return NewTLS(c.config)
166 }
167
168 func (c *tlsCreds) OverrideServerName(serverNameOverride string) error {
169         c.config.ServerName = serverNameOverride
170         return nil
171 }
172
173 // NewTLS uses c to construct a TransportCredentials based on TLS.
174 func NewTLS(c *tls.Config) TransportCredentials {
175         tc := &tlsCreds{cloneTLSConfig(c)}
176         tc.config.NextProtos = alpnProtoStr
177         return tc
178 }
179
180 // NewClientTLSFromCert constructs TLS credentials from the input certificate for client.
181 // serverNameOverride is for testing only. If set to a non empty string,
182 // it will override the virtual host name of authority (e.g. :authority header field) in requests.
183 func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials {
184         return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})
185 }
186
187 // NewClientTLSFromFile constructs TLS credentials from the input certificate file for client.
188 // serverNameOverride is for testing only. If set to a non empty string,
189 // it will override the virtual host name of authority (e.g. :authority header field) in requests.
190 func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
191         b, err := ioutil.ReadFile(certFile)
192         if err != nil {
193                 return nil, err
194         }
195         cp := x509.NewCertPool()
196         if !cp.AppendCertsFromPEM(b) {
197                 return nil, fmt.Errorf("credentials: failed to append certificates")
198         }
199         return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil
200 }
201
202 // NewServerTLSFromCert constructs TLS credentials from the input certificate for server.
203 func NewServerTLSFromCert(cert *tls.Certificate) TransportCredentials {
204         return NewTLS(&tls.Config{Certificates: []tls.Certificate{*cert}})
205 }
206
207 // NewServerTLSFromFile constructs TLS credentials from the input certificate file and key
208 // file for server.
209 func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error) {
210         cert, err := tls.LoadX509KeyPair(certFile, keyFile)
211         if err != nil {
212                 return nil, err
213         }
214         return NewTLS(&tls.Config{Certificates: []tls.Certificate{cert}}), nil
215 }