@@ -51,7 +51,18 @@ pub type UpdateTips<'a> = dyn FnMut(&str, Oid, Oid) -> bool + 'a;
51
51
///
52
52
/// The second argument is the hostname for the connection is passed as the last
53
53
/// argument.
54
- pub type CertificateCheck < ' a > = dyn FnMut ( & Cert < ' _ > , & str ) -> bool + ' a ;
54
+ pub type CertificateCheck < ' a > =
55
+ dyn FnMut ( & Cert < ' _ > , & str ) -> Result < CertificateCheckStatus , Error > + ' a ;
56
+
57
+ /// The return value for the [`CertificateCheck`] callback.
58
+ pub enum CertificateCheckStatus {
59
+ /// Indicates that the certificate should be accepted.
60
+ CertificateOk ,
61
+ /// Indicates that the certificate callback is neither accepting nor
62
+ /// rejecting the certificate. The result of the certificate checks
63
+ /// built-in to libgit2 will be used instead.
64
+ CertificatePassthrough ,
65
+ }
55
66
56
67
/// Callback for each updated reference on push.
57
68
///
@@ -162,7 +173,7 @@ impl<'a> RemoteCallbacks<'a> {
162
173
/// connection to proceed.
163
174
pub fn certificate_check < F > ( & mut self , cb : F ) -> & mut RemoteCallbacks < ' a >
164
175
where
165
- F : FnMut ( & Cert < ' _ > , & str ) -> bool + ' a ,
176
+ F : FnMut ( & Cert < ' _ > , & str ) -> Result < CertificateCheckStatus , Error > + ' a ,
166
177
{
167
178
self . certificate_check = Some ( Box :: new ( cb) as Box < CertificateCheck < ' a > > ) ;
168
179
self
@@ -371,16 +382,26 @@ extern "C" fn certificate_check_cb(
371
382
let payload = & mut * ( data as * mut RemoteCallbacks < ' _ > ) ;
372
383
let callback = match payload. certificate_check {
373
384
Some ( ref mut c) => c,
374
- None => return true ,
385
+ None => return Ok ( CertificateCheckStatus :: CertificatePassthrough ) ,
375
386
} ;
376
387
let cert = Binding :: from_raw ( cert) ;
377
388
let hostname = str:: from_utf8 ( CStr :: from_ptr ( hostname) . to_bytes ( ) ) . unwrap ( ) ;
378
389
callback ( & cert, hostname)
379
390
} ) ;
380
- if ok == Some ( true ) {
381
- 0
382
- } else {
383
- -1
391
+ match ok {
392
+ Some ( Ok ( CertificateCheckStatus :: CertificateOk ) ) => 0 ,
393
+ Some ( Ok ( CertificateCheckStatus :: CertificatePassthrough ) ) => raw:: GIT_PASSTHROUGH as c_int ,
394
+ Some ( Err ( e) ) => {
395
+ let s = CString :: new ( e. message ( ) ) . unwrap ( ) ;
396
+ unsafe {
397
+ raw:: git_error_set_str ( e. class ( ) as c_int , s. as_ptr ( ) ) ;
398
+ }
399
+ e. raw_code ( ) as c_int
400
+ }
401
+ None => {
402
+ // Panic. The *should* get resumed by some future call to check().
403
+ -1
404
+ }
384
405
}
385
406
}
386
407
0 commit comments