Commit 8ee1009874d11a61ccd4b89322432c3633b4cc1f

Edward Thomson 2018-11-06T13:10:30

transport: see if cert/cred callbacks exist before calling them Custom transports may want to ask libgit2 to invoke a configured credential or certificate callback; however they likely do not know if a callback was actually configured. Return a sentinal value (GIT_PASSTHROUGH) if there is no callback configured instead of crashing.

diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h
index a395de5..aac6f9f 100644
--- a/include/git2/sys/transport.h
+++ b/include/git2/sys/transport.h
@@ -226,7 +226,10 @@ GIT_EXTERN(int) git_transport_smart(
  * @param cert the certificate to pass to the caller
  * @param valid whether we believe the certificate is valid
  * @param hostname the hostname we connected to
- * @return the return value of the callback
+ * @return the return value of the callback: 0 for no error, GIT_PASSTHROUGH
+ *         to indicate that there is no callback registered (or the callback
+ *         refused to validate the certificate and callers should behave as
+ *         if no callback was set), or < 0 for an error
  */
 GIT_EXTERN(int) git_transport_smart_certificate_check(git_transport *transport, git_cert *cert, int valid, const char *hostname);
 
@@ -237,7 +240,10 @@ GIT_EXTERN(int) git_transport_smart_certificate_check(git_transport *transport, 
  * @param transport a smart transport
  * @param user the user we saw on the url (if any)
  * @param methods available methods for authentication
- * @return the return value of the callback
+ * @return the return value of the callback: 0 for no error, GIT_PASSTHROUGH
+ *         to indicate that there is no callback registered (or the callback
+ *         refused to provide credentials and callers should behave as if no
+ *         callback was set), or < 0 for an error
  */
 GIT_EXTERN(int) git_transport_smart_credentials(git_cred **out, git_transport *transport, const char *user, int methods);
 
diff --git a/src/transports/smart.c b/src/transports/smart.c
index e972d30..9fcbdcf 100644
--- a/src/transports/smart.c
+++ b/src/transports/smart.c
@@ -481,6 +481,11 @@ int git_transport_smart_certificate_check(git_transport *transport, git_cert *ce
 {
 	transport_smart *t = (transport_smart *)transport;
 
+	assert(transport && cert && hostname);
+
+	if (!t->certificate_check_cb)
+		return GIT_PASSTHROUGH;
+
 	return t->certificate_check_cb(cert, valid, hostname, t->message_cb_payload);
 }
 
@@ -488,6 +493,11 @@ int git_transport_smart_credentials(git_cred **out, git_transport *transport, co
 {
 	transport_smart *t = (transport_smart *)transport;
 
+	assert(out && transport);
+
+	if (!t->cred_acquire_cb)
+		return GIT_PASSTHROUGH;
+
 	return t->cred_acquire_cb(out, t->url, user, methods, t->cred_acquire_payload);
 }