git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] http.c: prompt for SSL client certificate password

From
Mark Lodato <lodatom@gmail.com>
Date
May 28, 2009, 03:16 UTC
Message-ID
<1243480563-5954-1-git-send-email-lodatom@gmail.com>

If an SSL client certificate is enabled (via http.sslcert or GIT_SSL_CERT), prompt for the certificate password rather than defaulting to OpenSSL's password prompt. This causes the prompt to only appear once each run. Previously, OpenSSL prompted the user *many* times, causing git to be unusable over HTTPS with client-side certificates.

Note that the password is stored in memory in the clear while the program is running. This may be a security problem if git crashes and core dumps.

The user is always prompted, even if the certificate is not encrypted. This should be fine; unencrypted certificates are rare and a security risk anyway.

Signed-off-by: Mark Lodato <lodatom@gmail.com>
---

See http://osdir.com/ml/git/2009-02/msg03402.html for a discussion of this topic and an example showing how horrible the current password prompts are.

The next patch adds an option to disable this feature. I split it into two commits in case the configuration option is not wanted.

I did not create any tests because the existing http.sslcert option has no tests to begin with.

I would really like to use git over HTTPS with client certs, but the current situation is just unusable. So, I'm hoping this gets included in git.git at some point. I would be happy to hear any comments people have about this patch series. Thanks!

 http.c |   40 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 39 insertions(+), 1 deletions(-)
diff --git a/http.c b/http.c
index 2e3d649..1fc3444 100644
--- a/http.c
+++ b/http.c
@@ -26,6 +26,8 @@ static long curl_low_speed_time = -1;
 static int curl_ftp_no_epsv;
 static const char *curl_http_proxy;
 static char *user_name, *user_pass;
+static char *ssl_cert_password;
+static int ssl_cert_password_required;
 
 static struct curl_slist *pragma_header;
 
@@ -167,6 +169,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();
@@ -189,6 +207,16 @@ 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,
+#if LIBCURL_VERSION_NUM >= 0x071700
+				 CURLOPT_KEYPASSWD,
+#elif LIBCURL_VERSION_NUM >= 0x070903
+				 CURLOPT_SSLKEYPASSWD,
+#else
+				 CURLOPT_SSLCERTPASSWD,
+#endif
+				 ssl_cert_password);
 #if LIBCURL_VERSION_NUM >= 0x070902
 	if (ssl_key != NULL)
 		curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
@@ -329,8 +357,11 @@ 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 (!prefixcmp(remote->url[0], "https://"))
+			ssl_cert_password_required = 1;
+	}
 
 #ifndef NO_CURL_EASY_DUPHANDLE
 	curl_default = get_curl_handle();
@@ -370,6 +401,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)
-- 
1.6.3.1
Next: Mark Lodato
Message 1 of 25 in “http.c: prompt for SSL client certificate password”
  1. 1/2 http.c: prompt for SSL client certificate passwordMark Lodato, May 28, 2009
  2. 2/2 http.c: add http.sslCertNoPass optionMark Lodato, May 28, 2009
  3. Mark LodatoJun 5, 2009
  4. Constantine PlotnikovJun 5, 2009
  5. Mark LodatoJun 7, 2009
  6. Mark LodatoJun 11, 2009
  7. Nanako ShiraishiJun 11, 2009
  8. Junio C HamanoJun 11, 2009
  9. Daniel StenbergJun 12, 2009
  10. Constantine PlotnikovJun 12, 2009
  11. Jakub NarebskiJun 12, 2009
  12. Rogan DawesJun 12, 2009
  13. Mark LodatoJun 12, 2009
  14. Mark LodatoJun 12, 2009
  15. Junio C HamanoJun 13, 2009
  16. Mark LodatoJun 13, 2009
  17. Daniel StenbergJun 13, 2009
  18. Junio C HamanoJun 11, 2009
  19. Mark LodatoJun 12, 2009
  20. Junio C HamanoJun 12, 2009
  21. Daniel StenbergJun 12, 2009
  22. Mark LodatoJun 12, 2009
  23. Junio C HamanoJun 13, 2009
  24. Mark LodatoJun 13, 2009
  25. Junio C HamanoJun 13, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.