google.golang.org/grpc@v1.72.2/test/insecure_creds_test.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 test 20 21 import ( 22 "context" 23 "strings" 24 "testing" 25 26 "google.golang.org/grpc" 27 "google.golang.org/grpc/codes" 28 "google.golang.org/grpc/credentials" 29 "google.golang.org/grpc/credentials/insecure" 30 "google.golang.org/grpc/internal/stubserver" 31 "google.golang.org/grpc/internal/testutils" 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(context.Context, ...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 lis, err := testutils.LocalTCPListener() 87 if err != nil { 88 t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err) 89 } 90 91 ss := &stubserver.StubServer{ 92 Listener: lis, 93 EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) { 94 if !test.serverInsecureCreds { 95 return &testpb.Empty{}, nil 96 } 97 98 pr, ok := peer.FromContext(ctx) 99 if !ok { 100 return nil, status.Error(codes.DataLoss, "Failed to get peer from ctx") 101 } 102 // Check security level. 103 secLevel := getSecurityLevel(pr.AuthInfo) 104 if secLevel == credentials.InvalidSecurityLevel { 105 return nil, status.Errorf(codes.Unauthenticated, "peer.AuthInfo does not implement GetCommonAuthInfo()") 106 } 107 if secLevel != credentials.NoSecurity { 108 return nil, status.Errorf(codes.Unauthenticated, "Wrong security level: got %q, want %q", secLevel, credentials.NoSecurity) 109 } 110 return &testpb.Empty{}, nil 111 }, 112 } 113 sOpts := []grpc.ServerOption{} 114 if test.serverInsecureCreds { 115 ss.S = grpc.NewServer(grpc.Creds(insecure.NewCredentials())) 116 } else { 117 ss.S = grpc.NewServer(sOpts...) 118 } 119 stubserver.StartTestService(t, ss) 120 defer ss.S.Stop() 121 addr := lis.Addr().String() 122 opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} 123 cc, err := grpc.NewClient(addr, opts...) 124 if err != nil { 125 t.Fatalf("grpc.NewClient(%q) failed: %v", addr, err) 126 } 127 defer cc.Close() 128 129 c := testgrpc.NewTestServiceClient(cc) 130 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 131 defer cancel() 132 if _, err = c.EmptyCall(ctx, &testpb.Empty{}); err != nil { 133 t.Fatalf("EmptyCall(_, _) = _, %v; want _, <nil>", err) 134 } 135 }) 136 } 137 } 138 139 func (s) TestInsecureCreds_WithPerRPCCredentials_AsCallOption(t *testing.T) { 140 lis, err := testutils.LocalTCPListener() 141 if err != nil { 142 t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err) 143 } 144 145 ss := &stubserver.StubServer{ 146 Listener: lis, 147 EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { 148 return &testpb.Empty{}, nil 149 }, 150 S: grpc.NewServer(grpc.Creds(insecure.NewCredentials())), 151 } 152 stubserver.StartTestService(t, ss) 153 defer ss.S.Stop() 154 155 addr := lis.Addr().String() 156 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 157 defer cancel() 158 159 dopts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} 160 copts := []grpc.CallOption{grpc.PerRPCCredentials(testLegacyPerRPCCredentials{})} 161 cc, err := grpc.NewClient(addr, dopts...) 162 if err != nil { 163 t.Fatalf("grpc.NewClient(%q) failed: %v", addr, err) 164 } 165 defer cc.Close() 166 167 const wantErr = "transport: cannot send secure credentials on an insecure connection" 168 c := testgrpc.NewTestServiceClient(cc) 169 if _, err = c.EmptyCall(ctx, &testpb.Empty{}, copts...); err == nil || !strings.Contains(err.Error(), wantErr) { 170 t.Fatalf("insecure credentials with per-RPC credentials requiring transport security returned error: %v; want %s", err, wantErr) 171 } 172 } 173 174 func (s) TestInsecureCreds_WithPerRPCCredentials_AsDialOption(t *testing.T) { 175 lis, err := testutils.LocalTCPListener() 176 if err != nil { 177 t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err) 178 } 179 ss := &stubserver.StubServer{ 180 Listener: lis, 181 EmptyCallF: func(_ context.Context, _ *testpb.Empty) (*testpb.Empty, error) { 182 return &testpb.Empty{}, nil 183 }, 184 S: grpc.NewServer(grpc.Creds(insecure.NewCredentials())), 185 } 186 stubserver.StartTestService(t, ss) 187 defer ss.S.Stop() 188 189 addr := lis.Addr().String() 190 dopts := []grpc.DialOption{ 191 grpc.WithTransportCredentials(insecure.NewCredentials()), 192 grpc.WithPerRPCCredentials(testLegacyPerRPCCredentials{}), 193 } 194 const wantErr = "the credentials require transport level security" 195 if _, err := grpc.NewClient(addr, dopts...); err == nil || !strings.Contains(err.Error(), wantErr) { 196 t.Fatalf("grpc.NewClient(%q) returned err %v, want: %v", addr, err, wantErr) 197 } 198 }