about summary refs log tree commit diff stats
path: root/WWW/Library/Implementation/HTTP.c
diff options
context:
space:
mode:
Diffstat (limited to 'WWW/Library/Implementation/HTTP.c')
-rw-r--r--WWW/Library/Implementation/HTTP.c186
1 files changed, 150 insertions, 36 deletions
diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c
index e78870d6..e617b9c8 100644
--- a/WWW/Library/Implementation/HTTP.c
+++ b/WWW/Library/Implementation/HTTP.c
@@ -3,6 +3,7 @@
 ** Modified:
 ** 27 Jan 1994  PDM  Added Ari Luotonen's Fix for Reload when using proxy
 **                   servers.
+** 28 Apr 1997  AJL,FM Do Proxy Authorisation.
 */
 
 #include "HTUtils.h"
@@ -50,6 +51,7 @@ extern BOOL LYNoFromHeader;	/* Never send From header? */
 extern BOOL LYSetCookies;	/* Act on Set-Cookie headers? */
 
 extern BOOL using_proxy;	/* Are we using an HTTP gateway? */
+PUBLIC BOOL auth_proxy = NO;	/* Generate a proxy authentication. - AJL */
 PUBLIC BOOL reloading = FALSE;	/* Reloading => send no-cache pragma to proxy */
 PUBLIC char * redirecting_url = NULL;	    /* Location: value. */
 PUBLIC BOOL permanent_redirection = FALSE;  /* Got 301 status? */
