{"thread":{"id":"38197","subject":"git-http-backend auth via Kerberos","startedAt":"2014-12-18T22:19:19Z","lastAt":"2015-03-12T13:09:40Z","messageCount":39,"participants":["Dan Langille (dalangil)","brian m. carlson","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"253818","messageId":"540A8740-B240-40FF-BB50-0D90DEA04031@cisco.com","threadId":"38197","inReplyTo":null,"subject":"git-http-backend auth via Kerberos","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2014-12-18T22:19:19Z","receivedAt":"2014-12-18T22:19:19Z","isPatch":false,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"I am trying to get http://git-scm.com/docs/git-http-backend to auth via Kerberos.\n\nI have success when a Kerberos ticket is present.\n\nI am trying to get git to authenticate with Kerberos when a ticket is not present.\n\nHere is what succeeds with a ticket:\n\n<Location /git>\n  SSLOptions +StdenvVars\n  Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch\n\n    # By default, allow access to anyone.\n    Order allow,deny\n    Allow from All\n\n    # Enable Kerberos authentication using mod_auth_kerb.\n    AuthType Kerberos\n    AuthName “us.example.com\"\n    KrbAuthRealm us.example.com\n    Krb5KeyTab /usr/local/etc/apache22/repo-test.keytab\n    KrbMethodNegotiate on\n    KrbSaveCredentials on\n    KrbVerifyKDC on\n    KrbServiceName Any\n    Require valid-user\n</Location>\n\nThis is what happens without a valid ticket:\n\n$ git clone https://us.example.com/git/clamav-bytecode-compiler\nCloning into 'clamav-bytecode-compiler'...\nUsername for 'https://us.example.com': dan\nPassword for 'https://dan@us.example.com': \nfatal: Authentication failed for 'https://us.example.com/git/clamav-bytecode-compiler/'\n\nOf note, I see this in the Apache logs:\n\nThu Dec 18 16:43:35 2014] [debug] src/mod_auth_kerb.c(1749): [client 10.7.69.10] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos\n\nIdeas?  Suggestions?  Hints?  Thanks.\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n"},{"id":"253819","messageId":"20141218225418.GA84625@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"540A8740-B240-40FF-BB50-0D90DEA04031@cisco.com","subject":"Re: git-http-backend auth via Kerberos","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-12-18T22:54:32Z","receivedAt":"2014-12-18T22:54:32Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Thu, Dec 18, 2014 at 10:19:19PM +0000, Dan Langille (dalangil) wrote:\n> This is what happens without a valid ticket:\n> \n> $ git clone https://us.example.com/git/clamav-bytecode-compiler\n> Cloning into 'clamav-bytecode-compiler'...\n> Username for 'https://us.example.com': dan\n> Password for 'https://dan@us.example.com': \n> fatal: Authentication failed for 'https://us.example.com/git/clamav-bytecode-compiler/'\n\nSo there are two ways to do this.  One is allowing users to clone\nwithout any credentials, which I take it you are trying to avoid.  If\nthat *is* what you're going for, I can provide you with my Apache\nconfiguration, which does allow that.\n\nWhat I would recommend is going to\nhttps://us.example.com/git/clamav-bytecode-compiler/info/refs in a web\nbrowser without a ticket, and see if it prompts you for a username and\npassword.  When you get that working, it will probably also work for you\nwith git.\n\nYou can also run git with GIT_CURL_VERBOSE=1 and see the protocol\nexchange printed out, so you can see what's happening.  You'll obviously\nwant to see if the server offers Basic auth as well as Negotiate.\n\nYou might also try specifying KrbMethodK5Passwd on explicitly.  I don't\nhappen to use that option (I use Kerberos to avoid passwords altogether)\nso that might work for you.\n\nI don't know what version of git you're using, but some older versions\nwill still prompt for a password whenever authentication fails.\nTherefore, just because you're getting a password prompt doesn't mean\nthat providing a password will necessarily work.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"253839","messageId":"D562883B-47D7-4569-B1BB-84BFBDCBA93A@cisco.com","threadId":"38197","inReplyTo":"20141218225418.GA84625@vauxhall.crustytoothpaste.net","subject":"Re: git-http-backend auth via Kerberos","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2014-12-19T15:07:20Z","receivedAt":"2014-12-19T15:07:20Z","isPatch":false,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Dec 18, 2014, at 5:54 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> On Thu, Dec 18, 2014 at 10:19:19PM +0000, Dan Langille (dalangil) wrote:\n>> This is what happens without a valid ticket:\n>> \n>> $ git clone https://us.example.com/git/clamav-bytecode-compiler\n>> Cloning into 'clamav-bytecode-compiler'...\n>> Username for 'https://us.example.com': dan\n>> Password for 'https://dan@us.example.com': \n>> fatal: Authentication failed for 'https://us.example.com/git/clamav-bytecode-compiler/'\n> \n> So there are two ways to do this.  One is allowing users to clone\n> without any credentials, which I take it you are trying to avoid.  If\n> that *is* what you're going for, I can provide you with my Apache\n> configuration, which does allow that.\n\nCorrect, we are trying to avoid that.  In addition, there is only https, no http.\n\n> What I would recommend is going to\n> https://us.example.com/git/clamav-bytecode-compiler/info/refs in a web\n> browser without a ticket, and see if it prompts you for a username and\n> password.\n\nTo be clear, for the following tests, there is no Kerberos ticket.\n\nI tried that URL using three different browsers.  Each time I am prompted for\na username & password.  After entering valid credentials, I get:\n\nChrome: No data received. Unable to load the webpage because the server\nsent no data. Error code: ERR_EMPTY_RESPONSE\n\nWith Firefox: The connection was reset\n\nSafari: Safari Can’t Open The Page\n\nHowever, I did stumble across something which seems promising.\n\nAfter the above failures, if I then browse to /gitweb/\n(where I see expected results) and then go to the info/refs URL you supplied,\nI see data such as this:\n\n   fe068a8ae55cea4bb90e2cc714107f4c5389d516\trefs/heads/0.96.x\n   d384a963980e9b40e34dea80eac280cf2d4b7c73\trefs/heads/0.97.x\n\nConclusion: there is something in the /gitweb auth which is succeeding and then\nallowing /git to work\n\nFor the record, this is the gitweb auth:\n\n<Location /gitweb>\n  SSLOptions +StdenvVars\n  Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch\n\n  AuthType           Kerberos\n  AuthName           “us.example.com\"\n  KrbAuthRealms      us.example.com\n  KrbServiceName     HTTP/us.example.com\n  Krb5Keytab         /usr/local/etc/apache22/repo-test.keytab\n  KrbMethodNegotiate on\n  KrbMethodk5Passwd  on\n\n  require            valid-user\n</Location>\n\n\n>  When you get that working, it will probably also work for you\n> with git.\n\nNot yet...\n\n> \n> You can also run git with GIT_CURL_VERBOSE=1 and see the protocol\n> exchange printed out, so you can see what's happening.  \n\nThat attempt is shown here: http://dpaste.com/04RG37E.txt\n\n> You'll obviously\n> want to see if the server offers Basic auth as well as Negotiate.\n\nI’m not up on my knowledge here.  You mean the Kerberos server?\n\n\n> You might also try specifying KrbMethodK5Passwd on explicitly.  I don't\n> happen to use that option (I use Kerberos to avoid passwords altogether)\n> so that might work for you.\n> \n> I don't know what version of git you're using, but some older versions\n> will still prompt for a password whenever authentication fails.\n> Therefore, just because you're getting a password prompt doesn't mean\n> that providing a password will necessarily work.\n\nHow old is older?\n\n$ git --version\ngit version 1.9.3 (Apple Git-50)\n\nMight that be it?  Hmmm.\n\n"},{"id":"253844","messageId":"323AFE89-DD9C-4FA3-BED8-16F353A84386@cisco.com","threadId":"38197","inReplyTo":"D562883B-47D7-4569-B1BB-84BFBDCBA93A@cisco.com","subject":"Re: git-http-backend auth via Kerberos","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2014-12-19T15:50:18Z","receivedAt":"2014-12-19T15:50:18Z","isPatch":false,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Dec 19, 2014, at 10:07 AM, Dan Langille (dalangil) <dalangil@cisco.com> wrote:\n> \n>> You might also try specifying KrbMethodK5Passwd on explicitly.  I don't\n>> happen to use that option (I use Kerberos to avoid passwords altogether)\n>> so that might work for you.\n>> \n>> I don't know what version of git you're using, but some older versions\n>> will still prompt for a password whenever authentication fails.\n>> Therefore, just because you're getting a password prompt doesn't mean\n>> that providing a password will necessarily work.\n> \n> How old is older?\n> \n> $ git --version\n> git version 1.9.3 (Apple Git-50)\n> \n> Might that be it?  Hmmm.\n> \n\nFor the record, I tried git 2.2.1 and it gave identical results.\n"},{"id":"253845","messageId":"C50363BE-A217-47B1-8556-919DC933D83C@cisco.com","threadId":"38197","inReplyTo":"D562883B-47D7-4569-B1BB-84BFBDCBA93A@cisco.com","subject":"Re: git-http-backend auth via Kerberos","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2014-12-19T16:07:49Z","receivedAt":"2014-12-19T16:07:49Z","isPatch":false,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Dec 19, 2014, at 10:07 AM, Dan Langille (dalangil) <dalangil@cisco.com> wrote:\n> \n>> You might also try specifying KrbMethodK5Passwd on explicitly.  I don't\n>> happen to use that option (I use Kerberos to avoid passwords altogether)\n>> so that might work for you.\n>> \n>> I don't know what version of git you're using, but some older versions\n>> will still prompt for a password whenever authentication fails.\n>> Therefore, just because you're getting a password prompt doesn't mean\n>> that providing a password will necessarily work.\n> \n> How old is older?\n> \n> $ git --version\n> git version 1.9.3 (Apple Git-50)\n> \n> Might that be it?  Hmmm.\n> \n\nFor the record, I tried git 2.2.1 and it gave identical results.\n"},{"id":"253871","messageId":"20141219201633.GA88110@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"D562883B-47D7-4569-B1BB-84BFBDCBA93A@cisco.com","subject":"Re: git-http-backend auth via Kerberos","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-12-19T20:16:33Z","receivedAt":"2014-12-19T20:16:33Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Fri, Dec 19, 2014 at 03:07:20PM +0000, Dan Langille (dalangil) wrote:\n> Correct, we are trying to avoid that.  In addition, there is only https, no http.\n\nI don't think HTTPS versus HTTP matters.  I use Kerberos over HTTPS only\nand it works fine.\n\n> To be clear, for the following tests, there is no Kerberos ticket.\n> \n> I tried that URL using three different browsers.  Each time I am prompted for\n> a username & password.  After entering valid credentials, I get:\n> \n> Chrome: No data received. Unable to load the webpage because the server\n> sent no data. Error code: ERR_EMPTY_RESPONSE\n> \n> With Firefox: The connection was reset\n> \n> Safari: Safari Can’t Open The Page\n> \n> However, I did stumble across something which seems promising.\n> \n> After the above failures, if I then browse to /gitweb/\n> (where I see expected results) and then go to the info/refs URL you supplied,\n> I see data such as this:\n> \n>    fe068a8ae55cea4bb90e2cc714107f4c5389d516\trefs/heads/0.96.x\n>    d384a963980e9b40e34dea80eac280cf2d4b7c73\trefs/heads/0.97.x\n> \n> Conclusion: there is something in the /gitweb auth which is succeeding and then\n> allowing /git to work\n\nThat could possibly be due to KrbSaveCredentials.\n\n> For the record, this is the gitweb auth:\n> \n> <Location /gitweb>\n>   SSLOptions +StdenvVars\n>   Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch\n> \n>   AuthType           Kerberos\n>   AuthName           “us.example.com\"\n>   KrbAuthRealms      us.example.com\n>   KrbServiceName     HTTP/us.example.com\n>   Krb5Keytab         /usr/local/etc/apache22/repo-test.keytab\n>   KrbMethodNegotiate on\n>   KrbMethodk5Passwd  on\n\nDoes it work if you set this value (KrbMethodK5Passwd on) explicitly in\nthe other configuration?  That might be sufficient.\n\n> \n> That attempt is shown here: http://dpaste.com/04RG37E.txt\n> \n> > You'll obviously\n> > want to see if the server offers Basic auth as well as Negotiate.\n> \n> I’m not up on my knowledge here.  You mean the Kerberos server?\n\nNo, I meant the HTTP server, which it looks like from your attempt it\ndoes.  I'm not really sure what the issue is after looking at that,\nalthough it looks like Git isn't sending the username and password.\nI'll try to look at this a little more this weekend.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"253872","messageId":"FBFEB910-4CB8-4049-901C-AADBFAB3AE9E@cisco.com","threadId":"38197","inReplyTo":"20141219201633.GA88110@vauxhall.crustytoothpaste.net","subject":"Re: git-http-backend auth via Kerberos","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2014-12-19T20:57:51Z","receivedAt":"2014-12-19T20:57:51Z","isPatch":false,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"On Dec 19, 2014, at 3:16 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> On Fri, Dec 19, 2014 at 03:07:20PM +0000, Dan Langille (dalangil) wrote:\n>> Correct, we are trying to avoid that.  In addition, there is only https, no http.\n> \n> I don't think HTTPS versus HTTP matters.  I use Kerberos over HTTPS only\n> and it works fine.\n> \n>> To be clear, for the following tests, there is no Kerberos ticket.\n>> \n>> I tried that URL using three different browsers.  Each time I am prompted for\n>> a username & password.  After entering valid credentials, I get:\n>> \n>> Chrome: No data received. Unable to load the webpage because the server\n>> sent no data. Error code: ERR_EMPTY_RESPONSE\n>> \n>> With Firefox: The connection was reset\n>> \n>> Safari: Safari Can’t Open The Page\n>> \n>> However, I did stumble across something which seems promising.\n>> \n>> After the above failures, if I then browse to /gitweb/\n>> (where I see expected results) and then go to the info/refs URL you supplied,\n>> I see data such as this:\n>> \n>>   fe068a8ae55cea4bb90e2cc714107f4c5389d516\trefs/heads/0.96.x\n>>   d384a963980e9b40e34dea80eac280cf2d4b7c73\trefs/heads/0.97.x\n>> \n>> Conclusion: there is something in the /gitweb auth which is succeeding and then\n>> allowing /git to work\n> \n> That could possibly be due to KrbSaveCredentials.\n> \n>> For the record, this is the gitweb auth:\n>> \n>> <Location /gitweb>\n>>  SSLOptions +StdenvVars\n>>  Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch\n>> \n>>  AuthType           Kerberos\n>>  AuthName           “us.example.com\"\n>>  KrbAuthRealms      us.example.com\n>>  KrbServiceName     HTTP/us.example.com\n>>  Krb5Keytab         /usr/local/etc/apache22/repo-test.keytab\n>>  KrbMethodNegotiate on\n>>  KrbMethodk5Passwd  on\n> \n> Does it work if you set this value (KrbMethodK5Passwd on) explicitly in\n> the other configuration?  That might be sufficient.\n\nNo, it does not.\n\n>> That attempt is shown here: http://dpaste.com/04RG37E.txt\n>> \n>>> You'll obviously\n>>> want to see if the server offers Basic auth as well as Negotiate.\n>> \n>> I’m not up on my knowledge here.  You mean the Kerberos server?\n> \n> No, I meant the HTTP server, which it looks like from your attempt it\n> does.  I'm not really sure what the issue is after looking at that,\n> although it looks like Git isn't sending the username and password.\n> I'll try to look at this a little more this weekend.\n\nIf you can, thanks.  I’ll be happy to run any tests etc.  I’m the second\nperson here to tackle this and we keep hitting the same block.\n\ncheers\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n"},{"id":"254109","messageId":"1419652893-477694-1-git-send-email-sandals@crustytoothpaste.net","threadId":"38197","inReplyTo":"FBFEB910-4CB8-4049-901C-AADBFAB3AE9E@cisco.com","subject":"[PATCH] remote-curl: fall back to Basic auth if Negotiate fails.","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-12-27T04:01:33Z","receivedAt":"2014-12-27T04:01:33Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"Apache servers using mod_auth_kerb can be configured to allow the user\nto authenticate either using Negotiate (using the Kerberos ticket) or\nBasic authentication (using the Kerberos password).  Often, one will\nwant to use Negotiate authentication if it is available, but fall back\nto Basic authentication if the ticket is missing or expired.\n\nTeach the HTTP client code to stop trying authentication mechanisms that\ndon't use a password (currently Negotiate) after the first failure,\nsince if they failed the first time, they will never succeed.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\nI was able to reproduce the problem on my server.  This fixes the\nproblem for me both when info/refs requires authentication and when it\ndoes not.  Dan, please try and see if this fixes the problem for you.\n\nI'm not clear on whether NTLM is a passwordless authentication method.\nSince I don't use Windows or NTLM, I can't test it, but if it is, just\nadding it to HTTP_AUTH_PASSWORDLESS should be sufficient.\n\n http.c        | 14 ++++++++++++++\n http.h        |  5 ++++-\n remote-curl.c | 13 ++++++++++++-\n 3 files changed, 30 insertions(+), 2 deletions(-)\n\ndiff --git a/http.c b/http.c\nindex 040f362..e3e4c65 100644\n--- a/http.c\n+++ b/http.c\n@@ -986,6 +986,16 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,\n \t\tstrbuf_addstr(charset, \"ISO-8859-1\");\n }\n \n+void disable_passwordless_auth(struct active_request_slot *slot)\n+{\n+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n+#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)\n+\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,\n+\t\t\t CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);\n+#endif\n+}\n+\n+\n /* http_request() targets */\n #define HTTP_REQUEST_STRBUF\t0\n #define HTTP_REQUEST_FILE\t1\n@@ -1035,6 +1045,9 @@ static int http_request(const char *url,\n \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);\n \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n \n+\tif (options->no_passwordless_auth)\n+\t\tdisable_passwordless_auth(slot);\n+\n \tret = run_one_slot(slot, &results);\n \n \tif (options && options->content_type) {\n@@ -1139,6 +1152,7 @@ static int http_request_reauth(const char *url,\n \t}\n \n \tcredential_fill(&http_auth);\n+\toptions->no_passwordless_auth = 1;\n \n \treturn http_request(url, result, target, options);\n }\ndiff --git a/http.h b/http.h\nindex 473179b..fc42bf5 100644\n--- a/http.h\n+++ b/http.h\n@@ -98,6 +98,8 @@ extern int handle_curl_result(struct slot_results *results);\n int run_one_slot(struct active_request_slot *slot,\n \t\t struct slot_results *results);\n \n+void disable_passwordless_auth(struct active_request_slot *slot);\n+\n #ifdef USE_CURL_MULTI\n extern void fill_active_slots(void);\n extern void add_fill_function(void *data, int (*fill)(void *));\n@@ -138,7 +140,8 @@ extern char *get_remote_object_url(const char *url, const char *hex,\n /* Options for http_get_*() */\n struct http_get_options {\n \tunsigned no_cache:1,\n-\t\t keep_error:1;\n+\t\t keep_error:1,\n+\t\t no_passwordless_auth:1;\n \n \t/* If non-NULL, returns the content-type of the response. */\n \tstruct strbuf *content_type;\ndiff --git a/remote-curl.c b/remote-curl.c\nindex dd63bc2..89bf4ea 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -369,6 +369,8 @@ struct rpc_state {\n \tstruct strbuf result;\n \tunsigned gzip_request : 1;\n \tunsigned initial_buffer : 1;\n+\t/* Automatic authentication didn't work, so don't try it again. */\n+\tunsigned no_passwordless_auth : 1;\n };\n \n static size_t rpc_out(void *ptr, size_t eltsize,\n@@ -467,6 +469,9 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);\n \n+\tif (rpc->no_passwordless_auth)\n+\t\tdisable_passwordless_auth(slot);\n+\n \terr = run_slot(slot, results);\n \n \tcurl_slist_free_all(headers);\n@@ -510,8 +515,10 @@ static int post_rpc(struct rpc_state *rpc)\n \n \t\tdo {\n \t\t\terr = probe_rpc(rpc, &results);\n-\t\t\tif (err == HTTP_REAUTH)\n+\t\t\tif (err == HTTP_REAUTH) {\n \t\t\t\tcredential_fill(&http_auth);\n+\t\t\t\trpc->no_passwordless_auth = 1;\n+\t\t\t}\n \t\t} while (err == HTTP_REAUTH);\n \t\tif (err != HTTP_OK)\n \t\t\treturn -1;\n@@ -533,6 +540,9 @@ retry:\n \tcurl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);\n \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n \n+\tif (rpc->no_passwordless_auth)\n+\t\tdisable_passwordless_auth(slot);\n+\n \tif (large_request) {\n \t\t/* The request body is large and the size cannot be predicted.\n \t\t * We must use chunked encoding to send it.\n@@ -617,6 +627,7 @@ retry:\n \terr = run_slot(slot, NULL);\n \tif (err == HTTP_REAUTH && !large_request) {\n \t\tcredential_fill(&http_auth);\n+\t\trpc->no_passwordless_auth = 1;\n \t\tgoto retry;\n \t}\n \tif (err != HTTP_OK)\n-- \n2.2.1.209.g41e5f3a\n"},{"id":"254111","messageId":"20141227175604.GA23732@peff.net","threadId":"38197","inReplyTo":"1419652893-477694-1-git-send-email-sandals@crustytoothpaste.net","subject":"Re: [PATCH] remote-curl: fall back to Basic auth if Negotiate fails.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-12-27T17:56:04Z","receivedAt":"2014-12-27T17:56:04Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Dec 27, 2014 at 04:01:33AM +0000, brian m. carlson wrote:\n\n> Apache servers using mod_auth_kerb can be configured to allow the user\n> to authenticate either using Negotiate (using the Kerberos ticket) or\n> Basic authentication (using the Kerberos password).  Often, one will\n> want to use Negotiate authentication if it is available, but fall back\n> to Basic authentication if the ticket is missing or expired.\n> \n> Teach the HTTP client code to stop trying authentication mechanisms that\n> don't use a password (currently Negotiate) after the first failure,\n> since if they failed the first time, they will never succeed.\n> \n> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n> ---\n> I was able to reproduce the problem on my server.  This fixes the\n> problem for me both when info/refs requires authentication and when it\n> does not.  Dan, please try and see if this fixes the problem for you.\n> \n> I'm not clear on whether NTLM is a passwordless authentication method.\n> Since I don't use Windows or NTLM, I can't test it, but if it is, just\n> adding it to HTTP_AUTH_PASSWORDLESS should be sufficient.\n\nI don't think this should make things any worse for NTLM if it is. It\nwould just not get the benefit of the feature you are adding, and\nsomebody with a working setup can test and add it at that time, right?\n\nI'm not familiar enough with Negotiate auth to do give a thorough review\non the logic above. But FWIW, it makes sense to me, and the code looks\ncorrect.\n\nThe number of places you needed to add calls to disable_passwordless_auth\nis a sign that we might need to factor out our http auth handling better.\nThough that is not a problem you are introducing. :)\n\nThe credential struct is already a global for all requests. If you made\nthe \"no_passwordless\" flag similarly global, it would be enough to set\nit in handle_curl_result and respect it in get_curl_handle.\n\n-Peff\n"},{"id":"254115","messageId":"20141227210935.GA10649@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"20141227175604.GA23732@peff.net","subject":"Re: [PATCH] remote-curl: fall back to Basic auth if Negotiate fails.","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-12-27T21:09:36Z","receivedAt":"2014-12-27T21:09:36Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Sat, Dec 27, 2014 at 12:56:04PM -0500, Jeff King wrote:\n> On Sat, Dec 27, 2014 at 04:01:33AM +0000, brian m. carlson wrote:\n> \n> > Apache servers using mod_auth_kerb can be configured to allow the user\n> > to authenticate either using Negotiate (using the Kerberos ticket) or\n> > Basic authentication (using the Kerberos password).  Often, one will\n> > want to use Negotiate authentication if it is available, but fall back\n> > to Basic authentication if the ticket is missing or expired.\n> > \n> > Teach the HTTP client code to stop trying authentication mechanisms that\n> > don't use a password (currently Negotiate) after the first failure,\n> > since if they failed the first time, they will never succeed.\n> > \n> > Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n> > ---\n> > I was able to reproduce the problem on my server.  This fixes the\n> > problem for me both when info/refs requires authentication and when it\n> > does not.  Dan, please try and see if this fixes the problem for you.\n> > \n> > I'm not clear on whether NTLM is a passwordless authentication method.\n> > Since I don't use Windows or NTLM, I can't test it, but if it is, just\n> > adding it to HTTP_AUTH_PASSWORDLESS should be sufficient.\n> \n> I don't think this should make things any worse for NTLM if it is. It\n> would just not get the benefit of the feature you are adding, and\n> somebody with a working setup can test and add it at that time, right?\n\nCorrect.\n\n> I'm not familiar enough with Negotiate auth to do give a thorough review\n> on the logic above. But FWIW, it makes sense to me, and the code looks\n> correct.\n\nlibcurl will try very hard to use something other than Basic auth, even\nover HTTPS.  If Basic and something else are offered, libcurl will never\nuse Basic.  I should probably make a note of that in the commit message.\n\n> The credential struct is already a global for all requests. If you made\n> the \"no_passwordless\" flag similarly global, it would be enough to set\n> it in handle_curl_result and respect it in get_curl_handle.\n\nI'll reroll with that change.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"254116","messageId":"20141227212948.GA30098@peff.net","threadId":"38197","inReplyTo":"20141227210935.GA10649@vauxhall.crustytoothpaste.net","subject":"Re: [PATCH] remote-curl: fall back to Basic auth if Negotiate fails.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-12-27T21:29:49Z","receivedAt":"2014-12-27T21:29:49Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Dec 27, 2014 at 09:09:36PM +0000, brian m. carlson wrote:\n\n> > I'm not familiar enough with Negotiate auth to do give a thorough review\n> > on the logic above. But FWIW, it makes sense to me, and the code looks\n> > correct.\n> \n> libcurl will try very hard to use something other than Basic auth, even\n> over HTTPS.  If Basic and something else are offered, libcurl will never\n> use Basic.  I should probably make a note of that in the commit message.\n\nThanks, that does help explain things (to me, anyway).\n\nThe thing I am not sure of in your explanation is:\n\n>>> since if they failed the first time, they will never succeed\n\nAre there other GSSAPI methods where this is not the case? I don't know\nof any, and AFAICT git's support is used only for Kerberos, so this is\nprobably safe for now. If somebody can produce a concrete case that\nbehaves differently, we can untangle it then.\n\n-Peff\n"},{"id":"254122","messageId":"20141228000501.GB10649@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"20141227212948.GA30098@peff.net","subject":"Re: [PATCH] remote-curl: fall back to Basic auth if Negotiate fails.","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-12-28T00:05:03Z","receivedAt":"2014-12-28T00:05:03Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Sat, Dec 27, 2014 at 04:29:49PM -0500, Jeff King wrote:\n> >>> since if they failed the first time, they will never succeed\n> \n> Are there other GSSAPI methods where this is not the case? I don't know\n> of any, and AFAICT git's support is used only for Kerberos, so this is\n> probably safe for now. If somebody can produce a concrete case that\n> behaves differently, we can untangle it then.\n\nGSSAPI defines a token-based interface.  While it's possible that a user\ncould have multiple tokens, I don't think libcurl knows how to select\ndifferent ones, so TTBOMK it will always present the same token and\nhence always get the same response.\n\nlibcurl could theoretically be linked against any shared library\nimplementing the GSSAPI version 2.  I only know if it being used in\nKerberos and NTLM in practice.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"254244","messageId":"1420142187-1025433-1-git-send-email-sandals@crustytoothpaste.net","threadId":"38197","inReplyTo":"1419652893-477694-1-git-send-email-sandals@crustytoothpaste.net","subject":"[PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-01-01T19:56:27Z","receivedAt":"2015-01-01T19:56:27Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"Apache servers using mod_auth_kerb can be configured to allow the user\nto authenticate either using Negotiate (using the Kerberos ticket) or\nBasic authentication (using the Kerberos password).  Often, one will\nwant to use Negotiate authentication if it is available, but fall back\nto Basic authentication if the ticket is missing or expired.\n\nHowever, libcurl will try very hard to use something other than Basic\nauth, even over HTTPS.  If Basic and something else are offered, libcurl\nwill never attempt to use Basic, even if the other option fails.\nTeach the HTTP client code to stop trying authentication mechanisms that\ndon't use a password (currently Negotiate) after the first failure,\nsince if they failed the first time, they will never succeed.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\n http.c        | 16 ++++++++++++++++\n http.h        |  3 +++\n remote-curl.c | 11 ++++++++++-\n 3 files changed, 29 insertions(+), 1 deletion(-)\n\ndiff --git a/http.c b/http.c\nindex 040f362..815194d 100644\n--- a/http.c\n+++ b/http.c\n@@ -62,6 +62,8 @@ static const char *user_agent;\n \n static struct credential cert_auth = CREDENTIAL_INIT;\n static int ssl_cert_password_required;\n+/* Should we allow non-password-based authentication (e.g. GSSAPI)? */\n+int http_passwordless_auth = 1;\n \n static struct curl_slist *pragma_header;\n static struct curl_slist *no_pragma_header;\n@@ -986,6 +988,16 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,\n \t\tstrbuf_addstr(charset, \"ISO-8859-1\");\n }\n \n+void disable_passwordless_auth(struct active_request_slot *slot)\n+{\n+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n+#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)\n+\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,\n+\t\t\t CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);\n+#endif\n+}\n+\n+\n /* http_request() targets */\n #define HTTP_REQUEST_STRBUF\t0\n #define HTTP_REQUEST_FILE\t1\n@@ -1035,6 +1047,9 @@ static int http_request(const char *url,\n \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);\n \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n \n+\tif (!http_passwordless_auth)\n+\t\tdisable_passwordless_auth(slot);\n+\n \tret = run_one_slot(slot, &results);\n \n \tif (options && options->content_type) {\n@@ -1139,6 +1154,7 @@ static int http_request_reauth(const char *url,\n \t}\n \n \tcredential_fill(&http_auth);\n+\thttp_passwordless_auth = 0;\n \n \treturn http_request(url, result, target, options);\n }\ndiff --git a/http.h b/http.h\nindex 473179b..71943d3 100644\n--- a/http.h\n+++ b/http.h\n@@ -98,6 +98,8 @@ extern int handle_curl_result(struct slot_results *results);\n int run_one_slot(struct active_request_slot *slot,\n \t\t struct slot_results *results);\n \n+void disable_passwordless_auth(struct active_request_slot *slot);\n+\n #ifdef USE_CURL_MULTI\n extern void fill_active_slots(void);\n extern void add_fill_function(void *data, int (*fill)(void *));\n@@ -112,6 +114,7 @@ extern int active_requests;\n extern int http_is_verbose;\n extern size_t http_post_buffer;\n extern struct credential http_auth;\n+extern int http_passwordless_auth;\n \n extern char curl_errorstr[CURL_ERROR_SIZE];\n \ndiff --git a/remote-curl.c b/remote-curl.c\nindex dd63bc2..4ca5447 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -467,6 +467,9 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);\n \n+\tif (!http_passwordless_auth)\n+\t\tdisable_passwordless_auth(slot);\n+\n \terr = run_slot(slot, results);\n \n \tcurl_slist_free_all(headers);\n@@ -510,8 +513,10 @@ static int post_rpc(struct rpc_state *rpc)\n \n \t\tdo {\n \t\t\terr = probe_rpc(rpc, &results);\n-\t\t\tif (err == HTTP_REAUTH)\n+\t\t\tif (err == HTTP_REAUTH) {\n \t\t\t\tcredential_fill(&http_auth);\n+\t\t\t\thttp_passwordless_auth = 0;\n+\t\t\t}\n \t\t} while (err == HTTP_REAUTH);\n \t\tif (err != HTTP_OK)\n \t\t\treturn -1;\n@@ -533,6 +538,9 @@ retry:\n \tcurl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);\n \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n \n+\tif (!http_passwordless_auth)\n+\t\tdisable_passwordless_auth(slot);\n+\n \tif (large_request) {\n \t\t/* The request body is large and the size cannot be predicted.\n \t\t * We must use chunked encoding to send it.\n@@ -617,6 +625,7 @@ retry:\n \terr = run_slot(slot, NULL);\n \tif (err == HTTP_REAUTH && !large_request) {\n \t\tcredential_fill(&http_auth);\n+\t\thttp_passwordless_auth = 0;\n \t\tgoto retry;\n \t}\n \tif (err != HTTP_OK)\n-- \n2.2.1.209.g41e5f3a\n"},{"id":"254267","messageId":"20150103111922.GB27793@peff.net","threadId":"38197","inReplyTo":"1420142187-1025433-1-git-send-email-sandals@crustytoothpaste.net","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-01-03T11:19:23Z","receivedAt":"2015-01-03T11:19:23Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 01, 2015 at 07:56:27PM +0000, brian m. carlson wrote:\n\n> +void disable_passwordless_auth(struct active_request_slot *slot)\n> +{\n> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n> +#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)\n> +\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,\n> +\t\t\t CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);\n> +#endif\n> +}\n\nI like that you are trying to put a layer of abstraction around what\n\"passwordless\" means here, but it seems like there are two layers. The\nfunction itself abstracts the idea, and then there is an extra\nHTTP_AUTH_PASSWORDLESS macro. Since the concept is already confined to\nthis function and used only once, it might be more readable to simply\nget rid of HTTP_AUTH_PASSWORD.\n\n> @@ -1035,6 +1047,9 @@ static int http_request(const char *url,\n>  \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);\n>  \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n>  \n> +\tif (!http_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n>  \tret = run_one_slot(slot, &results);\n>  \n>  \tif (options && options->content_type) {\n> @@ -1139,6 +1154,7 @@ static int http_request_reauth(const char *url,\n>  \t}\n>  \n>  \tcredential_fill(&http_auth);\n> +\thttp_passwordless_auth = 0;\n>  \n>  \treturn http_request(url, result, target, options);\n>  }\n\nThis pattern gets repeated in several places. Now that\nhttp_passwordless_auth is a global, can we handle it automatically for\nthe callers, as below (which, aside from compiling, is completely\nuntested by me)?\n\nNote that this is in a slightly different boat than credential_fill.\nIdeally we would also handle picking up credentials on behalf of the\ncallers of get_curl_handle/handle_curl_result. But that may involve\nsignificant work and/or prompting the user, which we _must_ avoid if we\ndo not know if we are going to retry the request (and only the caller\nknows that for sure). However, in the case of http_passwordless_auth, we\nare just setting a flag, so it's OK to do it preemptively.\n\ndiff --git a/http.c b/http.c\nindex 040f362..2bbcdf1 100644\n--- a/http.c\n+++ b/http.c\n@@ -62,6 +62,8 @@ static const char *user_agent;\n \n static struct credential cert_auth = CREDENTIAL_INIT;\n static int ssl_cert_password_required;\n+/* Should we allow non-password-based authentication (e.g. GSSAPI)? */\n+static int http_passwordless_auth = 1;\n \n static struct curl_slist *pragma_header;\n static struct curl_slist *no_pragma_header;\n@@ -318,7 +320,12 @@ static CURL *get_curl_handle(void)\n \tcurl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);\n #endif\n #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n-\tcurl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\n+\t{\n+\t\tint flags = CURLAUTH_ANY;\n+\t\tif (!http_passwordless_auth)\n+\t\t\tflags &= ~CURLAUTH_GSSNEGOTIATE;\n+\t\tcurl_easy_setopt(result, CURLOPT_HTTPAUTH, flags);\n+\t}\n #endif\n \n \tif (http_proactive_auth)\n@@ -870,6 +877,7 @@ int handle_curl_result(struct slot_results *results)\n \t\t\tcredential_reject(&http_auth);\n \t\t\treturn HTTP_NOAUTH;\n \t\t} else {\n+\t\t\thttp_passwordless_auth = 0;\n \t\t\treturn HTTP_REAUTH;\n \t\t}\n \t} else {\n\n\nNote that you could probably drop http_passwordless_auth completely, and\njust keep a:\n\n  static int http_auth_methods = CURLAUTH_ANY;\n\nand then drop CURLAUTH_GSSNEGOTIATE from it instead of setting the\npasswordless_auth flag to 0 (again, it happens in one place, so I don't\nknow that it needs an extra layer of abstraction).\n\n-Peff\n"},{"id":"254269","messageId":"20150103174509.GA1025060@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"20150103111922.GB27793@peff.net","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-01-03T17:45:09Z","receivedAt":"2015-01-03T17:45:09Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Sat, Jan 03, 2015 at 06:19:23AM -0500, Jeff King wrote:\n>This pattern gets repeated in several places. Now that\n>http_passwordless_auth is a global, can we handle it automatically for\n>the callers, as below (which, aside from compiling, is completely\n>untested by me)?\n\nThis looks good (although I haven't tested it).\n\n>Note that this is in a slightly different boat than credential_fill.\n>Ideally we would also handle picking up credentials on behalf of the\n>callers of get_curl_handle/handle_curl_result. But that may involve\n>significant work and/or prompting the user, which we _must_ avoid if we\n>do not know if we are going to retry the request (and only the caller\n>knows that for sure). However, in the case of http_passwordless_auth, we\n>are just setting a flag, so it's OK to do it preemptively.\n\nRight.  We already prompt the user for a username and password in that \ncase, so we already have the credentials that we need.\n\n>diff --git a/http.c b/http.c\n>index 040f362..2bbcdf1 100644\n>--- a/http.c\n>+++ b/http.c\n>@@ -62,6 +62,8 @@ static const char *user_agent;\n>\n> static struct credential cert_auth = CREDENTIAL_INIT;\n> static int ssl_cert_password_required;\n>+/* Should we allow non-password-based authentication (e.g. GSSAPI)? */\n>+static int http_passwordless_auth = 1;\n>\n> static struct curl_slist *pragma_header;\n> static struct curl_slist *no_pragma_header;\n>@@ -318,7 +320,12 @@ static CURL *get_curl_handle(void)\n> \tcurl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);\n> #endif\n> #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n>-\tcurl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\n>+\t{\n>+\t\tint flags = CURLAUTH_ANY;\n\nI think this needs to be unsigned long or it can cause undefined \nbehavior, since libcurl uses unsigned long in the flags.  I'll fix that \nup when I reroll.  I'll need your sign-off since it will essentially be \nyour work.\n\n>+\t\tif (!http_passwordless_auth)\n>+\t\t\tflags &= ~CURLAUTH_GSSNEGOTIATE;\n>+\t\tcurl_easy_setopt(result, CURLOPT_HTTPAUTH, flags);\n>+\t}\n> #endif\n>\n> \tif (http_proactive_auth)\n>@@ -870,6 +877,7 @@ int handle_curl_result(struct slot_results *results)\n> \t\t\tcredential_reject(&http_auth);\n> \t\t\treturn HTTP_NOAUTH;\n> \t\t} else {\n>+\t\t\thttp_passwordless_auth = 0;\n> \t\t\treturn HTTP_REAUTH;\n> \t\t}\n> \t} else {\n>\n>\n>Note that you could probably drop http_passwordless_auth completely, and\n>just keep a:\n>\n>  static int http_auth_methods = CURLAUTH_ANY;\n>\n>and then drop CURLAUTH_GSSNEGOTIATE from it instead of setting the\n>passwordless_auth flag to 0 (again, it happens in one place, so I don't\n>know that it needs an extra layer of abstraction).\n\nThis does seem to handle both cases well.  It also has the pleasant \nside effect of being static.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"254271","messageId":"20150103201444.GA8285@peff.net","threadId":"38197","inReplyTo":"20150103174509.GA1025060@vauxhall.crustytoothpaste.net","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-01-03T20:14:44Z","receivedAt":"2015-01-03T20:14:44Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jan 03, 2015 at 05:45:09PM +0000, brian m. carlson wrote:\n\n> >+\t{\n> >+\t\tint flags = CURLAUTH_ANY;\n> \n> I think this needs to be unsigned long or it can cause undefined behavior,\n> since libcurl uses unsigned long in the flags.  I'll fix that up when I\n> reroll.  I'll need your sign-off since it will essentially be your work.\n\nI think curl typically uses signed \"long\" for flags, but certainly\ncheck the docs to be sure.\n\nI was thinking it would be integer-promoted in this case, but I'm not\nsure that works always (certainly it does not if CURLAUTH_ANY needs high\nbits, but depending on how curl_easy_setopt is implemented, it may also\nbe implicitly cast as a pointer or something).\n\nAnd certainly you can have my signoff:\n\n  Signed-off-by: Jeff King <peff@peff.net>\n\n-Peff\n"},{"id":"254290","messageId":"E4E8ABDE-80F2-4378-8B12-251B70056BF8@cisco.com","threadId":"38197","inReplyTo":"1419652893-477694-1-git-send-email-sandals@crustytoothpaste.net","subject":"Re: [PATCH] remote-curl: fall back to Basic auth if Negotiate fails.","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-05T13:12:21Z","receivedAt":"2015-01-05T13:12:21Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Dec 26, 2014, at 11:01 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> Apache servers using mod_auth_kerb can be configured to allow the user\n> to authenticate either using Negotiate (using the Kerberos ticket) or\n> Basic authentication (using the Kerberos password).  Often, one will\n> want to use Negotiate authentication if it is available, but fall back\n> to Basic authentication if the ticket is missing or expired.\n> \n> Teach the HTTP client code to stop trying authentication mechanisms that\n> don't use a password (currently Negotiate) after the first failure,\n> since if they failed the first time, they will never succeed.\n> \n> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n> ---\n> I was able to reproduce the problem on my server.  This fixes the\n> problem for me both when info/refs requires authentication and when it\n> does not.  Dan, please try and see if this fixes the problem for you.\n\nHas the patch changed since originally posted?  Is there a newer one I should try instead?\n\nThank you for your work on this, I will test this today.\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n\n\n> \n> I'm not clear on whether NTLM is a passwordless authentication method.\n> Since I don't use Windows or NTLM, I can't test it, but if it is, just\n> adding it to HTTP_AUTH_PASSWORDLESS should be sufficient.\n> \n> http.c        | 14 ++++++++++++++\n> http.h        |  5 ++++-\n> remote-curl.c | 13 ++++++++++++-\n> 3 files changed, 30 insertions(+), 2 deletions(-)\n> \n> diff --git a/http.c b/http.c\n> index 040f362..e3e4c65 100644\n> --- a/http.c\n> +++ b/http.c\n> @@ -986,6 +986,16 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,\n> \t\tstrbuf_addstr(charset, \"ISO-8859-1\");\n> }\n> \n> +void disable_passwordless_auth(struct active_request_slot *slot)\n> +{\n> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n> +#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)\n> +\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,\n> +\t\t\t CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);\n> +#endif\n> +}\n> +\n> +\n> /* http_request() targets */\n> #define HTTP_REQUEST_STRBUF\t0\n> #define HTTP_REQUEST_FILE\t1\n> @@ -1035,6 +1045,9 @@ static int http_request(const char *url,\n> \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n> \n> +\tif (options->no_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \tret = run_one_slot(slot, &results);\n> \n> \tif (options && options->content_type) {\n> @@ -1139,6 +1152,7 @@ static int http_request_reauth(const char *url,\n> \t}\n> \n> \tcredential_fill(&http_auth);\n> +\toptions->no_passwordless_auth = 1;\n> \n> \treturn http_request(url, result, target, options);\n> }\n> diff --git a/http.h b/http.h\n> index 473179b..fc42bf5 100644\n> --- a/http.h\n> +++ b/http.h\n> @@ -98,6 +98,8 @@ extern int handle_curl_result(struct slot_results *results);\n> int run_one_slot(struct active_request_slot *slot,\n> \t\t struct slot_results *results);\n> \n> +void disable_passwordless_auth(struct active_request_slot *slot);\n> +\n> #ifdef USE_CURL_MULTI\n> extern void fill_active_slots(void);\n> extern void add_fill_function(void *data, int (*fill)(void *));\n> @@ -138,7 +140,8 @@ extern char *get_remote_object_url(const char *url, const char *hex,\n> /* Options for http_get_*() */\n> struct http_get_options {\n> \tunsigned no_cache:1,\n> -\t\t keep_error:1;\n> +\t\t keep_error:1,\n> +\t\t no_passwordless_auth:1;\n> \n> \t/* If non-NULL, returns the content-type of the response. */\n> \tstruct strbuf *content_type;\n> diff --git a/remote-curl.c b/remote-curl.c\n> index dd63bc2..89bf4ea 100644\n> --- a/remote-curl.c\n> +++ b/remote-curl.c\n> @@ -369,6 +369,8 @@ struct rpc_state {\n> \tstruct strbuf result;\n> \tunsigned gzip_request : 1;\n> \tunsigned initial_buffer : 1;\n> +\t/* Automatic authentication didn't work, so don't try it again. */\n> +\tunsigned no_passwordless_auth : 1;\n> };\n> \n> static size_t rpc_out(void *ptr, size_t eltsize,\n> @@ -467,6 +469,9 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)\n> \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);\n> \n> +\tif (rpc->no_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \terr = run_slot(slot, results);\n> \n> \tcurl_slist_free_all(headers);\n> @@ -510,8 +515,10 @@ static int post_rpc(struct rpc_state *rpc)\n> \n> \t\tdo {\n> \t\t\terr = probe_rpc(rpc, &results);\n> -\t\t\tif (err == HTTP_REAUTH)\n> +\t\t\tif (err == HTTP_REAUTH) {\n> \t\t\t\tcredential_fill(&http_auth);\n> +\t\t\t\trpc->no_passwordless_auth = 1;\n> +\t\t\t}\n> \t\t} while (err == HTTP_REAUTH);\n> \t\tif (err != HTTP_OK)\n> \t\t\treturn -1;\n> @@ -533,6 +540,9 @@ retry:\n> \tcurl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n> \n> +\tif (rpc->no_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \tif (large_request) {\n> \t\t/* The request body is large and the size cannot be predicted.\n> \t\t * We must use chunked encoding to send it.\n> @@ -617,6 +627,7 @@ retry:\n> \terr = run_slot(slot, NULL);\n> \tif (err == HTTP_REAUTH && !large_request) {\n> \t\tcredential_fill(&http_auth);\n> +\t\trpc->no_passwordless_auth = 1;\n> \t\tgoto retry;\n> \t}\n> \tif (err != HTTP_OK)\n> -- \n> 2.2.1.209.g41e5f3a\n> \n\n"},{"id":"254292","messageId":"DE424FAF-32BC-4E73-B81E-36836D5613E7@cisco.com","threadId":"38197","inReplyTo":"1420142187-1025433-1-git-send-email-sandals@crustytoothpaste.net","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-05T16:02:49Z","receivedAt":"2015-01-05T16:02:49Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"I’ve found the latest patch.  Trying this now.  Thanks.\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n> On Jan 1, 2015, at 2:56 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> Apache servers using mod_auth_kerb can be configured to allow the user\n> to authenticate either using Negotiate (using the Kerberos ticket) or\n> Basic authentication (using the Kerberos password).  Often, one will\n> want to use Negotiate authentication if it is available, but fall back\n> to Basic authentication if the ticket is missing or expired.\n> \n> However, libcurl will try very hard to use something other than Basic\n> auth, even over HTTPS.  If Basic and something else are offered, libcurl\n> will never attempt to use Basic, even if the other option fails.\n> Teach the HTTP client code to stop trying authentication mechanisms that\n> don't use a password (currently Negotiate) after the first failure,\n> since if they failed the first time, they will never succeed.\n> \n> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n> ---\n> http.c        | 16 ++++++++++++++++\n> http.h        |  3 +++\n> remote-curl.c | 11 ++++++++++-\n> 3 files changed, 29 insertions(+), 1 deletion(-)\n> \n> diff --git a/http.c b/http.c\n> index 040f362..815194d 100644\n> --- a/http.c\n> +++ b/http.c\n> @@ -62,6 +62,8 @@ static const char *user_agent;\n> \n> static struct credential cert_auth = CREDENTIAL_INIT;\n> static int ssl_cert_password_required;\n> +/* Should we allow non-password-based authentication (e.g. GSSAPI)? */\n> +int http_passwordless_auth = 1;\n> \n> static struct curl_slist *pragma_header;\n> static struct curl_slist *no_pragma_header;\n> @@ -986,6 +988,16 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,\n> \t\tstrbuf_addstr(charset, \"ISO-8859-1\");\n> }\n> \n> +void disable_passwordless_auth(struct active_request_slot *slot)\n> +{\n> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n> +#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)\n> +\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,\n> +\t\t\t CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);\n> +#endif\n> +}\n> +\n> +\n> /* http_request() targets */\n> #define HTTP_REQUEST_STRBUF\t0\n> #define HTTP_REQUEST_FILE\t1\n> @@ -1035,6 +1047,9 @@ static int http_request(const char *url,\n> \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n> \n> +\tif (!http_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \tret = run_one_slot(slot, &results);\n> \n> \tif (options && options->content_type) {\n> @@ -1139,6 +1154,7 @@ static int http_request_reauth(const char *url,\n> \t}\n> \n> \tcredential_fill(&http_auth);\n> +\thttp_passwordless_auth = 0;\n> \n> \treturn http_request(url, result, target, options);\n> }\n> diff --git a/http.h b/http.h\n> index 473179b..71943d3 100644\n> --- a/http.h\n> +++ b/http.h\n> @@ -98,6 +98,8 @@ extern int handle_curl_result(struct slot_results *results);\n> int run_one_slot(struct active_request_slot *slot,\n> \t\t struct slot_results *results);\n> \n> +void disable_passwordless_auth(struct active_request_slot *slot);\n> +\n> #ifdef USE_CURL_MULTI\n> extern void fill_active_slots(void);\n> extern void add_fill_function(void *data, int (*fill)(void *));\n> @@ -112,6 +114,7 @@ extern int active_requests;\n> extern int http_is_verbose;\n> extern size_t http_post_buffer;\n> extern struct credential http_auth;\n> +extern int http_passwordless_auth;\n> \n> extern char curl_errorstr[CURL_ERROR_SIZE];\n> \n> diff --git a/remote-curl.c b/remote-curl.c\n> index dd63bc2..4ca5447 100644\n> --- a/remote-curl.c\n> +++ b/remote-curl.c\n> @@ -467,6 +467,9 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)\n> \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);\n> \n> +\tif (!http_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \terr = run_slot(slot, results);\n> \n> \tcurl_slist_free_all(headers);\n> @@ -510,8 +513,10 @@ static int post_rpc(struct rpc_state *rpc)\n> \n> \t\tdo {\n> \t\t\terr = probe_rpc(rpc, &results);\n> -\t\t\tif (err == HTTP_REAUTH)\n> +\t\t\tif (err == HTTP_REAUTH) {\n> \t\t\t\tcredential_fill(&http_auth);\n> +\t\t\t\thttp_passwordless_auth = 0;\n> +\t\t\t}\n> \t\t} while (err == HTTP_REAUTH);\n> \t\tif (err != HTTP_OK)\n> \t\t\treturn -1;\n> @@ -533,6 +538,9 @@ retry:\n> \tcurl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n> \n> +\tif (!http_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \tif (large_request) {\n> \t\t/* The request body is large and the size cannot be predicted.\n> \t\t * We must use chunked encoding to send it.\n> @@ -617,6 +625,7 @@ retry:\n> \terr = run_slot(slot, NULL);\n> \tif (err == HTTP_REAUTH && !large_request) {\n> \t\tcredential_fill(&http_auth);\n> +\t\thttp_passwordless_auth = 0;\n> \t\tgoto retry;\n> \t}\n> \tif (err != HTTP_OK)\n> -- \n> 2.2.1.209.g41e5f3a\n> \n\n"},{"id":"254307","messageId":"F91CD1B2-262C-4ED6-AE46-31B1333E0350@cisco.com","threadId":"38197","inReplyTo":"1420142187-1025433-1-git-send-email-sandals@crustytoothpaste.net","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-05T21:23:32Z","receivedAt":"2015-01-05T21:23:32Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"I have tried both patches.  Neither succeeds here.  I patched git version 2.2.1 but I don’t think that affects this.\n\nBefore I flood the list with debug runs, I wanted to make sure I was testing with an appropriate configuration:\n\n<Location /git>\n SSLOptions +StdenvVars\n Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch\n\n   # By default, allow access to anyone.\n   Order allow,deny\n   Allow from All\n\n   # Enable Kerberos authentication using mod_auth_kerb.\n  AuthType           Kerberos\n  AuthName           “us.example.org\"\n  KrbAuthRealms      us.example.org\n  # I have tried both with and without the following line:\n  KrbServiceName     HTTP/us.example.org\n  Krb5Keytab         /usr/local/etc/apache22/repo-test.keytab\n   KrbMethodNegotiate on\n   KrbSaveCredentials on\n   KrbVerifyKDC on\n   KrbServiceName Any\n  # I have tried with and without this line:\n  KrbMethodk5Passwd  on\n   Require valid-user\n</Location>\n\nWith a valid ticket, the above works for a git clone.\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n> On Jan 1, 2015, at 2:56 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> Apache servers using mod_auth_kerb can be configured to allow the user\n> to authenticate either using Negotiate (using the Kerberos ticket) or\n> Basic authentication (using the Kerberos password).  Often, one will\n> want to use Negotiate authentication if it is available, but fall back\n> to Basic authentication if the ticket is missing or expired.\n> \n> However, libcurl will try very hard to use something other than Basic\n> auth, even over HTTPS.  If Basic and something else are offered, libcurl\n> will never attempt to use Basic, even if the other option fails.\n> Teach the HTTP client code to stop trying authentication mechanisms that\n> don't use a password (currently Negotiate) after the first failure,\n> since if they failed the first time, they will never succeed.\n> \n> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n> ---\n> http.c        | 16 ++++++++++++++++\n> http.h        |  3 +++\n> remote-curl.c | 11 ++++++++++-\n> 3 files changed, 29 insertions(+), 1 deletion(-)\n> \n> diff --git a/http.c b/http.c\n> index 040f362..815194d 100644\n> --- a/http.c\n> +++ b/http.c\n> @@ -62,6 +62,8 @@ static const char *user_agent;\n> \n> static struct credential cert_auth = CREDENTIAL_INIT;\n> static int ssl_cert_password_required;\n> +/* Should we allow non-password-based authentication (e.g. GSSAPI)? */\n> +int http_passwordless_auth = 1;\n> \n> static struct curl_slist *pragma_header;\n> static struct curl_slist *no_pragma_header;\n> @@ -986,6 +988,16 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,\n> \t\tstrbuf_addstr(charset, \"ISO-8859-1\");\n> }\n> \n> +void disable_passwordless_auth(struct active_request_slot *slot)\n> +{\n> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n> +#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)\n> +\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,\n> +\t\t\t CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);\n> +#endif\n> +}\n> +\n> +\n> /* http_request() targets */\n> #define HTTP_REQUEST_STRBUF\t0\n> #define HTTP_REQUEST_FILE\t1\n> @@ -1035,6 +1047,9 @@ static int http_request(const char *url,\n> \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n> \n> +\tif (!http_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \tret = run_one_slot(slot, &results);\n> \n> \tif (options && options->content_type) {\n> @@ -1139,6 +1154,7 @@ static int http_request_reauth(const char *url,\n> \t}\n> \n> \tcredential_fill(&http_auth);\n> +\thttp_passwordless_auth = 0;\n> \n> \treturn http_request(url, result, target, options);\n> }\n> diff --git a/http.h b/http.h\n> index 473179b..71943d3 100644\n> --- a/http.h\n> +++ b/http.h\n> @@ -98,6 +98,8 @@ extern int handle_curl_result(struct slot_results *results);\n> int run_one_slot(struct active_request_slot *slot,\n> \t\t struct slot_results *results);\n> \n> +void disable_passwordless_auth(struct active_request_slot *slot);\n> +\n> #ifdef USE_CURL_MULTI\n> extern void fill_active_slots(void);\n> extern void add_fill_function(void *data, int (*fill)(void *));\n> @@ -112,6 +114,7 @@ extern int active_requests;\n> extern int http_is_verbose;\n> extern size_t http_post_buffer;\n> extern struct credential http_auth;\n> +extern int http_passwordless_auth;\n> \n> extern char curl_errorstr[CURL_ERROR_SIZE];\n> \n> diff --git a/remote-curl.c b/remote-curl.c\n> index dd63bc2..4ca5447 100644\n> --- a/remote-curl.c\n> +++ b/remote-curl.c\n> @@ -467,6 +467,9 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)\n> \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);\n> \n> +\tif (!http_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \terr = run_slot(slot, results);\n> \n> \tcurl_slist_free_all(headers);\n> @@ -510,8 +513,10 @@ static int post_rpc(struct rpc_state *rpc)\n> \n> \t\tdo {\n> \t\t\terr = probe_rpc(rpc, &results);\n> -\t\t\tif (err == HTTP_REAUTH)\n> +\t\t\tif (err == HTTP_REAUTH) {\n> \t\t\t\tcredential_fill(&http_auth);\n> +\t\t\t\thttp_passwordless_auth = 0;\n> +\t\t\t}\n> \t\t} while (err == HTTP_REAUTH);\n> \t\tif (err != HTTP_OK)\n> \t\t\treturn -1;\n> @@ -533,6 +538,9 @@ retry:\n> \tcurl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_ENCODING, \"gzip\");\n> \n> +\tif (!http_passwordless_auth)\n> +\t\tdisable_passwordless_auth(slot);\n> +\n> \tif (large_request) {\n> \t\t/* The request body is large and the size cannot be predicted.\n> \t\t * We must use chunked encoding to send it.\n> @@ -617,6 +625,7 @@ retry:\n> \terr = run_slot(slot, NULL);\n> \tif (err == HTTP_REAUTH && !large_request) {\n> \t\tcredential_fill(&http_auth);\n> +\t\thttp_passwordless_auth = 0;\n> \t\tgoto retry;\n> \t}\n> \tif (err != HTTP_OK)\n> -- \n> 2.2.1.209.g41e5f3a\n> \n\n"},{"id":"254311","messageId":"20150105235308.GC1025060@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"F91CD1B2-262C-4ED6-AE46-31B1333E0350@cisco.com","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-01-05T23:53:09Z","receivedAt":"2015-01-05T23:53:09Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Mon, Jan 05, 2015 at 09:23:32PM +0000, Dan Langille (dalangil) wrote:\n>I have tried both patches.  Neither succeeds here.  I patched git \n>version 2.2.1 but I don’t think that affects this.\n\nYou are patching the client side, correct?  That's the side that needs \npatching here.\n\nJust so the list knows, I will be sending a reroll to the existing \npatch, but the patches I've posted do indeed work in my testing.\n\n>Before I flood the list with debug runs, I wanted to make sure I was \n>testing with an appropriate configuration:\n>\n><Location /git>\n> SSLOptions +StdenvVars\n> Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch\n>\n>   # By default, allow access to anyone.\n>   Order allow,deny\n>   Allow from All\n>\n>   # Enable Kerberos authentication using mod_auth_kerb.\n>  AuthType           Kerberos\n>  AuthName           “us.example.org\"\n>  KrbAuthRealms      us.example.org\n>  # I have tried both with and without the following line:\n>  KrbServiceName     HTTP/us.example.org\n>  Krb5Keytab         /usr/local/etc/apache22/repo-test.keytab\n>   KrbMethodNegotiate on\n>   KrbSaveCredentials on\n>   KrbVerifyKDC on\n>   KrbServiceName Any\n>  # I have tried with and without this line:\n>  KrbMethodk5Passwd  on\n>   Require valid-user\n></Location>\n\nI'm not sure why it's not working for you.  Here's a snippet from my \nconfig:\n\n  SetEnv GIT_HTTP_EXPORT_ALL 1\n  SetEnv REMOTE_USER $REDIRECT_REMOTE_USER\n  AuthType Kerberos\n  AuthName \"Kerberos Login\"\n  KrbMethodNegotiate on\n  KrbMethodK5Passwd off\n  KrbAuthRealms CRUSTYTOOTHPASTE.NET\n  Krb5Keytab /etc/krb5.apache.keytab\n\nWhen I was testing, I set KrbMethodK5Passwd to on and it did in fact \nwork.  I'm using Debian's Apache 2.4.10-9 with mod_auth_kerb 5.4-2.2.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"254340","messageId":"3FBC0B0E-BB54-4BD5-AE7D-C82BA9FBA1C1@cisco.com","threadId":"38197","inReplyTo":"20150105235308.GC1025060@vauxhall.crustytoothpaste.net","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-06T15:31:29Z","receivedAt":"2015-01-06T15:31:29Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"On Jan 5, 2015, at 6:53 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> On Mon, Jan 05, 2015 at 09:23:32PM +0000, Dan Langille (dalangil) wrote:\n>> I have tried both patches.  Neither succeeds here.  I patched git version 2.2.1 but I don’t think that affects this.\n> \n> You are patching the client side, correct?  That's the side that needs patching here.\n\nYes, I am.\n\n> Just so the list knows, I will be sending a reroll to the existing patch, but the patches I've posted do indeed work in my testing.\n\nI appreciate the patches.  I blame something here.\n\nThe patches don’t t apply cleanly to git-2.2.1 or to the latest git source I just cloned.  I had to copy/paste some two chunks in http.c and everything in remote-curl.c.\n\nLooking at the source, the place to patch is there, just on a different line number.\n\n[dvl@porter93 /usr/ports/devel/git/work/git-2.2.1]$ sudo patch < ~dvl/patch2.txt\nHmm...  Looks like a unified diff to me...\nThe text leading up to this was:\n--------------------------\n|diff --git a/http.c b/http.c\n|index 040f362..815194d 100644\n|--- a/http.c\n|+++ b/http.c\n--------------------------\nPatching file http.c using Plan A...\nHunk #1 succeeded at 62.\nHunk #2 succeeded at 988 with fuzz 2.\nHunk #3 failed at 1047.\nHunk #4 failed at 1154.\n2 out of 4 hunks failed--saving rejects to http.c.rej\nHmm...  The next patch looks like a unified diff to me...\nThe text leading up to this was:\n--------------------------\n|diff --git a/http.h b/http.h\n|index 473179b..71943d3 100644\n|--- a/http.h\n|+++ b/http.h\n--------------------------\nPatching file http.h using Plan A...\nHunk #1 succeeded at 98 with fuzz 2.\nHunk #2 succeeded at 114.\nHmm...  The next patch looks like a unified diff to me...\nThe text leading up to this was:\n--------------------------\n|diff --git a/remote-curl.c b/remote-curl.c\n|index dd63bc2..4ca5447 100644\n|--- a/remote-curl.c\n|+++ b/remote-curl.c\n--------------------------\nPatching file remote-curl.c using Plan A...\nHunk #1 failed at 467.\nHunk #2 failed at 513.\nHunk #3 failed at 538.\nHunk #4 failed at 625.\n4 out of 4 hunks failed--saving rejects to remote-curl.c.rej\ndone\n\n\n>> Before I flood the list with debug runs, I wanted to make sure I was testing with an appropriate configuration:\n>> \n>> <Location /git>\n>> SSLOptions +StdenvVars\n>> Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch\n>> \n>>  # By default, allow access to anyone.\n>>  Order allow,deny\n>>  Allow from All\n>> \n>>  # Enable Kerberos authentication using mod_auth_kerb.\n>> AuthType           Kerberos\n>> AuthName           “us.example.org\"\n>> KrbAuthRealms      us.example.org\n>> # I have tried both with and without the following line:\n>> KrbServiceName     HTTP/us.example.org\n>> Krb5Keytab         /usr/local/etc/apache22/repo-test.keytab\n>>  KrbMethodNegotiate on\n>>  KrbSaveCredentials on\n>>  KrbVerifyKDC on\n>>  KrbServiceName Any\n>> # I have tried with and without this line:\n>> KrbMethodk5Passwd  on\n>>  Require valid-user\n>> </Location>\n> \n> I'm not sure why it's not working for you.  Here's a snippet from my config:\n> \n> SetEnv GIT_HTTP_EXPORT_ALL 1\n> SetEnv REMOTE_USER $REDIRECT_REMOTE_USER\n> AuthType Kerberos\n> AuthName \"Kerberos Login\"\n> KrbMethodNegotiate on\n> KrbMethodK5Passwd off\n> KrbAuthRealms CRUSTYTOOTHPASTE.NET\n> Krb5Keytab /etc/krb5.apache.keytab\n> \n> When I was testing, I set KrbMethodK5Passwd to on and it did in fact work.  I'm using Debian's Apache 2.4.10-9 with mod_auth_kerb 5.4-2.2.\n\nThat didn’t seem to help, but perhaps the patching is the issue.\n\n\n\n"},{"id":"254341","messageId":"531A1350-22B9-4B64-BB8E-C627C545F4DA@cisco.com","threadId":"38197","inReplyTo":"3FBC0B0E-BB54-4BD5-AE7D-C82BA9FBA1C1@cisco.com","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-06T15:41:20Z","receivedAt":"2015-01-06T15:41:20Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Jan 6, 2015, at 10:31 AM, Dan Langille (dalangil) <dalangil@cisco.com> wrote:\n> \n> On Jan 5, 2015, at 6:53 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n>> \n>> On Mon, Jan 05, 2015 at 09:23:32PM +0000, Dan Langille (dalangil) wrote:\n>>> I have tried both patches.  Neither succeeds here.  I patched git version 2.2.1 but I don’t think that affects this.\n>> \n>> You are patching the client side, correct?  That's the side that needs patching here.\n> \n> Yes, I am.\n> \n>> Just so the list knows, I will be sending a reroll to the existing patch, but the patches I've posted do indeed work in my testing.\n> \n> I appreciate the patches.  I blame something here.\n> \n> The patches don’t t apply cleanly to git-2.2.1 or to the latest git source I just cloned.  I had to copy/paste some two chunks in http.c and everything in remote-curl.c.\n\nNOTE: I now realize these problems are caused by tabs being converted to spaces when downloading the patch.  I’m going to test again."},{"id":"254343","messageId":"AB98E028-8531-447B-959C-1DB385AB8578@cisco.com","threadId":"38197","inReplyTo":"3FBC0B0E-BB54-4BD5-AE7D-C82BA9FBA1C1@cisco.com","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-06T16:07:01Z","receivedAt":"2015-01-06T16:07:01Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Jan 6, 2015, at 10:31 AM, Dan Langille (dalangil) <dalangil@cisco.com> wrote:\n> \n> On Jan 5, 2015, at 6:53 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n>> \n>> On Mon, Jan 05, 2015 at 09:23:32PM +0000, Dan Langille (dalangil) wrote:\n>>> I have tried both patches.  Neither succeeds here.  I patched git version 2.2.1 but I don’t think that affects this.\n>> \n>> You are patching the client side, correct?  That's the side that needs patching here.\n> \n> Yes, I am.\n> \n>> Just so the list knows, I will be sending a reroll to the existing patch, but the patches I've posted do indeed work in my testing.\n> \n> I appreciate the patches.  I blame something here.\n> \n> The patches don’t t apply cleanly to git-2.2.1 or to the latest git source I just cloned.  I had to copy/paste some two chunks in http.c and everything in remote-curl.c.\n\nI tried again, with a proper copy of your patch. Cleanly patched versions of git 2.2.1 and from\na recent clone of the repo both give 'Authentication failed’ when doing a clone without a ticket.\n\nI’m sure there’s something here which is at fault.\n\nHere is the client side debugging.  Is this what is expected?  Tested with a clone of git from this morning.\n\n[dan@porter93 ~/tmp/tmp]$ ~/src/git/git clone https://us.example.org/git/clamav-bytecode-compiler\nCloning into 'clamav-bytecode-compiler'...\nwarning: templates not found /usr/home/dan/share/git-core/templates\n* Couldn't find host us.example.org in the .netrc file; using defaults\n* Hostname was NOT found in DNS cache\n*   Trying 10.0.0.1...\n* Connected to us.example.org (10.0.0.1) port 443 (#0)\n* successfully set certificate verify locations:\n*   CAfile: /usr/local/share/certs/ca-root-nss.crt\n  CApath: none\n* SSL connection using TLSv1.0 / DHE-RSA-CAMELLIA256-SHA\n* Server certificate:\n* \t subject: REDACTED\n* \t start date: REDACTED\n* \t expire date: REDACTED\n* \t issuer: REDACTED\n* \t SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.\n> GET /git/clamav-bytecode-compiler/info/refs?service=git-upload-pack HTTP/1.1\nUser-Agent: git/2.2.1.212.gc5b9256.dirty\nHost: us.example.org\nAccept: */*\nAccept-Encoding: gzip\nPragma: no-cache\n\n< HTTP/1.1 401 Authorization Required\n< Date: Tue, 06 Jan 2015 16:02:38 GMT\n< Server: Apache\n< WWW-Authenticate: Negotiate\n< Content-Length: 401\n< Content-Type: text/html; charset=iso-8859-1\n< \n* Connection #0 to host us.example.org left intact\nUsername for 'https://us.example.org': \nPassword for 'https://dan@us.example.org': \n* Couldn't find host us.example.org in the .netrc file; using defaults\n* Connection 0 seems to be dead!\n* Closing connection 0\n* Hostname was found in DNS cache\n*   Trying 10.0.0.1...\n* Connected to us.example.org (10.0.0.1) port 443 (#1)\n* successfully set certificate verify locations:\n*   CAfile: /usr/local/share/certs/ca-root-nss.crt\n  CApath: none\n* SSL re-using session ID\n* SSL connection using TLSv1.0 / DHE-RSA-CAMELLIA256-SHA\n* Server certificate:\n* \t subject: REDACTED\n* \t start date: REDACTED\n* \t expire date: REDACTED\n* \t issuer: REDACTED\n* \t SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.\n> GET /git/clamav-bytecode-compiler/info/refs?service=git-upload-pack HTTP/1.1\nUser-Agent: git/2.2.1.212.gc5b9256.dirty\nHost: us.example.org\nAccept: */*\nAccept-Encoding: gzip\nPragma: no-cache\n\n< HTTP/1.1 401 Authorization Required\n< Date: Tue, 06 Jan 2015 16:02:48 GMT\n< Server: Apache\n< WWW-Authenticate: Negotiate\n< Content-Length: 401\n< Content-Type: text/html; charset=iso-8859-1\n< \n* Connection #1 to host us.example.org left intact\nfatal: Authentication failed for 'https://us.example.org/git/clamav-bytecode-compiler/'\n[dan@porter93 ~/tmp/tmp]$ \n\n\n\n\n"},{"id":"254437","messageId":"20150108000216.GH1025060@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"AB98E028-8531-447B-959C-1DB385AB8578@cisco.com","subject":"Re: [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-01-08T00:02:17Z","receivedAt":"2015-01-08T00:02:17Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Tue, Jan 06, 2015 at 04:07:01PM +0000, Dan Langille (dalangil) wrote:\n>< HTTP/1.1 401 Authorization Required\n>< Date: Tue, 06 Jan 2015 16:02:48 GMT\n>< Server: Apache\n>< WWW-Authenticate: Negotiate\n\nYour server is set up incorrectly.  You should see a Negotiate line and \na Basic line as well.  Right now, you only have Negotiate set up, so if \nyou don't have a ticket, it's going to fail.\n\nI'd recommend making sure that you can access it using a web browser \nafter running kdestroy.  That will ensure that it's working properly.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"254438","messageId":"1420676960-492860-1-git-send-email-sandals@crustytoothpaste.net","threadId":"38197","inReplyTo":"1420142187-1025433-1-git-send-email-sandals@crustytoothpaste.net","subject":"[PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-01-08T00:29:20Z","receivedAt":"2015-01-08T00:29:20Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"Apache servers using mod_auth_kerb can be configured to allow the user\nto authenticate either using Negotiate (using the Kerberos ticket) or\nBasic authentication (using the Kerberos password).  Often, one will\nwant to use Negotiate authentication if it is available, but fall back\nto Basic authentication if the ticket is missing or expired.\n\nHowever, libcurl will try very hard to use something other than Basic\nauth, even over HTTPS.  If Basic and something else are offered, libcurl\nwill never attempt to use Basic, even if the other option fails.\nTeach the HTTP client code to stop trying authentication mechanisms that\ndon't use a password (currently Negotiate) after the first failure,\nsince if they failed the first time, they will never succeed.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\nSigned-off-by: Jeff King <peff@peff.net>\n---\nPeff's original change was to get_curl_handle; however, we retry the\nsecond time with the same slot and we may not call get_curl_handle\nagain, so I had to move that change to get_active_slot.  This has been\ntested pushing with both Negotiate and Basic against an HTTPS server\nboth when info/refs was protected and when it was not.\n\n http.c | 10 ++++++++++\n 1 file changed, 10 insertions(+)\n\ndiff --git a/http.c b/http.c\nindex 040f362..44b130c 100644\n--- a/http.c\n+++ b/http.c\n@@ -62,6 +62,9 @@ static const char *user_agent;\n \n static struct credential cert_auth = CREDENTIAL_INIT;\n static int ssl_cert_password_required;\n+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n+static unsigned long http_auth_methods = CURLAUTH_ANY;\n+#endif\n \n static struct curl_slist *pragma_header;\n static struct curl_slist *no_pragma_header;\n@@ -580,6 +583,9 @@ struct active_request_slot *get_active_slot(void)\n \tcurl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);\n \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);\n+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n+\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);\n+#endif\n \tif (http_auth.password)\n \t\tinit_curl_http_auth(slot->curl);\n \n@@ -870,6 +876,9 @@ int handle_curl_result(struct slot_results *results)\n \t\t\tcredential_reject(&http_auth);\n \t\t\treturn HTTP_NOAUTH;\n \t\t} else {\n+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n+\t\t\thttp_auth_methods &= ~CURLAUTH_GSSNEGOTIATE;\n+#endif\n \t\t\treturn HTTP_REAUTH;\n \t\t}\n \t} else {\n@@ -986,6 +995,7 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,\n \t\tstrbuf_addstr(charset, \"ISO-8859-1\");\n }\n \n+\n /* http_request() targets */\n #define HTTP_REQUEST_STRBUF\t0\n #define HTTP_REQUEST_FILE\t1\n-- \n2.2.1.209.g41e5f3a\n"},{"id":"254941","messageId":"7930FE25-8206-43A8-9678-C56D789E09CE@cisco.com","threadId":"38197","inReplyTo":"1420676960-492860-1-git-send-email-sandals@crustytoothpaste.net","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-20T16:40:52Z","receivedAt":"2015-01-20T16:40:52Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"I did not test this patch.  Is that holding up a commit?\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n> On Jan 7, 2015, at 7:29 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> Apache servers using mod_auth_kerb can be configured to allow the user\n> to authenticate either using Negotiate (using the Kerberos ticket) or\n> Basic authentication (using the Kerberos password).  Often, one will\n> want to use Negotiate authentication if it is available, but fall back\n> to Basic authentication if the ticket is missing or expired.\n> \n> However, libcurl will try very hard to use something other than Basic\n> auth, even over HTTPS.  If Basic and something else are offered, libcurl\n> will never attempt to use Basic, even if the other option fails.\n> Teach the HTTP client code to stop trying authentication mechanisms that\n> don't use a password (currently Negotiate) after the first failure,\n> since if they failed the first time, they will never succeed.\n> \n> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n> Signed-off-by: Jeff King <peff@peff.net>\n> ---\n> Peff's original change was to get_curl_handle; however, we retry the\n> second time with the same slot and we may not call get_curl_handle\n> again, so I had to move that change to get_active_slot.  This has been\n> tested pushing with both Negotiate and Basic against an HTTPS server\n> both when info/refs was protected and when it was not.\n> \n> http.c | 10 ++++++++++\n> 1 file changed, 10 insertions(+)\n> \n> diff --git a/http.c b/http.c\n> index 040f362..44b130c 100644\n> --- a/http.c\n> +++ b/http.c\n> @@ -62,6 +62,9 @@ static const char *user_agent;\n> \n> static struct credential cert_auth = CREDENTIAL_INIT;\n> static int ssl_cert_password_required;\n> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n> +static unsigned long http_auth_methods = CURLAUTH_ANY;\n> +#endif\n> \n> static struct curl_slist *pragma_header;\n> static struct curl_slist *no_pragma_header;\n> @@ -580,6 +583,9 @@ struct active_request_slot *get_active_slot(void)\n> \tcurl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);\n> \tcurl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);\n> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n> +\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);\n> +#endif\n> \tif (http_auth.password)\n> \t\tinit_curl_http_auth(slot->curl);\n> \n> @@ -870,6 +876,9 @@ int handle_curl_result(struct slot_results *results)\n> \t\t\tcredential_reject(&http_auth);\n> \t\t\treturn HTTP_NOAUTH;\n> \t\t} else {\n> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY\n> +\t\t\thttp_auth_methods &= ~CURLAUTH_GSSNEGOTIATE;\n> +#endif\n> \t\t\treturn HTTP_REAUTH;\n> \t\t}\n> \t} else {\n> @@ -986,6 +995,7 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,\n> \t\tstrbuf_addstr(charset, \"ISO-8859-1\");\n> }\n> \n> +\n> /* http_request() targets */\n> #define HTTP_REQUEST_STRBUF\t0\n> #define HTTP_REQUEST_FILE\t1\n> -- \n> 2.2.1.209.g41e5f3a\n> \n\n"},{"id":"254969","messageId":"xmqqk30hyock.fsf@gitster.dls.corp.google.com","threadId":"38197","inReplyTo":"7930FE25-8206-43A8-9678-C56D789E09CE@cisco.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-01-21T00:22:19Z","receivedAt":"2015-01-21T00:22:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Dan Langille (dalangil)\" <dalangil@cisco.com> writes:\n\n> I did not test this patch.  Is that holding up a commit?\n\nI am hoping that you rebuilt the Git you use with this patch by the\ntime you wrote the message I am responding to and have been using it\nfor your daily Git needs ;-)\n\nI believe it is queued on the 'next' branch so that others like you\nwho need the change can verify the improvements, and others unlike\nyou who do not need the change can make sure the change does not\ncause unintended consequences.\n\nThanks.\n"},{"id":"255100","messageId":"00E4CEA7-3ECC-41CD-A9BC-D7EAF56DCFDE@cisco.com","threadId":"38197","inReplyTo":"xmqqk30hyock.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-01-22T14:47:21Z","receivedAt":"2015-01-22T14:47:21Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Jan 20, 2015, at 7:22 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \n> \"Dan Langille (dalangil)\" <dalangil@cisco.com> writes:\n> \n>> I did not test this patch.  Is that holding up a commit?\n> \n> I am hoping that you rebuilt the Git you use with this patch by the\n> time you wrote the message I am responding to and have been using it\n> for your daily Git needs ;-)\n\nPatch v2 has been used in our test environment with success.  I got diverted to other projects before I could test Patch v3.\n\n> I believe it is queued on the 'next' branch so that others like you\n> who need the change can verify the improvements, and others unlike\n> you who do not need the change can make sure the change does not\n> cause unintended consequences.\n\nThank you.\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n\n"},{"id":"256248","messageId":"CA01B76E-F3D4-40AC-B524-32BFBA930108@cisco.com","threadId":"38197","inReplyTo":"xmqqk30hyock.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-02-17T23:05:41Z","receivedAt":"2015-02-17T23:05:41Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Jan 20, 2015, at 7:22 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \n> \"Dan Langille (dalangil)\" <dalangil@cisco.com> writes:\n> \n>> I did not test this patch.  Is that holding up a commit?\n> \n> I am hoping that you rebuilt the Git you use with this patch by the\n> time you wrote the message I am responding to and have been using it\n> for your daily Git needs ;-)\n> \n> I believe it is queued on the 'next' branch so that others like you\n> who need the change can verify the improvements, and others unlike\n> you who do not need the change can make sure the change does not\n> cause unintended consequences.\n\nIs this the patch in question?\n\n https://github.com/git/git/commit/4dbe66464b4fd695c5989cc272fa0edd6475037c\n\nI ask because previous versions of the patch acted against http.h as well and my failure with it.\n\nCould I expect that patch work against 2.3.0?\n\nIt applies cleanly, compiles, but cores when I try a ‘git clone’.  Unmatched 2.3.0 succeeds."},{"id":"256252","messageId":"xmqqa90cxg89.fsf@gitster.dls.corp.google.com","threadId":"38197","inReplyTo":"CA01B76E-F3D4-40AC-B524-32BFBA930108@cisco.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-02-17T23:36:54Z","receivedAt":"2015-02-17T23:36:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Dan Langille (dalangil)\" <dalangil@cisco.com> writes:\n\n>> On Jan 20, 2015, at 7:22 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> \n>> \"Dan Langille (dalangil)\" <dalangil@cisco.com> writes:\n>> \n>>> I did not test this patch.  Is that holding up a commit?\n>> \n>> I am hoping that you rebuilt the Git you use with this patch by the\n>> time you wrote the message I am responding to and have been using it\n>> for your daily Git needs ;-)\n>> \n>> I believe it is queued on the 'next' branch so that others like you\n>> who need the change can verify the improvements, and others unlike\n>> you who do not need the change can make sure the change does not\n>> cause unintended consequences.\n>\n> Is this the patch in question?\n>\n>  https://github.com/git/git/commit/4dbe66464b4fd695c5989cc272fa0edd6475037c\n>\n> I ask because previous versions of the patch acted against http.h as\n> well and my failure with it.\n>\n> Could I expect that patch work against 2.3.0?\n>\n> It applies cleanly, compiles, but cores when I try a ‘git clone’.\n> Unmatched 2.3.0 succeeds.\n\nIt already is in 'master', so please holler if things break with\nthat version.\n\nThanks.\n"},{"id":"256278","messageId":"1B14107C-FC87-4F69-AEBE-9EA1BAF50A17@cisco.com","threadId":"38197","inReplyTo":"xmqqa90cxg89.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-02-18T16:17:46Z","receivedAt":"2015-02-18T16:17:46Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"On Feb 17, 2015, at 6:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \n> \"Dan Langille (dalangil)\" <dalangil@cisco.com> writes:\n> \n>>> On Jan 20, 2015, at 7:22 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> \n>>> \"Dan Langille (dalangil)\" <dalangil@cisco.com> writes:\n>>> \n>>>> I did not test this patch.  Is that holding up a commit?\n>>> \n>>> I am hoping that you rebuilt the Git you use with this patch by the\n>>> time you wrote the message I am responding to and have been using it\n>>> for your daily Git needs ;-)\n>>> \n>>> I believe it is queued on the 'next' branch so that others like you\n>>> who need the change can verify the improvements, and others unlike\n>>> you who do not need the change can make sure the change does not\n>>> cause unintended consequences.\n>> \n>> Is this the patch in question?\n>> \n>> https://github.com/git/git/commit/4dbe66464b4fd695c5989cc272fa0edd6475037c\n>> \n>> I ask because previous versions of the patch acted against http.h as\n>> well and my failure with it.\n>> \n>> Could I expect that patch work against 2.3.0?\n>> \n>> It applies cleanly, compiles, but cores when I try a ‘git clone’.\n>> Unmatched 2.3.0 succeeds.\n> \n> It already is in 'master', so please holler if things break with\n> that version.\n\n\nI just built from ‘master’, on FreeBSD 9.3:\n\ncd ~/src\ngit clone https://github.com/git/git.git\ncd git\ngmake\n\nThen tried ~/src/git/git clone https://OUR_REPO\n\n It cores too, and I see: git-remote-https.core\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n"},{"id":"256364","messageId":"20150219203556.GC5021@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"1B14107C-FC87-4F69-AEBE-9EA1BAF50A17@cisco.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-02-19T20:35:57Z","receivedAt":"2015-02-19T20:35:57Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Wed, Feb 18, 2015 at 04:17:46PM +0000, Dan Langille (dalangil) wrote:\n> I just built from ‘master’, on FreeBSD 9.3:\n> \n> cd ~/src\n> git clone https://github.com/git/git.git\n> cd git\n> gmake\n> \n> Then tried ~/src/git/git clone https://OUR_REPO\n> \n>  It cores too, and I see: git-remote-https.core\n\nCan you compile with debugging symbols and provide a backtrace?  I'm not \nseeing any such behavior on my end, and I'm not sure whether it's my \npatch or something else that might be present in master.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"256594","messageId":"ABA76895-9BD2-4EA8-B765-0F9DE71A2CEC@cisco.com","threadId":"38197","inReplyTo":"20150219203556.GC5021@vauxhall.crustytoothpaste.net","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-02-24T21:03:32Z","receivedAt":"2015-02-24T21:03:32Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Feb 19, 2015, at 3:35 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> On Wed, Feb 18, 2015 at 04:17:46PM +0000, Dan Langille (dalangil) wrote:\n>> I just built from ‘master’, on FreeBSD 9.3:\n>> \n>> cd ~/src\n>> git clone https://github.com/git/git.git\n>> cd git\n>> gmake\n>> \n>> Then tried ~/src/git/git clone https://OUR_REPO\n>> \n>> It cores too, and I see: git-remote-https.core\n> \n> Can you compile with debugging symbols and provide a backtrace?  I'm not \n> seeing any such behavior on my end, and I'm not sure whether it's my \n> patch or something else that might be present in master.\n\nThe problem originally occurred under VMware Fusion and I’m unable to get a backtrace from it.\nI suspect memory constraints are a factor.  There’s only 5GB RAM available to this VM.\n\nI have tried in another VM and that succeeds.  All good there. It has 40GB RAM.\n\nI am going to try this on a third system. At present, we’re just 50/50 on success.\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n\n\n"},{"id":"256660","messageId":"3E5DD2BE-1E44-4D0A-89A1-627A1239C72A@cisco.com","threadId":"38197","inReplyTo":"ABA76895-9BD2-4EA8-B765-0F9DE71A2CEC@cisco.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-02-25T20:59:19Z","receivedAt":"2015-02-25T20:59:19Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Feb 24, 2015, at 4:03 PM, Dan Langille (dalangil) <dalangil@cisco.com> wrote:\n> \n>> On Feb 19, 2015, at 3:35 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n>> \n>> On Wed, Feb 18, 2015 at 04:17:46PM +0000, Dan Langille (dalangil) wrote:\n>>> I just built from ‘master’, on FreeBSD 9.3:\n>>> \n>>> cd ~/src\n>>> git clone https://github.com/git/git.git\n>>> cd git\n>>> gmake\n>>> \n>>> Then tried ~/src/git/git clone https://OUR_REPO\n>>> \n>>> It cores too, and I see: git-remote-https.core\n>> \n>> Can you compile with debugging symbols and provide a backtrace?  I'm not \n>> seeing any such behavior on my end, and I'm not sure whether it's my \n>> patch or something else that might be present in master.\n> \n> The problem originally occurred under VMware Fusion and I’m unable to get a backtrace from it.\n> I suspect memory constraints are a factor.  There’s only 5GB RAM available to this VM.\n> \n> I have tried in another VM and that succeeds.  All good there. It has 40GB RAM.\n> \n> I am going to try this on a third system. At present, we’re just 50/50 on success.\n\n\nWe have made progress I think.\n\nWith stock git:\n\ntl;dr: 1 - with a ticket, you get prompted, but hitting ENTER succeeds.\n       2 - without a ticket, nothing works\n\n\nWith patched git:\n\ntl;dr: 1 - with a ticket,    entering credentials, SUCCEEDS; just hit enter, failure\n       2 - without a ticket, entering credentials, SUCCEEDS\n\nHere is my test, with a valid kerberos ticket:\n\n$ git clone https://git.example.com/git/clamav-bytecode-compiler\nCloning into 'clamav-bytecode-compiler'...\nUsername for 'https://git.example.com': \nPassword for 'https://git.example.com': \n^Cmote: Counting objects: 224546   \n$\n\n"},{"id":"257486","messageId":"E53D99DB-E894-4FA8-9351-39E23FFD677E@cisco.com","threadId":"38197","inReplyTo":"3E5DD2BE-1E44-4D0A-89A1-627A1239C72A@cisco.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-03-10T18:05:46Z","receivedAt":"2015-03-10T18:05:46Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Feb 25, 2015, at 3:59 PM, Dan Langille (dalangil) <dalangil@cisco.com> wrote:\n> \n>> On Feb 24, 2015, at 4:03 PM, Dan Langille (dalangil) <dalangil@cisco.com> wrote:\n>> \n>>> On Feb 19, 2015, at 3:35 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n>>> \n>>> On Wed, Feb 18, 2015 at 04:17:46PM +0000, Dan Langille (dalangil) wrote:\n>>>> I just built from ‘master’, on FreeBSD 9.3:\n>>>> \n>>>> cd ~/src\n>>>> git clone https://github.com/git/git.git\n>>>> cd git\n>>>> gmake\n>>>> \n>>>> Then tried ~/src/git/git clone https://OUR_REPO\n>>>> \n>>>> It cores too, and I see: git-remote-https.core\n>>> \n>>> Can you compile with debugging symbols and provide a backtrace?  I'm not \n>>> seeing any such behavior on my end, and I'm not sure whether it's my \n>>> patch or something else that might be present in master.\n>> \n>> The problem originally occurred under VMware Fusion and I’m unable to get a backtrace from it.\n>> I suspect memory constraints are a factor.  There’s only 5GB RAM available to this VM.\n>> \n>> I have tried in another VM and that succeeds.  All good there. It has 40GB RAM.\n>> \n>> I am going to try this on a third system. At present, we’re just 50/50 on success.\n> \n> \n> We have made progress I think.\n> \n> With stock git:\n> \n> tl;dr: 1 - with a ticket, you get prompted, but hitting ENTER succeeds.\n>       2 - without a ticket, nothing works\n> \n> \n> With patched git:\n> \n> tl;dr: 1 - with a ticket,    entering credentials, SUCCEEDS; just hit enter, failure\n\nIf I have a valid ticket, why am I being prompted for credentials?\n\nIt appears patched git always wants credentials entered and ignores the valid ticket.\n\n>       2 - without a ticket, entering credentials, SUCCEEDS\n> \n> Here is my test, with a valid kerberos ticket:\n> \n> $ git clone https://git.example.com/git/clamav-bytecode-compiler\n> Cloning into 'clamav-bytecode-compiler'...\n> Username for 'https://git.example.com': \n> Password for 'https://git.example.com': \n> ^Cmote: Counting objects: 224546   \n> $\n> \n\n"},{"id":"257506","messageId":"20150310222907.GA36141@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"E53D99DB-E894-4FA8-9351-39E23FFD677E@cisco.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-03-10T22:29:08Z","receivedAt":"2015-03-10T22:29:08Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Tue, Mar 10, 2015 at 06:05:46PM +0000, Dan Langille (dalangil) wrote:\n>> We have made progress I think.\n>>\n>> With stock git:\n>>\n>> tl;dr: 1 - with a ticket, you get prompted, but hitting ENTER succeeds.\n>>       2 - without a ticket, nothing works\n>>\n>>\n>> With patched git:\n>>\n>> tl;dr: 1 - with a ticket,    entering credentials, SUCCEEDS; just hit enter, failure\n>\n>If I have a valid ticket, why am I being prompted for credentials?\n\nlibcurl won't even attempt authentication if you don't have a username\nspecified.  I know that the web server should be able to figure it out\nfrom your credentials, so it shouldn't matter what username you provide.\nThis is an unfortuate quirk of libcurl.\n\nAlso, are you using 2.3.0, or one of the earlier patched versions?  That\nmight affect how it works.\n\n>It appears patched git always wants credentials entered and ignores the\n>valid ticket.\n\nSo what I think is happening is that you didn't specify a username, but\ngit got a 401, so it prompted.  Now it actually attempts to use the\npassword you provided, whereas before it did not.\n\nDoes it work with a ticket if you specify a username, as in the\nfollowing URL?\nhttps://bmc@git.crustytoothpaste.net/git/bmc/homedir.git\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"257563","messageId":"68DFACB3-5EA7-4414-9B74-B4E6F6A417B9@cisco.com","threadId":"38197","inReplyTo":"20150310222907.GA36141@vauxhall.crustytoothpaste.net","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-03-11T19:33:05Z","receivedAt":"2015-03-11T19:33:05Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Mar 10, 2015, at 6:29 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> On Tue, Mar 10, 2015 at 06:05:46PM +0000, Dan Langille (dalangil) wrote:\n>>> We have made progress I think.\n>>> \n>>> With stock git:\n>>> \n>>> tl;dr: 1 - with a ticket, you get prompted, but hitting ENTER succeeds.\n>>>      2 - without a ticket, nothing works\n>>> \n>>> \n>>> With patched git:\n>>> \n>>> tl;dr: 1 - with a ticket,    entering credentials, SUCCEEDS; just hit enter, failure\n>> \n>> If I have a valid ticket, why am I being prompted for credentials?\n> \n> libcurl won't even attempt authentication if you don't have a username\n> specified.  I know that the web server should be able to figure it out\n> from your credentials, so it shouldn't matter what username you provide.\n> This is an unfortuate quirk of lib curl.\n\nI understand.\n\n> Also, are you using 2.3.0, or one of the earlier patched versions?  That\n> might affect how it works.\n\nI am using git-2.3.0\n\n>> It appears patched git always wants credentials entered and ignores the\n>> valid ticket.\n> \n> So what I think is happening is that you didn't specify a username, but\n> git got a 401, so it prompted.  Now it actually attempts to use the\n> password you provided, whereas before it did not.\n> \n> Does it work with a ticket if you specify a username, as in the\n> following URL?\n> https://bmc@git.crustytoothpaste.net/git/bmc/homedir.git\n\nYes, that does work.  Our project is 98% of the way there now. \n\nI looked at both libcurl and git environment variables to see if there\nwas a way to specify the user without putting it in the URL.  I didn’t see one.\n\nMy next step is the git configuration, either server or client.  Do you know \nif I should stop looking now because it’s not there?\n\nThank you for your help in getting us this far.  This helps us tremendously.\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n"},{"id":"257573","messageId":"20150311215919.GA46326@vauxhall.crustytoothpaste.net","threadId":"38197","inReplyTo":"68DFACB3-5EA7-4414-9B74-B4E6F6A417B9@cisco.com","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-03-11T21:59:20Z","receivedAt":"2015-03-11T21:59:20Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Wed, Mar 11, 2015 at 07:33:05PM +0000, Dan Langille (dalangil) wrote:\n>> On Mar 10, 2015, at 6:29 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n>> Does it work with a ticket if you specify a username, as in the\n>> following URL?\n>> https://bmc@git.crustytoothpaste.net/git/bmc/homedir.git\n>\n>Yes, that does work.  Our project is 98% of the way there now.\n>\n>I looked at both libcurl and git environment variables to see if there\n>was a way to specify the user without putting it in the URL.  I didn’t see one.\n>\n>My next step is the git configuration, either server or client.  Do you know\n>if I should stop looking now because it’s not there?\n\nYou might try looking at git config --help.  It looks like there's a\ncredential.username option that might do what you want.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"257592","messageId":"6A7DB00C-7787-41A0-9C9F-88F6CFD92D98@cisco.com","threadId":"38197","inReplyTo":"20150311215919.GA46326@vauxhall.crustytoothpaste.net","subject":"Re: [PATCH v3] remote-curl: fall back to Basic auth if Negotiate fails","fromName":"Dan Langille (dalangil)","fromEmail":"dalangil@cisco.com","sentAt":"2015-03-12T13:09:40Z","receivedAt":"2015-03-12T13:09:40Z","isPatch":true,"sender":{"key":"dalangil@cisco.com","avatar":null},"body":"> On Mar 11, 2015, at 5:59 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> On Wed, Mar 11, 2015 at 07:33:05PM +0000, Dan Langille (dalangil) wrote:\n>>> On Mar 10, 2015, at 6:29 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n>>> Does it work with a ticket if you specify a username, as in the\n>>> following URL?\n>>> https://bmc@git.crustytoothpaste.net/git/bmc/homedir.git\n>> \n>> Yes, that does work.  Our project is 98% of the way there now.\n>> \n>> I looked at both libcurl and git environment variables to see if there\n>> was a way to specify the user without putting it in the URL.  I didn’t see one.\n>> \n>> My next step is the git configuration, either server or client.  Do you know\n>> if I should stop looking now because it’s not there?\n> \n> You might try looking at git config --help.  It looks like there's a\n> credential.username option that might do what you want.\n\nBrian et al,\n\nThank you for your help and patience with this.  It is appreciated.\n\n— \nDan Langille\nInfrastructure & Operations\nTalos Group\nSourcefire, Inc.\n\n\n\n"}]}