http authentication via prompts
Curl is designed not to ask for password when only username is given in the URL, but has a way for application to feed a (username, password) pair to it. With this patch, you do not have to keep your password in plaintext in your $HOME/.netrc file when talking with a password protected URL with http://<username>@<host>/path/to/repository.git/ syntax. The code handles only the http-walker side, not the push side. At least, not yet. But interested parties can add support for it. Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
7059cd99fc
commit
c33976cbc6
60
http.c
60
http.c
|
@ -25,6 +25,7 @@ static long curl_low_speed_limit = -1;
|
||||||
static long curl_low_speed_time = -1;
|
static long curl_low_speed_time = -1;
|
||||||
static int curl_ftp_no_epsv;
|
static int curl_ftp_no_epsv;
|
||||||
static const char *curl_http_proxy;
|
static const char *curl_http_proxy;
|
||||||
|
static char *user_name, *user_pass;
|
||||||
|
|
||||||
static struct curl_slist *pragma_header;
|
static struct curl_slist *pragma_header;
|
||||||
|
|
||||||
|
@ -135,6 +136,20 @@ static int http_options(const char *var, const char *value, void *cb)
|
||||||
return git_default_config(var, value, cb);
|
return git_default_config(var, value, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_curl_http_auth(CURL *result)
|
||||||
|
{
|
||||||
|
if (!user_name)
|
||||||
|
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
||||||
|
else {
|
||||||
|
struct strbuf up = STRBUF_INIT;
|
||||||
|
if (!user_pass)
|
||||||
|
user_pass = xstrdup(getpass("Password: "));
|
||||||
|
strbuf_addf(&up, "%s:%s", user_name, user_pass);
|
||||||
|
curl_easy_setopt(result, CURLOPT_USERPWD,
|
||||||
|
strbuf_detach(&up, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static CURL *get_curl_handle(void)
|
static CURL *get_curl_handle(void)
|
||||||
{
|
{
|
||||||
CURL *result = curl_easy_init();
|
CURL *result = curl_easy_init();
|
||||||
|
@ -153,6 +168,8 @@ static CURL *get_curl_handle(void)
|
||||||
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
init_curl_http_auth(result);
|
||||||
|
|
||||||
if (ssl_cert != NULL)
|
if (ssl_cert != NULL)
|
||||||
curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
|
curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
|
||||||
#if LIBCURL_VERSION_NUM >= 0x070902
|
#if LIBCURL_VERSION_NUM >= 0x070902
|
||||||
|
@ -190,6 +207,46 @@ static CURL *get_curl_handle(void)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void http_auth_init(const char *url)
|
||||||
|
{
|
||||||
|
char *at, *colon, *cp, *slash;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
cp = strstr(url, "://");
|
||||||
|
if (!cp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ok, the URL looks like "proto://something". Which one?
|
||||||
|
* "proto://<user>:<pass>@<host>/...",
|
||||||
|
* "proto://<user>@<host>/...", or just
|
||||||
|
* "proto://<host>/..."?
|
||||||
|
*/
|
||||||
|
cp += 3;
|
||||||
|
at = strchr(cp, '@');
|
||||||
|
colon = strchr(cp, ':');
|
||||||
|
slash = strchrnul(cp, '/');
|
||||||
|
if (!at || slash <= at)
|
||||||
|
return; /* No credentials */
|
||||||
|
if (!colon || at <= colon) {
|
||||||
|
/* Only username */
|
||||||
|
len = at - cp;
|
||||||
|
user_name = xmalloc(len + 1);
|
||||||
|
memcpy(user_name, cp, len);
|
||||||
|
user_name[len] = '\0';
|
||||||
|
user_pass = NULL;
|
||||||
|
} else {
|
||||||
|
len = colon - cp;
|
||||||
|
user_name = xmalloc(len + 1);
|
||||||
|
memcpy(user_name, cp, len);
|
||||||
|
user_name[len] = '\0';
|
||||||
|
len = at - (colon + 1);
|
||||||
|
user_pass = xmalloc(len + 1);
|
||||||
|
memcpy(user_pass, colon + 1, len);
|
||||||
|
user_pass[len] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void set_from_env(const char **var, const char *envname)
|
static void set_from_env(const char **var, const char *envname)
|
||||||
{
|
{
|
||||||
const char *val = getenv(envname);
|
const char *val = getenv(envname);
|
||||||
|
@ -255,6 +312,9 @@ void http_init(struct remote *remote)
|
||||||
if (getenv("GIT_CURL_FTP_NO_EPSV"))
|
if (getenv("GIT_CURL_FTP_NO_EPSV"))
|
||||||
curl_ftp_no_epsv = 1;
|
curl_ftp_no_epsv = 1;
|
||||||
|
|
||||||
|
if (remote && remote->url && remote->url[0])
|
||||||
|
http_auth_init(remote->url[0]);
|
||||||
|
|
||||||
#ifndef NO_CURL_EASY_DUPHANDLE
|
#ifndef NO_CURL_EASY_DUPHANDLE
|
||||||
curl_default = get_curl_handle();
|
curl_default = get_curl_handle();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue