* * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http:www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *
Package alts implements the ALTS credential support by gRPC library, which encapsulates all the state needed by a client to authenticate with a server using ALTS and make various assertions, e.g., about the client's identity, role, or whether it is authorized to make a particular call. This package is experimental.
package alts

import (
	
	
	
	
	
	

	
	core 
	
	
	altspb 
	
)

hypervisorHandshakerServiceAddress represents the default ALTS gRPC handshaker service address in the hypervisor.
defaultTimeout specifies the server handshake timeout.
ErrUntrustedPlatform is returned from ClientHandshake and ServerHandshake is running on a platform where the trustworthiness of the handshaker service is not guaranteed.
	ErrUntrustedPlatform = errors.New("ALTS: untrusted platform. ALTS is only supported on GCP")
	logger               = grpclog.Component("alts")
)
AuthInfo exposes security information from the ALTS handshake to the application. This interface is to be implemented by ALTS. Users should not need a brand new implementation of this interface. For situations like testing, any new implementation should embed this interface. This allows ALTS to add new methods to this interface.
ApplicationProtocol returns application protocol negotiated for the ALTS connection.
RecordProtocol returns the record protocol negotiated for the ALTS connection.
SecurityLevel returns the security level of the created ALTS secure channel.
PeerServiceAccount returns the peer service account.
LocalServiceAccount returns the local service account.
PeerRPCVersions returns the RPC version supported by the peer.
	PeerRPCVersions() *altspb.RpcProtocolVersions
}
ClientOptions contains the client-side options of an ALTS channel. These options will be passed to the underlying ALTS handshaker.
TargetServiceAccounts contains a list of expected target service accounts.
HandshakerServiceAddress represents the ALTS handshaker gRPC service address to connect to.
DefaultClientOptions creates a new ClientOptions object with the default values.
ServerOptions contains the server-side options of an ALTS channel. These options will be passed to the underlying ALTS handshaker.
HandshakerServiceAddress represents the ALTS handshaker gRPC service address to connect to.
DefaultServerOptions creates a new ServerOptions object with the default values.
altsTC is the credentials required for authenticating a connection using ALTS. It implements credentials.TransportCredentials interface.
NewClientCreds constructs a client-side ALTS TransportCredentials object.
NewServerCreds constructs a server-side ALTS TransportCredentials object.
func ( *ServerOptions) credentials.TransportCredentials {
	return newALTS(core.ServerSide, nil, .HandshakerServiceAddress)
}

