google.golang.org/grpc@v1.62.1/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 "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.Dial(addr, opts...) 130 if err != nil { 131 t.Fatalf("grpc.Dial(%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.Dial(addr, dopts...) 169 if err != nil { 170 t.Fatalf("grpc.Dial(%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.Dial(addr, dopts...); err == nil || !strings.Contains(err.Error(), wantErr) { 205 t.Fatalf("grpc.Dial(%q) returned err %v, want: %v", addr, err, wantErr) 206 } 207 }