@@ -171,9 +171,29 @@ struct Tls {
171
171
ca : String ,
172
172
cert : String ,
173
173
key : String ,
174
+ cert_x : String ,
175
+ key_x : String ,
174
176
hostname_verification : bool ,
175
177
}
176
178
179
+ impl Tls {
180
+ fn options ( & self ) -> zk:: TlsOptions {
181
+ let mut options = zk:: TlsOptions :: default ( )
182
+ . with_pem_ca_certs ( & self . ca )
183
+ . unwrap ( )
184
+ . with_pem_identity ( & self . cert , & self . key )
185
+ . unwrap ( ) ;
186
+ if !self . hostname_verification {
187
+ options = unsafe { options. with_no_hostname_verification ( ) } ;
188
+ }
189
+ options
190
+ }
191
+
192
+ fn options_x ( & self ) -> zk:: TlsOptions {
193
+ self . options ( ) . with_pem_identity ( & self . cert_x , & self . key_x ) . unwrap ( )
194
+ }
195
+ }
196
+
177
197
struct Server {
178
198
tls : Option < Tls > ,
179
199
_dir : Option < TempDir > ,
@@ -263,7 +283,7 @@ impl Server {
263
283
let server_pem_file = dir. path ( ) . join ( "server.pem" ) ;
264
284
fs:: write ( & server_pem_file, & server_pem) . unwrap ( ) ;
265
285
266
- let client_cert = generate_client_cert ( ) ;
286
+ let client_cert = generate_client_cert ( "client" ) ;
267
287
let signed_client_cert = client_cert. serialize_pem_with_signer ( & ca_cert) . unwrap ( ) ;
268
288
let client_key = client_cert. serialize_private_key_pem ( ) ;
269
289
let client_pem = client_key. clone ( ) + & signed_client_cert;
@@ -307,12 +327,23 @@ serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory
307
327
] ,
308
328
} ;
309
329
330
+ let client_cert_x = generate_client_cert ( "client_x" ) ;
331
+ let signed_client_cert_x = client_cert_x. serialize_pem_with_signer ( & ca_cert) . unwrap ( ) ;
332
+ let client_key_x = client_cert_x. serialize_private_key_pem ( ) ;
333
+
310
334
let docker = Box :: new ( DockerCli :: default ( ) ) ;
311
335
let image = zookeeper_image ( options) ;
312
336
let container = unsafe { std:: mem:: transmute ( docker. run ( image) ) } ;
313
337
314
338
Self {
315
- tls : Some ( Tls { ca : ca_cert_pem, cert : signed_client_cert, key : client_key, hostname_verification } ) ,
339
+ tls : Some ( Tls {
340
+ ca : ca_cert_pem,
341
+ cert : signed_client_cert,
342
+ key : client_key,
343
+ cert_x : signed_client_cert_x,
344
+ key_x : client_key_x,
345
+ hostname_verification,
346
+ } ) ,
316
347
_dir : Some ( dir) ,
317
348
_docker : docker,
318
349
container,
@@ -346,22 +377,23 @@ serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory
346
377
let Some ( tls) = self . tls . as_ref ( ) else {
347
378
return connector;
348
379
} ;
349
- let mut tls_options = zk:: TlsOptions :: default ( )
350
- . with_pem_ca_certs ( & tls. ca )
351
- . unwrap ( )
352
- . with_pem_identity ( & tls. cert , & tls. key )
353
- . unwrap ( ) ;
354
- if !tls. hostname_verification {
355
- tls_options = unsafe { tls_options. with_no_hostname_verification ( ) } ;
356
- }
357
- connector. tls ( tls_options) ;
380
+ connector. tls ( tls. options ( ) ) ;
358
381
connector
359
382
}
360
383
361
384
pub async fn client ( & self , chroot : Option < & str > ) -> zk:: Client {
362
385
self . custom_client ( chroot, |connector| connector) . await . unwrap ( )
363
386
}
364
387
388
+ pub async fn client_x ( & self , chroot : Option < & str > ) -> zk:: Client {
389
+ self . custom_client ( chroot, |connector| match self . tls . as_ref ( ) . map ( Tls :: options_x) {
390
+ None => connector,
391
+ Some ( options) => connector. tls ( options) ,
392
+ } )
393
+ . await
394
+ . unwrap ( )
395
+ }
396
+
365
397
pub async fn custom_client (
366
398
& self ,
367
399
chroot : Option < & str > ,
@@ -1616,9 +1648,9 @@ fn generate_server_cert(hostname_verification: bool) -> Certificate {
1616
1648
Certificate :: from_params ( params) . unwrap ( )
1617
1649
}
1618
1650
1619
- fn generate_client_cert ( ) -> Certificate {
1651
+ fn generate_client_cert ( cn : & str ) -> Certificate {
1620
1652
let mut params = CertificateParams :: default ( ) ;
1621
- params. distinguished_name . push ( rcgen:: DnType :: CommonName , "client" ) ;
1653
+ params. distinguished_name . push ( rcgen:: DnType :: CommonName , cn ) ;
1622
1654
Certificate :: from_params ( params) . unwrap ( )
1623
1655
}
1624
1656
@@ -1628,6 +1660,13 @@ async fn test_tls() {
1628
1660
let client = server. client ( None ) . await ;
1629
1661
let children = client. list_children ( "/" ) . await . unwrap ( ) ;
1630
1662
assert_that ! ( children) . contains ( "zookeeper" . to_owned ( ) ) ;
1663
+
1664
+ client. create ( "/a" , b"my_data" , & zk:: CreateMode :: Persistent . with_acls ( zk:: Acls :: creator_all ( ) ) ) . await . unwrap ( ) ;
1665
+
1666
+ let client1 = server. client ( None ) . await ;
1667
+ let client2 = server. client_x ( None ) . await ;
1668
+ assert_eq ! ( client1. get_data( "/a" ) . await . unwrap( ) . 0 , b"my_data" . to_vec( ) ) ;
1669
+ assert_eq ! ( client2. get_data( "/a" ) . await . unwrap_err( ) , zk:: Error :: NoAuth ) ;
1631
1670
}
1632
1671
1633
1672
#[ allow( dead_code) ]
0 commit comments