func ( core.Side,  []string,  string) credentials.TransportCredentials {
	once.Do(func() {
		vmOnGCP = isRunningOnGCP()
	})

	if  == "" {
		 = hypervisorHandshakerServiceAddress
	}
	return &altsTC{
		info: &credentials.ProtocolInfo{
			SecurityProtocol: "alts",
			SecurityVersion:  "1.0",
		},
		side:      ,
		accounts:  ,
		hsAddress: ,
	}
}
ClientHandshake implements the client side handshake protocol.
func ( *altsTC) ( context.Context,  string,  net.Conn) ( net.Conn,  credentials.AuthInfo,  error) {
	if !vmOnGCP {
		return nil, nil, ErrUntrustedPlatform
	}
Connecting to ALTS handshaker service.
	,  := service.Dial(.hsAddress)
	if  != nil {
		return nil, nil, 
Do not close hsConn since it is shared with other handshakes.
Possible context leak: The cancel function for the child context we create will only be called a non-nil error is returned.
	var  context.CancelFunc
	,  = context.WithCancel()
	defer func() {
		if  != nil {
			()
		}
	}()

	 := handshaker.DefaultClientHandshakerOptions()
	.TargetName = 
	.TargetServiceAccounts = .accounts
	.RPCVersions = &altspb.RpcProtocolVersions{
		MaxRpcVersion: maxRPCVersion,
		MinRpcVersion: minRPCVersion,
	}
	,  := handshaker.NewClientHandshaker(, , , )
	if  != nil {
		return nil, nil, 
	}
	defer func() {
		if  != nil {
			.Close()
		}
	}()
	, ,  := .ClientHandshake()
	if  != nil {
		return nil, nil, 
	}
	,  := .(AuthInfo)
	if ! {
		return nil, nil, errors.New("client-side auth info is not of type alts.AuthInfo")
	}
	,  := checkRPCVersions(.RPCVersions, .PeerRPCVersions())
	if ! {
		return nil, nil, fmt.Errorf("server-side RPC versions are not compatible with this client, local versions: %v, peer versions: %v", .RPCVersions, .PeerRPCVersions())
	}
	return , , nil
}
ServerHandshake implements the server side ALTS handshaker.
Connecting to ALTS handshaker service.
	,  := service.Dial(.hsAddress)
	if  != nil {
		return nil, nil, 
Do not close hsConn since it's shared with other handshakes.

	,  := context.WithTimeout(context.Background(), defaultTimeout)
	defer ()
	 := handshaker.DefaultServerHandshakerOptions()
	.RPCVersions = &altspb.RpcProtocolVersions{
		MaxRpcVersion: maxRPCVersion,
		MinRpcVersion: minRPCVersion,
	}
	,  := handshaker.NewServerHandshaker(, , , )
	if  != nil {
		return nil, nil, 
	}
	defer func() {
		if  != nil {
			.Close()
		}
	}()
	, ,  := .ServerHandshake()
	if  != nil {
		return nil, nil, 
	}
	,  := .(AuthInfo)
	if ! {
		return nil, nil, errors.New("server-side auth info is not of type alts.AuthInfo")
	}
	,  := checkRPCVersions(.RPCVersions, .PeerRPCVersions())
	if ! {
		return nil, nil, fmt.Errorf("client-side RPC versions is not compatible with this server, local versions: %v, peer versions: %v", .RPCVersions, .PeerRPCVersions())
	}
	return , , nil
}

func ( *altsTC) () credentials.ProtocolInfo {
	return *.info
}

func ( *altsTC) () credentials.TransportCredentials {
	 := *.info
	var  []string
	if .accounts != nil {
		 = make([]string, len(.accounts))
		copy(, .accounts)
	}
	return &altsTC{
		info:      &,
		side:      .side,
		hsAddress: .hsAddress,
		accounts:  ,
	}
}

func ( *altsTC) ( string) error {
	.info.ServerName = 
	return nil
}
compareRPCVersion returns 0 if v1 == v2, 1 if v1 > v2 and -1 if v1 < v2.
func (,  *altspb.RpcProtocolVersions_Version) int {
	switch {
	case .GetMajor() > .GetMajor(),
		.GetMajor() == .GetMajor() && .GetMinor() > .GetMinor():
		return 1
	case .GetMajor() < .GetMajor(),
		.GetMajor() == .GetMajor() && .GetMinor() < .GetMinor():
		return -1
	}
	return 0
}
checkRPCVersions performs a version check between local and peer rpc protocol versions. This function returns true if the check passes which means both parties agreed on a common rpc protocol to use, and false otherwise. The function also returns the highest common RPC protocol version both parties agreed on.
func (,  *altspb.RpcProtocolVersions) (bool, *altspb.RpcProtocolVersions_Version) {
	if  == nil ||  == nil {
		logger.Error("invalid checkRPCVersions argument, either local or peer is nil.")
		return false, nil
	}
maxCommonVersion is MIN(local.max, peer.max).
	 := .GetMaxRpcVersion()
	if compareRPCVersions(.GetMaxRpcVersion(), .GetMaxRpcVersion()) > 0 {
		 = .GetMaxRpcVersion()
	}
minCommonVersion is MAX(local.min, peer.min).
	 := .GetMinRpcVersion()
	if compareRPCVersions(.GetMinRpcVersion(), .GetMinRpcVersion()) > 0 {
		 = .GetMinRpcVersion()
	}

	if compareRPCVersions(, ) < 0 {
		return false, nil
	}
	return true,