git-svn: ignore leading blank lines in svn:ignore
[gitweb.git] / http.c
diff --git a/http.c b/http.c
index b0499482455e256a3c2c9b6498b21c32d328c5c9..a2720d576d72e456b038444050f5b8de9d25d792 100644 (file)
--- a/http.c
+++ b/http.c
@@ -33,6 +33,17 @@ static int curl_ftp_no_epsv;
 static const char *curl_http_proxy;
 static char *user_name, *user_pass;
 
+#if LIBCURL_VERSION_NUM >= 0x071700
+/* Use CURLOPT_KEYPASSWD as is */
+#elif LIBCURL_VERSION_NUM >= 0x070903
+#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
+#else
+#define CURLOPT_KEYPASSWD CURLOPT_SSLCERTPASSWD
+#endif
+
+static char *ssl_cert_password;
+static int ssl_cert_password_required;
+
 static struct curl_slist *pragma_header;
 static struct curl_slist *no_pragma_header;
 
@@ -136,6 +147,11 @@ static int http_options(const char *var, const char *value, void *cb)
 #endif
        if (!strcmp("http.sslcainfo", var))
                return git_config_string(&ssl_cainfo, var, value);
+       if (!strcmp("http.sslcertpasswordprotected", var)) {
+               if (git_config_bool(var, value))
+                       ssl_cert_password_required = 1;
+               return 0;
+       }
 #ifdef USE_CURL_MULTI
        if (!strcmp("http.maxrequests", var)) {
                max_requests = git_config_int(var, value);
@@ -174,6 +190,22 @@ static void init_curl_http_auth(CURL *result)
        }
 }
 
+static int has_cert_password(void)
+{
+       if (ssl_cert_password != NULL)
+               return 1;
+       if (ssl_cert == NULL || ssl_cert_password_required != 1)
+               return 0;
+       /* Only prompt the user once. */
+       ssl_cert_password_required = -1;
+       ssl_cert_password = getpass("Certificate Password: ");
+       if (ssl_cert_password != NULL) {
+               ssl_cert_password = xstrdup(ssl_cert_password);
+               return 1;
+       } else
+               return 0;
+}
+
 static CURL *get_curl_handle(void)
 {
        CURL *result = curl_easy_init();
@@ -196,6 +228,8 @@ static CURL *get_curl_handle(void)
 
        if (ssl_cert != NULL)
                curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
+       if (has_cert_password())
+               curl_easy_setopt(result, CURLOPT_KEYPASSWD, ssl_cert_password);
 #if LIBCURL_VERSION_NUM >= 0x070903
        if (ssl_key != NULL)
                curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
@@ -339,8 +373,13 @@ void http_init(struct remote *remote)
        if (getenv("GIT_CURL_FTP_NO_EPSV"))
                curl_ftp_no_epsv = 1;
 
-       if (remote && remote->url && remote->url[0])
+       if (remote && remote->url && remote->url[0]) {
                http_auth_init(remote->url[0]);
+               if (!ssl_cert_password_required &&
+                   getenv("GIT_SSL_CERT_PASSWORD_PROTECTED") &&
+                   !prefixcmp(remote->url[0], "https://"))
+                       ssl_cert_password_required = 1;
+       }
 
 #ifndef NO_CURL_EASY_DUPHANDLE
        curl_default = get_curl_handle();
@@ -383,6 +422,13 @@ void http_cleanup(void)
                free((void *)curl_http_proxy);
                curl_http_proxy = NULL;
        }
+
+       if (ssl_cert_password != NULL) {
+               memset(ssl_cert_password, 0, strlen(ssl_cert_password));
+               free(ssl_cert_password);
+               ssl_cert_password = NULL;
+       }
+       ssl_cert_password_required = 0;
 }
 
 struct active_request_slot *get_active_slot(void)