From e6b0ae7a13e20c4361327e50048a5143c8e9941b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 30 Jun 2014 09:19:05 +0200 Subject: [PATCH 1/3] ssl: init only once without threads The OpenSSL library-loading functions do not expect to be called multiple times. Add a flag in the non-threaded libgit2 init so we only call once. This fixes #2446. --- src/global.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/global.c b/src/global.c index 03a4bcedf..c72bfe890 100644 --- a/src/global.c +++ b/src/global.c @@ -291,7 +291,13 @@ static git_global_st __state; int git_threads_init(void) { - init_ssl(); + static int ssl_inited = 0; + + if (!ssl_inited) { + init_ssl(); + ssl_inited = 1; + } + git_atomic_inc(&git__n_inits); return 0; } From eac63e6754f8ef3b8e8d4962a8642786ee1e1a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 30 Jun 2014 10:03:36 +0200 Subject: [PATCH 2/3] ssh: create the right callback signature based on build options When linking against libssh2, create the transport.h such that it contains its definition for custom crypto and keyboard-interactive callbacks. If we don't link against libssh2, create an equivalent signature which has void pointers instead of pointers to libssh2 structures. This would be one way to fix #2438. --- CMakeLists.txt | 11 +++++++++++ include/git2/{transport.h => transport.h.in} | 19 +++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) rename include/git2/{transport.h => transport.h.in} (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f1a97edb..45881d6aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -408,6 +408,17 @@ IF (SONAME) ENDIF() CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libgit2.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc @ONLY) +IF (LIBSSH2_FOUND) + SET(INCLUDE_LIBSSH2 "#include ") + SET(GIT_SSH_PK_FUNC "typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback));") + SET(GIT_SSH_KI_FUNC "typedef LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*git_cred_ssh_interactive_callback));") +ELSE () + SET(GIT_SSH_PK_FUNC "typedef int (*git_cred_sign_callback)(void *, unsigned char **, size_t *, const unsigned char *, size_t, void **);") + SET(GIT_SSH_KI_FUNC "typedef int (*git_cred_ssh_interactive_callback)(const char *, int, const char *, int, int, const void *, void *, void **);") +ENDIF () +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/include/git2/transport.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/git2/transport.h @ONLY) + + IF (MSVC_IDE) # Precompiled headers SET_TARGET_PROPERTIES(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") diff --git a/include/git2/transport.h b/include/git2/transport.h.in similarity index 97% rename from include/git2/transport.h rename to include/git2/transport.h.in index af7812b5d..73f0a99a1 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h.in @@ -11,9 +11,7 @@ #include "net.h" #include "types.h" -#ifdef GIT_SSH -#include -#endif +@INCLUDE_LIBSSH2@ /** * @file git2/transport.h @@ -61,13 +59,14 @@ typedef struct { char *password; } git_cred_userpass_plaintext; -#ifdef GIT_SSH -typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback)); -typedef LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*git_cred_ssh_interactive_callback)); -#else -typedef int (*git_cred_sign_callback)(void *, ...); -typedef int (*git_cred_ssh_interactive_callback)(void *, ...); -#endif +/* + * This defines the callbacks for custom public key signatures and + * keyboard-interactive authentication. It is replaced at build-time + * with either the libssh2 signature or a dummy signature that's close + * enough but with void pointers instead of libssh2 structures. + */ +@GIT_SSH_PK_FUNC@ +@GIT_SSH_KI_FUNC@ /** * A ssh key from disk From 00b8c216c2349d1f5901e9412d95f83c7d043e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 30 Jun 2014 23:18:37 +0200 Subject: [PATCH 3/3] ssh: always declare the libssh2 types This lets a user decide they do want to use keyboard-interactive after they've compiled. --- CMakeLists.txt | 11 ----------- include/git2/{transport.h.in => transport.h} | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 19 deletions(-) rename include/git2/{transport.h.in => transport.h} (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45881d6aa..6f1a97edb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -408,17 +408,6 @@ IF (SONAME) ENDIF() CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libgit2.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc @ONLY) -IF (LIBSSH2_FOUND) - SET(INCLUDE_LIBSSH2 "#include ") - SET(GIT_SSH_PK_FUNC "typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback));") - SET(GIT_SSH_KI_FUNC "typedef LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*git_cred_ssh_interactive_callback));") -ELSE () - SET(GIT_SSH_PK_FUNC "typedef int (*git_cred_sign_callback)(void *, unsigned char **, size_t *, const unsigned char *, size_t, void **);") - SET(GIT_SSH_KI_FUNC "typedef int (*git_cred_ssh_interactive_callback)(const char *, int, const char *, int, int, const void *, void *, void **);") -ENDIF () -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/include/git2/transport.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/git2/transport.h @ONLY) - - IF (MSVC_IDE) # Precompiled headers SET_TARGET_PROPERTIES(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") diff --git a/include/git2/transport.h.in b/include/git2/transport.h similarity index 95% rename from include/git2/transport.h.in rename to include/git2/transport.h index 73f0a99a1..944072632 100644 --- a/include/git2/transport.h.in +++ b/include/git2/transport.h @@ -11,8 +11,6 @@ #include "net.h" #include "types.h" -@INCLUDE_LIBSSH2@ - /** * @file git2/transport.h * @brief Git transport interfaces and functions @@ -59,14 +57,19 @@ typedef struct { char *password; } git_cred_userpass_plaintext; + /* - * This defines the callbacks for custom public key signatures and - * keyboard-interactive authentication. It is replaced at build-time - * with either the libssh2 signature or a dummy signature that's close - * enough but with void pointers instead of libssh2 structures. + * If the user hasn't included libssh2.h before git2.h, we need to + * define a few types for the callback signatures. */ -@GIT_SSH_PK_FUNC@ -@GIT_SSH_KI_FUNC@ +#ifndef LIBSSH2_VERSION +typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; +typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT; +typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE; +#endif + +typedef int (*git_cred_sign_callback)(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract); +typedef int (*git_cred_ssh_interactive_callback)(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract); /** * A ssh key from disk