@@ -33,6 +33,17 @@ static int curl_ftp_no_epsv;
3333static const char * curl_http_proxy ;
3434static char * user_name , * user_pass ;
3535
36+ #if LIBCURL_VERSION_NUM >= 0x071700
37+ /* Use CURLOPT_KEYPASSWD as is */
38+ #elif LIBCURL_VERSION_NUM >= 0x070903
39+ #define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
40+ #else
41+ #define CURLOPT_KEYPASSWD CURLOPT_SSLCERTPASSWD
42+ #endif
43+
44+ static char * ssl_cert_password ;
45+ static int ssl_cert_password_required ;
46+
3647static struct curl_slist * pragma_header ;
3748static struct curl_slist * no_pragma_header ;
3849
@@ -136,6 +147,11 @@ static int http_options(const char *var, const char *value, void *cb)
136147#endif
137148 if (!strcmp ("http.sslcainfo" , var ))
138149 return git_config_string (& ssl_cainfo , var , value );
150+ if (!strcmp ("http.sslcertpasswordprotected" , var )) {
151+ if (git_config_bool (var , value ))
152+ ssl_cert_password_required = 1 ;
153+ return 0 ;
154+ }
139155#ifdef USE_CURL_MULTI
140156 if (!strcmp ("http.maxrequests" , var )) {
141157 max_requests = git_config_int (var , value );
@@ -174,6 +190,22 @@ static void init_curl_http_auth(CURL *result)
174190 }
175191}
176192
193+ static int has_cert_password (void )
194+ {
195+ if (ssl_cert_password != NULL )
196+ return 1 ;
197+ if (ssl_cert == NULL || ssl_cert_password_required != 1 )
198+ return 0 ;
199+ /* Only prompt the user once. */
200+ ssl_cert_password_required = -1 ;
201+ ssl_cert_password = getpass ("Certificate Password: " );
202+ if (ssl_cert_password != NULL ) {
203+ ssl_cert_password = xstrdup (ssl_cert_password );
204+ return 1 ;
205+ } else
206+ return 0 ;
207+ }
208+
177209static CURL * get_curl_handle (void )
178210{
179211 CURL * result = curl_easy_init ();
@@ -196,6 +228,8 @@ static CURL *get_curl_handle(void)
196228
197229 if (ssl_cert != NULL )
198230 curl_easy_setopt (result , CURLOPT_SSLCERT , ssl_cert );
231+ if (has_cert_password ())
232+ curl_easy_setopt (result , CURLOPT_KEYPASSWD , ssl_cert_password );
199233#if LIBCURL_VERSION_NUM >= 0x070903
200234 if (ssl_key != NULL )
201235 curl_easy_setopt (result , CURLOPT_SSLKEY , ssl_key );
@@ -339,8 +373,13 @@ void http_init(struct remote *remote)
339373 if (getenv ("GIT_CURL_FTP_NO_EPSV" ))
340374 curl_ftp_no_epsv = 1 ;
341375
342- if (remote && remote -> url && remote -> url [0 ])
376+ if (remote && remote -> url && remote -> url [0 ]) {
343377 http_auth_init (remote -> url [0 ]);
378+ if (!ssl_cert_password_required &&
379+ getenv ("GIT_SSL_CERT_PASSWORD_PROTECTED" ) &&
380+ !prefixcmp (remote -> url [0 ], "https://" ))
381+ ssl_cert_password_required = 1 ;
382+ }
344383
345384#ifndef NO_CURL_EASY_DUPHANDLE
346385 curl_default = get_curl_handle ();
@@ -383,6 +422,13 @@ void http_cleanup(void)
383422 free ((void * )curl_http_proxy );
384423 curl_http_proxy = NULL ;
385424 }
425+
426+ if (ssl_cert_password != NULL ) {
427+ memset (ssl_cert_password , 0 , strlen (ssl_cert_password ));
428+ free (ssl_cert_password );
429+ ssl_cert_password = NULL ;
430+ }
431+ ssl_cert_password_required = 0 ;
386432}
387433
388434struct active_request_slot * get_active_slot (void )
0 commit comments