@@ -391,37 +393,94 @@ try_again:
 	}
 
 	/*
-	**  Add 'Cookie:' header, if applicable.
+	**  Add Authorization, Proxy-Authorization,
+	**  and/or Cookie headers, if applicable.
 	*/
 	if (using_proxy) {
 	    /*
-	    **  If it's not an HTTP or HTTPS document being proxied,
-	    **  forget about cookies.
+	    **  If we are using a proxy, first determine if
+	    **  we should include an Authorization header
+	    **  and/or Cookie header for the ultimate target
+	    **  of this request. - FM & AJL
 	    */
-	    if (!strncmp(docname, "http", 4)) {
-		char *host2 = NULL, *path2 = NULL;
-		int port = (strncmp(docname, "https", 5) ?
-					       HTTP_PORT : HTTPS_PORT);
-
-		host2 = HTParse(docname, "", PARSE_HOST);
-		path2 = HTParse(docname, "", PARSE_PATH|PARSE_PUNCTUATION);
-		if (host2) {
-		    if ((colon = strchr(host2, ':')) != NULL) {
-		        /*
-			**  Use non-default port number.
-			*/
-		        *colon = '\0';
-			colon++;
-			port = atoi(colon);
-		    }
+	    char *host2 = NULL, *path2 = NULL;
+	    int port2 = (strncmp(docname, "https", 5) ?
+					   HTTP_PORT : HTTPS_PORT);
+	    host2 = HTParse(docname, "", PARSE_HOST);
+	    path2 = HTParse(docname, "", PARSE_PATH|PARSE_PUNCTUATION);
+	    if (host2) {
+		if ((colon = strchr(host2, ':')) != NULL) {
+		    /* Use non-default port number */
+		    *colon = '\0';
+		    colon++;
+		    port2 = atoi(colon);
+		}
+	    }
+	    /*
+	    **  This composeAuth() does file access, i.e., for
+	    **  the ultimate target of the request. - AJL
+	    */
+	    auth_proxy = NO;
+	    if ((auth = HTAA_composeAuth(host2, port2, path2)) != NULL &&
+		*auth != '\0') {
+		/*
+		**  If auth is not NULL nor zero-length, it's
+		**  an Authorization header to be included. - FM
+		*/ 
+		sprintf(line, "%s%c%c", auth, CR, LF);
+		StrAllocCat(command, line);
+		if (TRACE)
+		    fprintf(stderr, "HTTP: Sending authorization: %s\n", auth);
+	    } else if (auth && *auth == '\0') {
+		/*
+		**  If auth is a zero-length string, the user either
+		**  cancelled or goofed at the username and password
+		**  prompt. - FM
+		*/
+		if (!(traversal || dump_output_immediately) &&
+			HTConfirm(
+			    "Proceed without a username and password?")) {
+		    show_401 = TRUE;
+		} else {
+		    if (traversal || dump_output_immediately)
+			HTAlert(
+			    "Can't proceed without a username and password.");
+		    FREE(command);
+		    FREE(hostname);
+		    FREE(docname);
+		    FREE(host2);
+		    FREE(path2);
+		    status = HT_NOT_LOADED;
+		    goto done;
 		}
-		cookie = LYCookie(host2, path2, port, secure);
-		FREE(host2);
-		FREE(path2);
+	    } else {
+		if (TRACE)
+		    fprintf(stderr,
+		    	    "HTTP: Not sending authorization (yet)\n");
+	    }
+	    /*
+	    **  Add 'Cookie:' header, if it's HTTP or HTTPS
+	    **  document being proxied.
+	    */
+	    if (!strncmp(docname, "http", 4)) {
+		cookie = LYCookie(host2, path2, port2, secure);
 	    }
+	    FREE(host2);
+	    FREE(path2);
+	    /*
+	    **  The next composeAuth() will be for the proxy. - AJL
+	    */
+	    auth_proxy = YES;
 	} else {
+	    /*
+	    **  Add cookie for a non-proxied request. - FM
+	    */
 	    cookie = LYCookie(hostname, abspath, portnumber, secure);
+	    auth_proxy = NO;
 	}
+	/*
+	**  If we do have a cookie set, add it to the request buffer. - FM
+	*/
 	if (cookie != NULL) {
 	    if (*cookie != '\0') {
 	        StrAllocCat(command, "Cookie: ");
@@ -434,16 +493,29 @@ try_again:
 	}
 	FREE(abspath);
 
-        if ((auth = HTAA_composeAuth(hostname, portnumber, docname)) != NULL &&
+	/*
+	**  If we are using a proxy, auth_proxy should be YES, and
+	**  we check here whether we want a Proxy-Authorization header
+	**  for it.  If we are not using a proxy, auth_proxy should
+	**  still be NO, and we check here for whether we want an
+	**  Authorization header. - FM & AJL
+	*/
+        if ((auth = HTAA_composeAuth(hostname,
+				     portnumber, docname)) != NULL &&
 	    *auth != '\0') {
 	    /*
 	    **  If auth is not NULL nor zero-length, it's
-	    **  an Authorization header to be included. - FM
+	    **  an Authorization or Proxy-Authorization
+	    **  header to be included. - FM
 	    */ 
             sprintf(line, "%s%c%c", auth, CR, LF);
             StrAllocCat(command, line);
 	    if (TRACE)
-                fprintf(stderr, "HTTP: Sending authorization: %s\n", auth);
+                fprintf(stderr,
+			(using_proxy ?
+			 "HTTP: Sending proxy authorization: %s\n" :
+			 "HTTP: Sending authorization: %s\n"),
+			auth);
 	} else if (auth && *auth == '\0') {
 	    /*
 	    **  If auth is a zero-length string, the user either
@@ -464,7 +536,10 @@ try_again:
 	    }
         } else {
 	    if (TRACE)
-                fprintf(stderr, "HTTP: Not sending authorization (yet)\n");
+                fprintf(stderr,
+			(using_proxy ?
+			 "HTTP: Not sending proxy authorization (yet).\n" :
+			 "HTTP: Not sending authorization (yet).\n"));
         }
         FREE(hostname);
         FREE(docname);
@@ -1229,6 +1304,7 @@ Cookie_continuation:
 		 *  to show the 401 body or restore the current
 		 *  document. - FM
 		 */
+		auth_proxy = NO;
 		if (show_401)
 		    break;
 		if (HTAA_shouldRetryWithAuth(start_of_data, length,
@@ -1271,17 +1347,55 @@ Cookie_continuation:
 
 	      case 407:
 	        /*
-		 *  Proxy Authentication Required.  We'll handle
-		 *  Proxy-Authenticate headers and retry with a
-		 *  Proxy-Authorization header, someday, but for
-		 *  now, apologized to the user and restore the
-		 *  current document. - FM
+		 *  Authorization for proxy server required.
+		 *  If we are not in fact using a proxy, or
+		 *  show_401 is set, proceed to showing the
+		 *  407 body.  Otherwise, if we can set up
+		 *  authorization based on the Proxy-Authenticate
+		 *  header, and the user provides a username and
+		 *  password, try again.  Otherwise, check whether
+		 *  to show the 401 body or restore the current
+		 *  document. - FM & AJL
 		 */
-	        HTAlert(
-		 "Proxy Authentication Required.  Sorry, not yet supported.");
-                HTTP_NETCLOSE(s, handle);
-	        status = HT_NO_DATA;
-	        goto done;
+		if (!using_proxy || show_401)
+		    break;
+		auth_proxy = YES;
+		if (HTAA_shouldRetryWithAuth(start_of_data, length,
+					     (void *)handle, s)) {
+ 		    extern char *authentication_info[2];
+
+                    HTTP_NETCLOSE(s, handle);
+                    if (dump_output_immediately && !authentication_info[0]) {
+                        fprintf(stderr,
+		      		"HTTP: Proxy authorization required.\n");
+                        fprintf(stderr,
+		      		"       Use the -auth=id:pw parameter.\n");
+                        status = HT_NO_DATA;
+                        goto clean_up;
+                    }
+
+                    if (TRACE) 
+                        fprintf(stderr, "%s %d %s\n",
+                              "HTTP: close socket", s,
+                              "to retry with Proxy Authorization");
+
+                    _HTProgress (
+		    	"Retrying with proxy authorization information.");
+		    FREE(line_buffer);
+		    FREE(line_kept_clean);
+                    goto try_again;
+                    break;
+		} else if (!(traversal || dump_output_immediately) &&
+		           HTConfirm("Show the 407 message body?")) {
+		    break;
+                } else {
+		    if (traversal || dump_output_immediately)
+		        HTAlert(
+	"Can't retry with proxy authorization!  Contact the server's WebMaster.");
+		    HTTP_NETCLOSE(s, handle);
+                    status = -1;
+                    goto clean_up;
+		}
 		break;
 
 	      case 408: