> On Dec 26, 2014, at 11:01 PM, brian m. carlson <sand...@crustytoothpaste.net> 
> wrote:
> 
> Apache servers using mod_auth_kerb can be configured to allow the user
> to authenticate either using Negotiate (using the Kerberos ticket) or
> Basic authentication (using the Kerberos password).  Often, one will
> want to use Negotiate authentication if it is available, but fall back
> to Basic authentication if the ticket is missing or expired.
> 
> Teach the HTTP client code to stop trying authentication mechanisms that
> don't use a password (currently Negotiate) after the first failure,
> since if they failed the first time, they will never succeed.
> 
> Signed-off-by: brian m. carlson <sand...@crustytoothpaste.net>
> ---
> I was able to reproduce the problem on my server.  This fixes the
> problem for me both when info/refs requires authentication and when it
> does not.  Dan, please try and see if this fixes the problem for you.

Has the patch changed since originally posted?  Is there a newer one I should 
try instead?

Thank you for your work on this, I will test this today.

— 
Dan Langille
Infrastructure & Operations
Talos Group
Sourcefire, Inc.



> 
> I'm not clear on whether NTLM is a passwordless authentication method.
> Since I don't use Windows or NTLM, I can't test it, but if it is, just
> adding it to HTTP_AUTH_PASSWORDLESS should be sufficient.
> 
> http.c        | 14 ++++++++++++++
> http.h        |  5 ++++-
> remote-curl.c | 13 ++++++++++++-
> 3 files changed, 30 insertions(+), 2 deletions(-)
> 
> diff --git a/http.c b/http.c
> index 040f362..e3e4c65 100644
> --- a/http.c
> +++ b/http.c
> @@ -986,6 +986,16 @@ static void extract_content_type(struct strbuf *raw, 
> struct strbuf *type,
>               strbuf_addstr(charset, "ISO-8859-1");
> }
> 
> +void disable_passwordless_auth(struct active_request_slot *slot)
> +{
> +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
> +#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)
> +     curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,
> +                      CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);
> +#endif
> +}
> +
> +
> /* http_request() targets */
> #define HTTP_REQUEST_STRBUF   0
> #define HTTP_REQUEST_FILE     1
> @@ -1035,6 +1045,9 @@ static int http_request(const char *url,
>       curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
>       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
> 
> +     if (options->no_passwordless_auth)
> +             disable_passwordless_auth(slot);
> +
>       ret = run_one_slot(slot, &results);
> 
>       if (options && options->content_type) {
> @@ -1139,6 +1152,7 @@ static int http_request_reauth(const char *url,
>       }
> 
>       credential_fill(&http_auth);
> +     options->no_passwordless_auth = 1;
> 
>       return http_request(url, result, target, options);
> }
> diff --git a/http.h b/http.h
> index 473179b..fc42bf5 100644
> --- a/http.h
> +++ b/http.h
> @@ -98,6 +98,8 @@ extern int handle_curl_result(struct slot_results *results);
> int run_one_slot(struct active_request_slot *slot,
>                struct slot_results *results);
> 
> +void disable_passwordless_auth(struct active_request_slot *slot);
> +
> #ifdef USE_CURL_MULTI
> extern void fill_active_slots(void);
> extern void add_fill_function(void *data, int (*fill)(void *));
> @@ -138,7 +140,8 @@ extern char *get_remote_object_url(const char *url, const 
> char *hex,
> /* Options for http_get_*() */
> struct http_get_options {
>       unsigned no_cache:1,
> -              keep_error:1;
> +              keep_error:1,
> +              no_passwordless_auth:1;
> 
>       /* If non-NULL, returns the content-type of the response. */
>       struct strbuf *content_type;
> diff --git a/remote-curl.c b/remote-curl.c
> index dd63bc2..89bf4ea 100644
> --- a/remote-curl.c
> +++ b/remote-curl.c
> @@ -369,6 +369,8 @@ struct rpc_state {
>       struct strbuf result;
>       unsigned gzip_request : 1;
>       unsigned initial_buffer : 1;
> +     /* Automatic authentication didn't work, so don't try it again. */
> +     unsigned no_passwordless_auth : 1;
> };
> 
> static size_t rpc_out(void *ptr, size_t eltsize,
> @@ -467,6 +469,9 @@ static int probe_rpc(struct rpc_state *rpc, struct 
> slot_results *results)
>       curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
>       curl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);
> 
> +     if (rpc->no_passwordless_auth)
> +             disable_passwordless_auth(slot);
> +
>       err = run_slot(slot, results);
> 
>       curl_slist_free_all(headers);
> @@ -510,8 +515,10 @@ static int post_rpc(struct rpc_state *rpc)
> 
>               do {
>                       err = probe_rpc(rpc, &results);
> -                     if (err == HTTP_REAUTH)
> +                     if (err == HTTP_REAUTH) {
>                               credential_fill(&http_auth);
> +                             rpc->no_passwordless_auth = 1;
> +                     }
>               } while (err == HTTP_REAUTH);
>               if (err != HTTP_OK)
>                       return -1;
> @@ -533,6 +540,9 @@ retry:
>       curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
>       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
> 
> +     if (rpc->no_passwordless_auth)
> +             disable_passwordless_auth(slot);
> +
>       if (large_request) {
>               /* The request body is large and the size cannot be predicted.
>                * We must use chunked encoding to send it.
> @@ -617,6 +627,7 @@ retry:
>       err = run_slot(slot, NULL);
>       if (err == HTTP_REAUTH && !large_request) {
>               credential_fill(&http_auth);
> +             rpc->no_passwordless_auth = 1;
>               goto retry;
>       }
>       if (err != HTTP_OK)
> -- 
> 2.2.1.209.g41e5f3a
> 

N�����r��y����b�X��ǧv�^�)޺{.n�+����ا���ܨ}���Ơz�&j:+v�������zZ+��+zf���h���~����i���z��w���?�����&�)ߢf

Reply via email to