aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/portsnap/phttpget
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2005-09-22 07:11:27 +0000
committerColin Percival <cperciva@FreeBSD.org>2005-09-22 07:11:27 +0000
commit31c06b3f09ecbe8f11c7fcc0c507a91bd9d10c41 (patch)
treeb1a3993056fa0a56fc9367cf6bf672e2d20aabf5 /usr.sbin/portsnap/phttpget
parentc82f53f61d3977665e4c37c3df1aa2cda2f8e318 (diff)
downloadsrc-31c06b3f09ecbe8f11c7fcc0c507a91bd9d10c41.tar.gz
src-31c06b3f09ecbe8f11c7fcc0c507a91bd9d10c41.zip
Add HTTP proxy authentication, via the HTTP_PROXY_AUTH environment
variable. Tested by: Emil Mikulic X-MFC-After: 6.0-RELEASE
Notes
Notes: svn path=/head/; revision=150461
Diffstat (limited to 'usr.sbin/portsnap/phttpget')
-rw-r--r--usr.sbin/portsnap/phttpget/phttpget.c102
1 files changed, 101 insertions, 1 deletions
diff --git a/usr.sbin/portsnap/phttpget/phttpget.c b/usr.sbin/portsnap/phttpget/phttpget.c
index 9f8e3b9cab9d..91f2e614071b 100644
--- a/usr.sbin/portsnap/phttpget/phttpget.c
+++ b/usr.sbin/portsnap/phttpget/phttpget.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -44,8 +45,10 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
static const char * env_HTTP_PROXY;
+static char * env_HTTP_PROXY_AUTH;
static const char * env_HTTP_USER_AGENT;
static const char * proxyport;
+static char * proxyauth;
static struct timeval timo = { 15, 0};
@@ -57,10 +60,70 @@ usage(void)
exit(EX_USAGE);
}
+/*
+ * Base64 encode a string; the string returned, if non-NULL, is
+ * allocated using malloc() and must be freed by the caller.
+ */
+static char *
+b64enc(const char *ptext)
+{
+ static const char base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+ const char *pt;
+ char *ctext, *pc;
+ size_t ptlen, ctlen;
+ uint32_t t;
+ unsigned int j;
+
+ /*
+ * Encoded length is 4 characters per 3-byte block or partial
+ * block of plaintext, plus one byte for the terminating NUL
+ */
+ ptlen = strlen(ptext);
+ if (ptlen > ((SIZE_MAX - 1) / 4) * 3 - 2)
+ return NULL; /* Possible integer overflow */
+ ctlen = 4 * ((ptlen + 2) / 3) + 1;
+ if ((ctext = malloc(ctlen)) == NULL)
+ return NULL;
+ ctext[ctlen - 1] = 0;
+
+ /*
+ * Scan through ptext, reading up to 3 bytes from ptext and
+ * writing 4 bytes to ctext, until we run out of input.
+ */
+ for (pt = ptext, pc = ctext; ptlen; ptlen -= 3, pc += 4) {
+ /* Read 3 bytes */
+ for (t = j = 0; j < 3; j++) {
+ t <<= 8;
+ if (j < ptlen)
+ t += *pt++;
+ }
+
+ /* Write 4 bytes */
+ for (j = 0; j < 4; j++) {
+ if (j <= ptlen + 1)
+ pc[j] = base64[(t >> 18) & 0x3f];
+ else
+ pc[j] = '=';
+ t <<= 6;
+ }
+
+ /* If we're done, exit the loop */
+ if (ptlen <= 3)
+ break;
+ }
+
+ return (ctext);
+}
+
static void
readenv(void)
{
- char * p;
+ char *proxy_auth_userpass, *proxy_auth_userpass64, *p;
+ char *proxy_auth_user = NULL;
+ char *proxy_auth_pass = NULL;
env_HTTP_PROXY = getenv("HTTP_PROXY");
if (env_HTTP_PROXY != NULL) {
@@ -77,6 +140,41 @@ readenv(void)
proxyport = "3128";
}
+ env_HTTP_PROXY_AUTH = getenv("HTTP_PROXY_AUTH");
+ if ((env_HTTP_PROXY != NULL) &&
+ (env_HTTP_PROXY_AUTH != NULL) &&
+ (strncasecmp(env_HTTP_PROXY_AUTH, "basic:" , 6) == 0)) {
+ /* Ignore authentication scheme */
+ (void) strsep(&env_HTTP_PROXY_AUTH, ":");
+
+ /* Ignore realm */
+ (void) strsep(&env_HTTP_PROXY_AUTH, ":");
+
+ /* Obtain username and password */
+ proxy_auth_user = strsep(&env_HTTP_PROXY_AUTH, ":");
+ proxy_auth_pass = strsep(&env_HTTP_PROXY_AUTH, ":");
+ }
+
+ if ((proxy_auth_user != NULL) && (proxy_auth_pass != NULL)) {
+ asprintf(&proxy_auth_userpass, "%s:%s",
+ proxy_auth_user, proxy_auth_pass);
+ if (proxy_auth_userpass == NULL)
+ err(1, "asprintf");
+
+ proxy_auth_userpass64 = b64enc(proxy_auth_userpass);
+ if (proxy_auth_userpass64 == NULL)
+ err(1, "malloc");
+
+ asprintf(&proxyauth, "Proxy-Authorization: Basic %s\r\n",
+ proxy_auth_userpass64);
+ if (proxyauth == NULL)
+ err(1, "asprintf");
+
+ free(proxy_auth_userpass);
+ free(proxy_auth_userpass64);
+ } else
+ proxyauth = NULL;
+
env_HTTP_USER_AGENT = getenv("HTTP_USER_AGENT");
if (env_HTTP_USER_AGENT == NULL)
env_HTTP_USER_AGENT = "phttpget/0.1";
@@ -92,10 +190,12 @@ makerequest(char ** buf, char * path, char * server, int connclose)
"Host: %s\r\n"
"User-Agent: %s\r\n"
"%s"
+ "%s"
"\r\n",
env_HTTP_PROXY ? "http://" : "",
env_HTTP_PROXY ? server : "",
path, server, env_HTTP_USER_AGENT,
+ proxyauth ? proxyauth : "",
connclose ? "Connection: Close\r\n" : "");
if (buflen == -1)
err(1, "asprintf");