1
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
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
60
61
62
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
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