Index: lib/http.c
===================================================================
--- lib/http.c	(revision 4)
+++ lib/http.c	(working copy)
@@ -677,6 +677,19 @@
   char *ptr;
   char *request;
 
+  if(!data->state.authstage) {
+    if(conn->bits.httpproxy) {
+      data->state.authstage = 407;
+      data->state.authwant = data->set.proxyauth;
+      data->state.authavail = CURLAUTH_NONE; /* nothing so far */
+    }
+    else {
+      data->state.authstage = 401;
+      data->state.authwant = data->set.httpauth;
+      data->state.authavail = CURLAUTH_NONE; /* nothing so far */
+    }
+  }
+
   if(!conn->proto.http) {
     /* Only allocate this struct if we don't already have it! */
 
@@ -722,6 +735,7 @@
 
 #ifdef GSSAPI
     if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) &&
+       data->state.authstage != 407 && /* Currently not supported */
        data->state.negotiate.context && 
        !GSS_ERROR(data->state.negotiate.status)) {
       result = Curl_output_negotiate(conn);
@@ -732,7 +746,7 @@
 #endif
 #ifdef USE_SSLEAY
     if(data->state.authwant == CURLAUTH_NTLM) {
-      result = Curl_output_ntlm(conn, FALSE);
+      result = Curl_output_ntlm(conn, data->state.authstage == 407);
       if(result)
         return result;
     }
@@ -740,6 +754,7 @@
 #endif
     {
       if((data->state.authwant == CURLAUTH_DIGEST) &&
+         data->state.authstage != 407 && /* Currently not supported */
          data->state.digest.nonce) {
         result = Curl_output_digest(conn,
                                     (unsigned char *)request,
@@ -748,6 +763,7 @@
           return result;
       }
       else if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */
+              data->state.authstage != 407 && /* Currently not supported */
               conn->bits.user_passwd &&
               !checkheaders(data, "Authorization:")) {
         result = Curl_output_basic(conn);
Index: lib/urldata.h
===================================================================
--- lib/urldata.h	(revision 4)
+++ lib/urldata.h	(working copy)
@@ -665,7 +665,12 @@
   struct negotiatedata negotiate;
 #endif
 
-  long authwant;  /* inherited from what the user set with CURLOPT_HTTPAUTH */
+  long authstage; /*   0 - authwant and authavail are still not initialized
+                     401 - web authentication is performed
+                     407 - proxy authentication is performed */
+  long authwant;  /* initially set to authentication methods requested by
+                     client (either with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH
+                     depending on authstage) */
   long authavail; /* what the server reports */
 };
 
@@ -716,6 +721,7 @@
   long use_port;     /* which port to use (when not using default) */
   char *userpwd;     /* <user:password>, if used */
   long httpauth;     /* what kind of HTTP authentication to use (bitmask) */
+  long proxyauth;    /* what kind of proxy authentication to use (bitmask) */
   char *set_range;   /* range, if used. See README for detailed specification
                         on this syntax. */
   long followlocation; /* as in HTTP Location: */
Index: lib/transfer.c
===================================================================
--- lib/transfer.c	(revision 4)
+++ lib/transfer.c	(working copy)
@@ -722,12 +722,30 @@
               if(data->set.get_filetime)
                 data->info.filetime = k->timeofdoc;
             }
-            else if(checkprefix("WWW-Authenticate:", k->p) &&
-                    (401 == k->httpcode)) {
+            else if((checkprefix("WWW-Authenticate:", k->p) &&
+                    (401 == k->httpcode)) ||
+                    (checkprefix("Proxy-authenticate:", k->p) &&
+                    (407 == k->httpcode))) {
               /*
                * This page requires authentication
                */
-              char *start = k->p+strlen("WWW-Authenticate:");
+              char *start = (k->httpcode == 407) ? 
+                            k->p+strlen("Proxy-authenticate:"): 
+                            k->p+strlen("WWW-Authenticate:");
+              /*
+               * Switch from proxy to web authentication and back if needed
+               */
+              if (k->httpcode == 407 && data->state.authstage != 407) {
+                data->state.authstage = 407;
+                data->state.authwant = data->set.proxyauth;
+                data->state.authavail = CURLAUTH_NONE;
+              }
+              
+              if (k->httpcode == 401 && data->state.authstage != 401) {
+                data->state.authstage = 401;
+                data->state.authwant = data->set.httpauth;
+                data->state.authavail = CURLAUTH_NONE;
+              }
 
               /* pass all white spaces */
               while(*start && isspace((int)*start))
@@ -752,8 +770,8 @@
               if(checkprefix("NTLM", start)) {
                 if(data->state.authwant == CURLAUTH_NTLM) {
                   /* NTLM authentication is activated */
-                  CURLntlm ntlm =
-                    Curl_input_ntlm(conn, FALSE, start);
+                  CURLntlm ntlm =
+                    Curl_input_ntlm(conn, k->httpcode == 407, start);
                   
                   if(CURLNTLM_BAD != ntlm)
                     conn->newurl = strdup(data->change.url); /* clone string */
@@ -1502,9 +1520,9 @@
   data->state.errorbuf = FALSE; /* no error has occurred */
 
   /* set preferred authentication, default to basic */
-  data->state.authwant = data->set.httpauth?data->set.httpauth:CURLAUTH_BASIC;
-  data->state.authavail = CURLAUTH_NONE; /* nothing so far */
 
+  data->state.authstage = 0; /* initialize authentication later */
+
   /* If there was a list of cookie files to read and we haven't done it before,
      do it now! */
   if(data->change.cookielist) {
Index: lib/url.c
===================================================================
--- lib/url.c	(revision 4)
+++ lib/url.c	(working copy)
@@ -303,6 +303,9 @@
 
   data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
 
+  data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic authentication */
+  data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic authentication */
+
   /* create an array with connection data struct pointers */
   data->state.numconnects = 5; /* hard-coded right now */
   data->state.connects = (struct connectdata **)
@@ -862,6 +865,26 @@
   }
   break;
   
+  case CURLOPT_PROXYAUTH:
+    /*
+     * Set HTTP Authentication type BITMASK.
+     */
+  {
+    long auth = va_arg(param, long);
+    /* switch off bits we can't support */
+#ifndef USE_SSLEAY
+    auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
+#endif
+#ifndef GSSAPI
+    auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
+#endif
+    if(!auth)
+      return CURLE_FAILED_INIT; /* no supported types left! */
+
+    data->set.proxyauth = auth;
+  }
+  break;
+
   case CURLOPT_USERPWD:
     /*
      * user:password to use in the operation
@@ -2975,7 +2998,8 @@
   /*************************************************************
    * Proxy authentication
    *************************************************************/
-  if(conn->bits.proxy_user_passwd) {
+  if(conn->bits.proxy_user_passwd && 
+     (data->set.proxyauth == CURLAUTH_BASIC)) {
     char *authorization;
     snprintf(data->state.buffer, BUFSIZE, "%s:%s",
              conn->proxyuser, conn->proxypasswd);
Index: include/curl/curl.h
===================================================================
--- include/curl/curl.h	(revision 4)
+++ include/curl/curl.h	(working copy)
@@ -669,6 +669,11 @@
      argument */
   CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
 
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(PROXYAUTH, LONG, 110),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
