@@ -51,7 +51,18 @@ pub type UpdateTips<'a> = dyn FnMut(&str, Oid, Oid) -> bool + 'a;
5151///
5252/// The second argument is the hostname for the connection is passed as the last
5353/// 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+ }
5566
5667/// Callback for each updated reference on push.
5768///
@@ -162,7 +173,7 @@ impl<'a> RemoteCallbacks<'a> {
162173 /// connection to proceed.
163174 pub fn certificate_check < F > ( & mut self , cb : F ) -> & mut RemoteCallbacks < ' a >
164175 where
165- F : FnMut ( & Cert < ' _ > , & str ) -> bool + ' a ,
176+ F : FnMut ( & Cert < ' _ > , & str ) -> Result < CertificateCheckStatus , Error > + ' a ,
166177 {
167178 self . certificate_check = Some ( Box :: new ( cb) as Box < CertificateCheck < ' a > > ) ;
168179 self
@@ -371,16 +382,26 @@ extern "C" fn certificate_check_cb(
371382 let payload = & mut * ( data as * mut RemoteCallbacks < ' _ > ) ;
372383 let callback = match payload. certificate_check {
373384 Some ( ref mut c) => c,
374- None => return true ,
385+ None => return Ok ( CertificateCheckStatus :: CertificatePassthrough ) ,
375386 } ;
376387 let cert = Binding :: from_raw ( cert) ;
377388 let hostname = str:: from_utf8 ( CStr :: from_ptr ( hostname) . to_bytes ( ) ) . unwrap ( ) ;
378389 callback ( & cert, hostname)
379390 } ) ;
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+ }
384405 }
385406}
386407
0 commit comments