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

[PATCH] http authentication via prompts

From
Mike Gaffney <mr.gaffo@gmail.com>
Date
Mar 5, 2009, 01:07 UTC
Message-ID
<49AF25BF.5060706@gmail.com>
Currently git over http only works with a .netrc file which required that you store your password on the file system in plaintext. This commit adds to configuration options for http for a username and an optional password. If a http.username is set, then the .netrc file is ignored and the username is used instead. If a http.password is set, then that is used as well, otherwise the user is prompted for their password.
With the old .netrc working, this patch provides backwards compatibility while adding a more secure option for users whose http password may be sensitive (such as if its a domain controller password) and do not wish to have it on the filesystem.
Signed-off-by: Mike Gaffney <mike@uberu.com>
---
 Documentation/config.txt                           |    7 +++
 Documentation/howto/setup-git-server-over-http.txt |   38 ++++++++++++++++--
 http.c                                             |   41 ++++++++++++++++++-
 http.h                                             |    2 +
 4 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index f5152c5..821bf48 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -920,6 +920,13 @@ help.autocorrect::
 	value is 0 - the command will be just shown but not executed.
 	This is the default.
 
+http.username, http.password:
+    The username and password for http authentication. http.username is
+    required, http.password is optional. If supplied, the .netrc file will
+    be ignored. If a password is not supplied, git will prompt for it.
+    Be careful when configuring a password as it will be stored in plain text
+    on the filesystem.
+
 http.proxy::
 	Override the HTTP proxy, normally configured using the 'http_proxy'
 	environment variable (see linkgit:curl[1]).  This can be overridden
diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt
index 622ee5c..462a9d4 100644
--- a/Documentation/howto/setup-git-server-over-http.txt
+++ b/Documentation/howto/setup-git-server-over-http.txt
@@ -189,8 +189,19 @@ Make sure that you have HTTP support, i.e. your git was built with
 libcurl (version more recent than 7.10). The command 'git http-push' with
 no argument should display a usage message.
 
-Then, add the following to your $HOME/.netrc (you can do without, but will be
-asked to input your password a _lot_ of times):
+There are 2 ways to authenticate with git http, netrc and via the git config.
+The netrc option requires that you put the username and password for the connection
+in $HOME/.netrc. The configuration method allows you to specify a username and
+optionally a password. If the password is not supplied then git will prompt you
+for the password. The downside to the netrc method is that you must have your
+username and password in plaintext on the filesystem, albeit in a protected file.
+If the username/password combo is a sensitive one, you may wish to use the
+git config method. The downside of the config method is that you will be prompted
+for your password every time you push or pull to the remote repository.
+
+Using netrc:
+
+Using your favourite ext editor, add the following to your $HOME/.netrc:
 
     machine <servername>
     login <username>
@@ -204,7 +215,7 @@ instead of the server name.
 
 To check whether all is OK, do:
 
-   curl --netrc --location -v http://<username>@<servername>/my-new-repo.git/HEAD
+   curl --netrc --location -v http://<servername>/my-new-repo.git/HEAD
 
 ...this should give something like 'ref: refs/heads/master', which is
 the content of the file HEAD on the server.
@@ -213,12 +224,31 @@ Now, add the remote in your existing repository which contains the project
 you want to export:
 
    $ git-config remote.upload.url \
-       http://<username>@<servername>/my-new-repo.git/
+       http://<servername>/my-new-repo.git/
 
 It is important to put the last '/'; Without it, the server will send
 a redirect which git-http-push does not (yet) understand, and git-http-push
 will repeat the request infinitely.
 
+Using git config:
+
+curl --user <username>:<password> --location -v http://<servername>/my-new-repo.git/HEAD
+
+...this should give something like 'ref: refs/heads/master', which is
+the content of the file HEAD on the server.
+
+Now, add the remote in your existing repository which contains the project
+you want to export:
+
+   $ git-config remote.upload.url \
+       http://<servername>/my-new-repo.git/
+
+Also, add in your username with:
+   $ git-config http.username <username>
+
+And optionally your password (you will be prompted for it if you do not):
+   $ git-config http.password <password>
+
 
 Step 4: make the initial push
 -----------------------------
diff --git a/http.c b/http.c
index ee58799..348b9fb 100644
--- a/http.c
+++ b/http.c
@@ -26,6 +26,9 @@ static long curl_low_speed_time = -1;
 static int curl_ftp_no_epsv = 0;
 static const char *curl_http_proxy = NULL;
 
+static const char *curl_http_username = NULL;
+static const char *curl_http_password = NULL;
+
 static struct curl_slist *pragma_header;
 
 static struct active_request_slot *active_queue_head = NULL;
@@ -153,11 +156,45 @@ static int http_options(const char *var, const char *value, void *cb)
 			return git_config_string(&curl_http_proxy, var, value);
 		return 0;
 	}
+	if (!strcmp("http.username", var)) {
+		if (curl_http_username == NULL)
+		{
+			return git_config_string(&curl_http_username, var, value);
+		}
+		return 0;
+	}
+	if (!strcmp("http.password", var)) {
+		if (curl_http_password == NULL)
+		{
+			return git_config_string(&curl_http_password, var, value);
+		}
+		return 0;
+	}
 
 	/* Fall back on the default ones */
 	return git_default_config(var, value, cb);
 }
 
+static void init_curl_http_auth(CURL* result){
+#if LIBCURL_VERSION_NUM >= 0x070907
+        struct strbuf userpass;
+        strbuf_init(&userpass, 0);
+        if (curl_http_username != NULL) {
+                strbuf_addstr(&userpass, curl_http_username);
+		strbuf_addstr(&userpass, ":");
+		if (curl_http_password != NULL) {
+			strbuf_addstr(&userpass, curl_http_password);
+		} else {
+			strbuf_addstr(&userpass, getpass("Password: "));
+		}
+		curl_easy_setopt(result, CURLOPT_USERPWD, userpass.buf);
+		curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_IGNORED);
+        } else {
+		curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
+        }
+#endif
+}
+
 static CURL* get_curl_handle(void)
 {
 	CURL* result = curl_easy_init();
@@ -172,9 +209,7 @@ static CURL* get_curl_handle(void)
 		curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
 	}
 
-#if LIBCURL_VERSION_NUM >= 0x070907
-	curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
-#endif
+        init_curl_http_auth(result);
 
 	if (ssl_cert != NULL)
 		curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
diff --git a/http.h b/http.h
index 905b462..71320d1 100644
--- a/http.h
+++ b/http.h
@@ -5,6 +5,8 @@
 
 #include <curl/curl.h>
 #include <curl/easy.h>
+#include <termios.h>
+#include <stdio.h>
 
 #include "strbuf.h"
 #include "remote.h"
-- 
1.6.1.2
Next: Junio C Hamano
Message 1 of 6 in “http authentication via prompts”
  1. http authentication via promptsMike Gaffney, Mar 5, 2009
  2. Junio C HamanoMar 5, 2009
  3. Johannes SchindelinMar 5, 2009
  4. Mike GaffneyMar 5, 2009
  5. Jeff KingMar 5, 2009
  6. Fredrik SkolmliMar 6, 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.