summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: cb9d398)
raw | patch | inline | side by side (parent: cb9d398)
author | Mark Lodato <lodatom@gmail.com> | |
Thu, 28 May 2009 03:16:02 +0000 (23:16 -0400) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Thu, 18 Jun 2009 17:45:05 +0000 (10:45 -0700) |
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
http.c | patch | blob | history |
index 2e3d6493ef40e1b34fea8d166d760f0b1fcccafc..1c138135d74ecef0ae6887a1951ce275c89502ca 100644 (file)
--- a/http.c
+++ b/http.c
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 active_request_slot *active_queue_head;
}
}
+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();
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 >= 0x070902
if (ssl_key != NULL)
curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
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();
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)