...

Source file src/google.golang.org/grpc/test/insecure_creds_test.go

Documentation: google.golang.org/grpc/test

     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 test
    20  
    21  import (
    22  	"context"
    23  	"net"
    24  	"strings"
    25  	"testing"
    26  
    27  	"google.golang.org/grpc"
    28  	"google.golang.org/grpc/codes"
    29  	"google.golang.org/grpc/credentials"
    30  	"google.golang.org/grpc/credentials/insecure"
    31  	"google.golang.org/grpc/internal/stubserver"
    32  	"google.golang.org/grpc/peer"
    33  	"google.golang.org/grpc/status"
    34  
    35  	testgrpc "google.golang.org/grpc/interop/grpc_testing"
    36  	testpb "google.golang.org/grpc/interop/grpc_testing"
    37  )
    38  
    39  // testLegacyPerRPCCredentials is a PerRPCCredentials that has yet incorporated security level.
    40  type testLegacyPerRPCCredentials struct{}
    41  
    42  func (cr testLegacyPerRPCCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
    43  	return nil, nil
    44  }
    45  
    46  func (cr testLegacyPerRPCCredentials) RequireTransportSecurity() bool {
    47  	return true
    48  }
    49  
    50  func getSecurityLevel(ai credentials.AuthInfo) credentials.SecurityLevel {
    51  	if c, ok := ai.(interface {
    52  		GetCommonAuthInfo() credentials.CommonAuthInfo
    53  	}); ok {
    54  		return c.GetCommonAuthInfo().SecurityLevel
    55  	}
    56  	return credentials.InvalidSecurityLevel
    57  }
    58  
    59  // TestInsecureCreds tests the use of insecure creds on the server and client
    60  // side, and verifies that expect security level and auth info are returned.
    61  // Also verifies that this credential can interop with existing `WithInsecure`
    62  // DialOption.
    63  func (s) TestInsecureCreds(t *testing.T) {
    64  	tests := []struct {
    65  		desc                string
    66  		clientInsecureCreds bool
    67  		serverInsecureCreds bool
    68  	}{
    69  		{
    70  			desc:                "client and server insecure creds",
    71  			clientInsecureCreds: true,
    72  			serverInsecureCreds: true,
    73  		},
    74  		{
    75  			desc:                "client only insecure creds",
    76  			clientInsecureCreds: true,
    77  		},
    78  		{
    79  			desc:                "server only insecure creds",
    80  			serverInsecureCreds: true,
    81  		},
    82  	}
    83  
    84  	for _, test := range tests {
    85  		t.Run(test.desc, func(t *testing.T) {
    86  			ss := &stubserver.StubServer{
    87  				EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) {
    88  					if !test.serverInsecureCreds {
    89  						return &testpb.Empty{}, nil
    90  					}
    91  
    92  					pr, ok := peer.FromContext(ctx)
    93  					if !ok {
    94  						return nil, status.Error(codes.DataLoss, "Failed to get peer from ctx")
    95  					}
    96  					// Check security level.
    97  					secLevel := getSecurityLevel(pr.AuthInfo)
    98  					if secLevel == credentials.InvalidSecurityLevel {
    99  						return nil, status.Errorf(codes.Unauthenticated, "peer.AuthInfo does not implement GetCommonAuthInfo()")
   100  					}
   101  					if secLevel != credentials.NoSecurity {
   102  						return nil, status.Errorf(codes.Unauthenticated, "Wrong security level: got %q, want %q", secLevel, credentials.NoSecurity)
   103  					}
   104  					return &testpb.Empty{}, nil
   105  				},
   106  			}
   107  
   108  			sOpts := []grpc.ServerOption{}
   109  			if test.serverInsecureCreds {
   110  				sOpts = append(sOpts, grpc.Creds(insecure.NewCredentials()))
   111  			}
   112  			s := grpc.NewServer(sOpts...)
   113  			defer s.Stop()
   114  
   115  			testgrpc.RegisterTestServiceServer(s, ss)
   116  
   117  			lis, err := net.Listen("tcp", "localhost:0")
   118  			if err != nil {
   119  				t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
   120  			}
   121  
   122  			go s.Serve(lis)
   123  
   124  			addr := lis.Addr().String()
   125  			opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
   126  			if test.clientInsecureCreds {
   127  				opts = []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
   128  			}
   129  			cc, err := grpc.NewClient(addr, opts...)
   130  			if err != nil {
   131  				t.Fatalf("grpc.NewClient(%q) failed: %v", addr, err)
   132  			}
   133  			defer cc.Close()
   134  
   135  			c := testgrpc.NewTestServiceClient(cc)
   136  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   137  			defer cancel()
   138  			if _, err = c.EmptyCall(ctx, &testpb.Empty{}); err != nil {
   139  				t.Fatalf("EmptyCall(_, _) = _, %v; want _, <nil>", err)
   140  			}
   141  		})
   142  	}
   143  }
   144  
   145  func (s) TestInsecureCreds_WithPerRPCCredentials_AsCallOption(t *testing.T) {
   146  	ss := &stubserver.StubServer{
   147  		EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) {
   148  			return &testpb.Empty{}, nil
   149  		},
   150  	}
   151  
   152  	s := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
   153  	defer s.Stop()
   154  	testgrpc.RegisterTestServiceServer(s, ss)
   155  
   156  	lis, err := net.Listen("tcp", "localhost:0")
   157  	if err != nil {
   158  		t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
   159  	}
   160  	go s.Serve(lis)
   161  
   162  	addr := lis.Addr().String()
   163  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   164  	defer cancel()
   165  
   166  	dopts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
   167  	copts := []grpc.CallOption{grpc.PerRPCCredentials(testLegacyPerRPCCredentials{})}
   168  	cc, err := grpc.NewClient(addr, dopts...)
   169  	if err != nil {
   170  		t.Fatalf("grpc.NewClient(%q) failed: %v", addr, err)
   171  	}
   172  	defer cc.Close()
   173  
   174  	const wantErr = "transport: cannot send secure credentials on an insecure connection"
   175  	c := testgrpc.NewTestServiceClient(cc)
   176  	if _, err = c.EmptyCall(ctx, &testpb.Empty{}, copts...); err == nil || !strings.Contains(err.Error(), wantErr) {
   177  		t.Fatalf("insecure credentials with per-RPC credentials requiring transport security returned error: %v; want %s", err, wantErr)
   178  	}
   179  }
   180  
   181  func (s) TestInsecureCreds_WithPerRPCCredentials_AsDialOption(t *testing.T) {
   182  	ss := &stubserver.StubServer{
   183  		EmptyCallF: func(_ context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
   184  			return &testpb.Empty{}, nil
   185  		},
   186  	}
   187  
   188  	s := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
   189  	defer s.Stop()
   190  	testgrpc.RegisterTestServiceServer(s, ss)
   191  
   192  	lis, err := net.Listen("tcp", "localhost:0")
   193  	if err != nil {
   194  		t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
   195  	}
   196  	go s.Serve(lis)
   197  
   198  	addr := lis.Addr().String()
   199  	dopts := []grpc.DialOption{
   200  		grpc.WithTransportCredentials(insecure.NewCredentials()),
   201  		grpc.WithPerRPCCredentials(testLegacyPerRPCCredentials{}),
   202  	}
   203  	const wantErr = "the credentials require transport level security"
   204  	if _, err := grpc.NewClient(addr, dopts...); err == nil || !strings.Contains(err.Error(), wantErr) {
   205  		t.Fatalf("grpc.NewClient(%q) returned err %v, want: %v", addr, err, wantErr)
   206  	}
   207  }
   208  

View as plain text