1
1
use crate :: {
2
- policy:: { self , AllowPolicy , GetPolicy } ,
2
+ policy:: { AllowPolicy , GetPolicy } ,
3
3
Inbound ,
4
4
} ;
5
5
use linkerd_app_core:: {
@@ -10,9 +10,6 @@ use linkerd_app_core::{
10
10
use std:: fmt:: Debug ;
11
11
use tracing:: info_span;
12
12
13
- #[ cfg( test) ]
14
- mod tests;
15
-
16
13
#[ derive( Clone , Debug ) ]
17
14
pub ( crate ) struct Accept {
18
15
client_addr : Remote < ClientAddr > ,
@@ -29,7 +26,7 @@ impl<N> Inbound<N> {
29
26
pub ( crate ) fn push_accept < T , I , NSvc , D , DSvc > (
30
27
self ,
31
28
proxy_port : u16 ,
32
- policies : impl GetPolicy ,
29
+ policies : impl GetPolicy + Clone + Send + Sync + ' static ,
33
30
direct : D ,
34
31
) -> Inbound < svc:: ArcNewTcp < T , I > >
35
32
where
@@ -49,24 +46,6 @@ impl<N> Inbound<N> {
49
46
{
50
47
self . map_stack ( |cfg, rt, accept| {
51
48
accept
52
- . push_on_service ( svc:: MapErr :: layer_boxed ( ) )
53
- . push_map_target ( |( policy, t) : ( AllowPolicy , T ) | {
54
- tracing:: debug!( policy = ?& * policy. borrow( ) , "Accepted" ) ;
55
- Accept {
56
- client_addr : t. param ( ) ,
57
- orig_dst_addr : t. param ( ) ,
58
- policy,
59
- }
60
- } )
61
- . lift_new_with_target ( )
62
- . push ( policy:: Discover :: layer_via ( policies, |t : & T | {
63
- // For non-direct inbound connections, policies are always
64
- // looked up for the original destination address.
65
- let OrigDstAddr ( addr) = t. param ( ) ;
66
- policy:: LookupAddr ( addr)
67
- } ) )
68
- . into_new_service ( )
69
- . check_new_service :: < T , I > ( )
70
49
. push_switch (
71
50
// Switch to the `direct` stack when a connection's original destination is the
72
51
// proxy's inbound port. Otherwise, check that connections are allowed on the
@@ -77,7 +56,13 @@ impl<N> Inbound<N> {
77
56
return Ok ( svc:: Either :: B ( t) ) ;
78
57
}
79
58
80
- Ok ( svc:: Either :: A ( t) )
59
+ let policy = policies. get_policy ( addr) ;
60
+ tracing:: debug!( policy = ?& * policy. borrow( ) , "Accepted" ) ;
61
+ Ok ( svc:: Either :: A ( Accept {
62
+ client_addr : t. param ( ) ,
63
+ orig_dst_addr : addr,
64
+ policy,
65
+ } ) )
81
66
} ,
82
67
direct,
83
68
)
@@ -120,3 +105,109 @@ impl svc::Param<AllowPolicy> for Accept {
120
105
self . policy . clone ( )
121
106
}
122
107
}
108
+
109
+ #[ cfg( test) ]
110
+ mod tests {
111
+ use super :: * ;
112
+ use crate :: {
113
+ policy:: { DefaultPolicy , Store } ,
114
+ test_util,
115
+ } ;
116
+ use futures:: future;
117
+ use linkerd_app_core:: {
118
+ svc:: { NewService , ServiceExt } ,
119
+ Error ,
120
+ } ;
121
+ use linkerd_proxy_server_policy:: { Authentication , Authorization , Meta , ServerPolicy } ;
122
+ use std:: sync:: Arc ;
123
+
124
+ #[ tokio:: test( flavor = "current_thread" ) ]
125
+ async fn default_allow ( ) {
126
+ let ( io, _) = io:: duplex ( 1 ) ;
127
+ let policies = Store :: for_test (
128
+ ServerPolicy {
129
+ protocol : linkerd_proxy_server_policy:: Protocol :: Opaque ( Arc :: new ( [
130
+ Authorization {
131
+ authentication : Authentication :: Unauthenticated ,
132
+ networks : vec ! [ Default :: default ( ) ] ,
133
+ meta : Arc :: new ( Meta :: Resource {
134
+ group : "policy.linkerd.io" . into ( ) ,
135
+ kind : "serverauthorization" . into ( ) ,
136
+ name : "testsaz" . into ( ) ,
137
+ } ) ,
138
+ } ,
139
+ ] ) ) ,
140
+ meta : Arc :: new ( Meta :: Resource {
141
+ group : "policy.linkerd.io" . into ( ) ,
142
+ kind : "server" . into ( ) ,
143
+ name : "testsrv" . into ( ) ,
144
+ } ) ,
145
+ } ,
146
+ None ,
147
+ ) ;
148
+ inbound ( )
149
+ . with_stack ( new_ok ( ) )
150
+ . push_accept ( 999 , policies, new_panic ( "direct stack must not be built" ) )
151
+ . into_inner ( )
152
+ . new_service ( Target ( 1000 ) )
153
+ . oneshot ( io)
154
+ . await
155
+ . expect ( "should succeed" ) ;
156
+ }
157
+
158
+ /// Default-deny authorizations are checked by an internal stack.
159
+ #[ tokio:: test( flavor = "current_thread" ) ]
160
+ async fn default_deny ( ) {
161
+ let policies = Store :: for_test ( DefaultPolicy :: Deny , None ) ;
162
+ let ( io, _) = io:: duplex ( 1 ) ;
163
+ inbound ( )
164
+ . with_stack ( new_ok ( ) )
165
+ . push_accept ( 999 , policies, new_panic ( "direct stack must not be built" ) )
166
+ . into_inner ( )
167
+ . new_service ( Target ( 1000 ) )
168
+ . oneshot ( io)
169
+ . await
170
+ . expect ( "should succeed" ) ;
171
+ }
172
+
173
+ #[ tokio:: test( flavor = "current_thread" ) ]
174
+ async fn direct ( ) {
175
+ let policies = Store :: for_test ( DefaultPolicy :: Deny , None ) ;
176
+ let ( io, _) = io:: duplex ( 1 ) ;
177
+ inbound ( )
178
+ . with_stack ( new_panic ( "detect stack must not be built" ) )
179
+ . push_accept ( 999 , policies, new_ok ( ) )
180
+ . into_inner ( )
181
+ . new_service ( Target ( 999 ) )
182
+ . oneshot ( io)
183
+ . await
184
+ . expect ( "should succeed" ) ;
185
+ }
186
+
187
+ fn inbound ( ) -> Inbound < ( ) > {
188
+ Inbound :: new ( test_util:: default_config ( ) , test_util:: runtime ( ) . 0 )
189
+ }
190
+
191
+ fn new_panic < T > ( msg : & ' static str ) -> svc:: ArcNewTcp < T , io:: DuplexStream > {
192
+ svc:: ArcNewService :: new ( move |_| panic ! ( "{msg}" ) )
193
+ }
194
+
195
+ fn new_ok < T > ( ) -> svc:: ArcNewTcp < T , io:: DuplexStream > {
196
+ svc:: ArcNewService :: new ( |_| svc:: BoxService :: new ( svc:: mk ( |_| future:: ok :: < ( ) , Error > ( ( ) ) ) ) )
197
+ }
198
+
199
+ #[ derive( Clone , Debug ) ]
200
+ struct Target ( u16 ) ;
201
+
202
+ impl svc:: Param < OrigDstAddr > for Target {
203
+ fn param ( & self ) -> OrigDstAddr {
204
+ OrigDstAddr ( ( [ 192 , 0 , 2 , 2 ] , self . 0 ) . into ( ) )
205
+ }
206
+ }
207
+
208
+ impl svc:: Param < Remote < ClientAddr > > for Target {
209
+ fn param ( & self ) -> Remote < ClientAddr > {
210
+ Remote ( ClientAddr ( ( [ 192 , 0 , 2 , 3 ] , 54321 ) . into ( ) ) )
211
+ }
212
+ }
213
+ }
0 commit comments