[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ftp(1) proxy basic auth support



ftp(1) support for proxy "basic authorization".
Corrections very appreciated.

Index: src/usr.bin/ftp/fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.56
diff -u -r1.56 fetch.c
--- src/usr.bin/ftp/fetch.c	2005/08/05 21:01:53	1.56
+++ src/usr.bin/ftp/fetch.c	2005/11/11 15:50:06
@@ -51,6 +51,7 @@
 #include <sys/stat.h>
 
 #include <netinet/in.h>
+#include <resolv.h>
 
 #include <arpa/ftp.h>
 #include <arpa/inet.h>
@@ -81,6 +82,7 @@
 #define	FILE_URL	"file:"		/* file URL prefix */
 #define FTP_PROXY	"ftp_proxy"	/* env var with ftp proxy location */
 #define HTTP_PROXY	"http_proxy"	/* env var with http proxy location */
+#define PROXY_AUTH_HEADER	"Proxy-Authorization: Basic"	/* proxy authorization header */
 
 
 #define EMPTYSTRING(x)	((x) == NULL || (*(x) == '\0'))
@@ -105,6 +107,7 @@
 	int error, i, isftpurl = 0, isfileurl = 0, isredirect = 0, rval = -1;
 	struct addrinfo hints, *res0, *res;
 	const char * volatile savefile;
+	char *proxyauth, *b64_proxyauth;
 	char * volatile proxy = NULL;
 	volatile int s = -1, out;
 	volatile sig_t oldintr;
@@ -173,6 +176,34 @@
 			warnx("Malformed proxy URL: %s", proxyenv);
 			goto cleanup_url_get;
 		}
+
+		proxyauth = strdup(host);
+		if (proxyauth == NULL)
+			errx(1, "Can't allocate memory for proxy URL.");
+
+		/* searching for authorization creditial before last '@' if any */
+		hosttail = strrchr(proxyauth, '@');
+		if (hosttail != NULL) {
+			*hosttail++ = '\0';
+			host = hosttail;
+			if (EMPTYSTRING(proxyauth)) {
+				warnx("Malformed proxy authorization creditials.");
+				goto cleanup_url_get;
+			}
+		} else
+			proxyauth = NULL;
+
+		if (proxyauth) {
+			/* encoding creditials to base64 */
+			b64_proxyauth = (char *)malloc(((strlen(proxyauth) + 2) * 4 / 3) + 1);
+			if (b64_proxyauth == NULL)
+				errx(1, "Can't allocate memory for proxy authorization.");
+
+			if (b64_ntop(proxyauth, strlen(proxyauth), b64_proxyauth, 
+			    ((strlen(proxyauth) + 2) * 4 / 3) + 1)  == -1)
+				errx(1, "b64_ntop: error encoding base64!");
+		}
+
 		*--path = '/';			/* add / back to real path */
 		path = strchr(host, '/');	/* remove trailing / on host */
 		if (!EMPTYSTRING(path))
@@ -346,8 +377,12 @@
 		 * Host: directive must use the destination host address for
 		 * the original URI (path).  We do not attach it at this moment.
 		 */
-		fprintf(fin, "GET %s HTTP/1.0\r\n%s\r\n\r\n", path,
-		    HTTP_USER_AGENT);
+		if (proxyauth) {
+			fprintf(fin, "GET %s HTTP/1.0\r\n%s\r\n%s %s\r\n\r\n", path,
+			    HTTP_USER_AGENT, PROXY_AUTH_HEADER, b64_proxyauth);
+		} else
+			fprintf(fin, "GET %s HTTP/1.0\r\n%s\r\n\r\n", path, 
+			    HTTP_USER_AGENT);
 	} else {
 		fprintf(fin, "GET /%s HTTP/1.0\r\nHost: ", path);
 		if (strchr(host, ':')) {