google.golang.org/grpc@v1.74.2/credentials/local/local.go (about) 1 /* 2 * 3 * Copyright 2020 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 local implements local transport credentials. 20 // Local credentials reports the security level based on the type 21 // of connection. If the connection is local TCP, NoSecurity will be 22 // reported, and if the connection is UDS, PrivacyAndIntegrity will be 23 // reported. If local credentials is not used in local connections 24 // (local TCP or UDS), it will fail. 25 // 26 // # Experimental 27 // 28 // Notice: This package is EXPERIMENTAL and may be changed or removed in a 29 // later release. 30 package local 31 32 import ( 33 "context" 34 "fmt" 35 "net" 36 "strings" 37 38 "google.golang.org/grpc/credentials" 39 ) 40 41 // info contains the auth information for a local connection. 42 // It implements the AuthInfo interface. 43 type info struct { 44 credentials.CommonAuthInfo 45 } 46 47 // AuthType returns the type of info as a string. 48 func (info) AuthType() string { 49 return "local" 50 } 51 52 // ValidateAuthority allows any value to be overridden for the :authority 53 // header. 54 func (info) ValidateAuthority(string) error { 55 return nil 56 } 57 58 // localTC is the credentials required to establish a local connection. 59 type localTC struct { 60 info credentials.ProtocolInfo 61 } 62 63 func (c *localTC) Info() credentials.ProtocolInfo { 64 return c.info 65 } 66 67 // getSecurityLevel returns the security level for a local connection. 68 // It returns an error if a connection is not local. 69 func getSecurityLevel(network, addr string) (credentials.SecurityLevel, error) { 70 switch { 71 // Local TCP connection 72 case strings.HasPrefix(addr, "127."), strings.HasPrefix(addr, "[::1]:"): 73 return credentials.NoSecurity, nil 74 // Windows named pipe connection 75 case network == "pipe" && strings.HasPrefix(addr, `\\.\pipe\`): 76 return credentials.NoSecurity, nil 77 // UDS connection 78 case network == "unix": 79 return credentials.PrivacyAndIntegrity, nil 80 // Not a local connection and should fail 81 default: 82 return credentials.InvalidSecurityLevel, fmt.Errorf("local credentials rejected connection to non-local address %q", addr) 83 } 84 } 85 86 func (*localTC) ClientHandshake(_ context.Context, _ string, conn net.Conn) (net.Conn, credentials.AuthInfo, error) { 87 secLevel, err := getSecurityLevel(conn.RemoteAddr().Network(), conn.RemoteAddr().String()) 88 if err != nil { 89 return nil, nil, err 90 } 91 return conn, info{credentials.CommonAuthInfo{SecurityLevel: secLevel}}, nil 92 } 93 94 func (*localTC) ServerHandshake(conn net.Conn) (net.Conn, credentials.AuthInfo, error) { 95 secLevel, err := getSecurityLevel(conn.RemoteAddr().Network(), conn.RemoteAddr().String()) 96 if err != nil { 97 return nil, nil, err 98 } 99 return conn, info{credentials.CommonAuthInfo{SecurityLevel: secLevel}}, nil 100 } 101 102 // NewCredentials returns a local credential implementing credentials.TransportCredentials. 103 func NewCredentials() credentials.TransportCredentials { 104 return &localTC{ 105 info: credentials.ProtocolInfo{ 106 SecurityProtocol: "local", 107 }, 108 } 109 } 110 111 // Clone makes a copy of Local credentials. 112 func (c *localTC) Clone() credentials.TransportCredentials { 113 return &localTC{info: c.info} 114 } 115 116 // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server. 117 // Since this feature is specific to TLS (SNI + hostname verification check), it does not take any effect for local credentials. 118 func (c *localTC) OverrideServerName(serverNameOverride string) error { 119 c.info.ServerName = serverNameOverride 120 return nil 121 }