From 4366418aeb146a966e532101e2e68dad7ed2289d Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 13:01:02 -0500
Subject: [PATCH 1/9] remove extraneous parens and clang warning on osx

---
 corkscrew.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/corkscrew.c b/corkscrew.c
index ebd798b..4af977d 100644
--- a/corkscrew.c
+++ b/corkscrew.c
@@ -184,7 +184,7 @@ char *argv[];
 
 	port = 80;
 
-	if ((argc == 5) || (argc == 6)) {
+	if (argc == 5 || argc == 6) {
 		if (argc == 5) {
 			host = argv[1];
 			port = atoi(argv[2]);
@@ -192,7 +192,7 @@ char *argv[];
 			destport = argv[4];
 			up = getenv("CORKSCREW_AUTH");
 		}
-		if ((argc == 6)) {
+		if (argc == 6) {
 			host = argv[1];
 			port = atoi(argv[2]);
 			desthost = argv[3];

From d9d252c7ff8d2d6530a3fa0639c51a9babad65b6 Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 13:01:25 -0500
Subject: [PATCH 2/9] ignore vim-generated swapfiles

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 33eda18..58cb08f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,5 @@ stamp-h1
 # binaries
 corkscrew
 *.o
+.*.swp
+.*.swo

From fffcd93d13917a35b9ab3dd3718030eb9efc517b Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 13:44:18 -0500
Subject: [PATCH 3/9] remove memleak on base64 encode

---
 corkscrew.c | 118 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 78 insertions(+), 40 deletions(-)

diff --git a/corkscrew.c b/corkscrew.c
index 4af977d..0377c19 100644
--- a/corkscrew.c
+++ b/corkscrew.c
@@ -43,47 +43,55 @@ char linefeed[] = "\r\n\r\n"; /* it is better and tested with oops & squid */
 
 const static char base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-/* the output will be allocated automagically */
 #ifdef ANSI_FUNC
-char *base64_encode (char *in)
+int base64_encode (char *out, char *in, size_t *outlen, size_t *encoded_len)
 #else
-char * base64_encode (in)
+int base64_encode (out, in, outlen, encoded_len)
+char *out;
 char *in;
+size_t *outlen;
+size_t *encoded_len;
 #endif
 {
 	char *src, *end;
-	char *buf, *ret;
+	int ret;
+	size_t outlen_min;
 
 	unsigned int tmp;
 
-	int i,len;
+	int i,inlen;
 
-	len = strlen(in);
-	if (!in)
-		return NULL;
-	else
-		len = strlen(in);
+	if (!in || !out || !outlen || !*outlen) {
+		return -1; // bad input
+	}
+	else {
+		inlen = strlen(in);
+	}
 
-	end = in + len;
+	end = in + inlen;
 
-	buf = malloc(4 * ((len + 2) / 3) + 1);
-	if (!buf)
-		return NULL;
-	ret = buf;
+	// base64 output always larger than the input by a factor of 2/3
+	outlen_min =  4 * ((inlen + 2) / 3) + 1;
+	if (*outlen < outlen_min) {
+		*outlen = outlen_min;
+		out = realloc(out, outlen_min);
+	}
 
+	ret = 0;
+	memset(out, 0, *outlen);
 
 	for (src = in; src < end - 3;) {
 		tmp = *src++ << 24;
 		tmp |= *src++ << 16;
 		tmp |= *src++ << 8;
 
-		*buf++ = base64[tmp >> 26];
+		*out++ = base64[tmp >> 26];
 		tmp <<= 6;
-		*buf++ = base64[tmp >> 26];
+		*out++ = base64[tmp >> 26];
 		tmp <<= 6;
-		*buf++ = base64[tmp >> 26];
+		*out++ = base64[tmp >> 26];
 		tmp <<= 6;
-		*buf++ = base64[tmp >> 26];
+		*out++ = base64[tmp >> 26];
 	}
 
 	tmp = 0;
@@ -92,32 +100,32 @@ char *in;
 
 	switch (i) {
 		case 3:
-			*buf++ = base64[tmp >> 26];
+			*out++ = base64[tmp >> 26];
 			tmp <<= 6;
-			*buf++ = base64[tmp >> 26];
+			*out++ = base64[tmp >> 26];
 			tmp <<= 6;
-			*buf++ = base64[tmp >> 26];
+			*out++ = base64[tmp >> 26];
 			tmp <<= 6;
-			*buf++ = base64[tmp >> 26];
+			*out++ = base64[tmp >> 26];
 		break;
 		case 2:
-			*buf++ = base64[tmp >> 26];
+			*out++ = base64[tmp >> 26];
 			tmp <<= 6;
-			*buf++ = base64[tmp >> 26];
+			*out++ = base64[tmp >> 26];
 			tmp <<= 6;
-			*buf++ = base64[tmp >> 26];
-			*buf++ = '=';
+			*out++ = base64[tmp >> 26];
+			*out++ = '=';
 		break;
 		case 1:
-			*buf++ = base64[tmp >> 26];
+			*out++ = base64[tmp >> 26];
 			tmp <<= 6;
-			*buf++ = base64[tmp >> 26];
-			*buf++ = '=';
-			*buf++ = '=';
+			*out++ = base64[tmp >> 26];
+			*out++ = '=';
+			*out++ = '=';
 		break;
 	}
 
-	*buf = 0;
+	*encoded_len = strlen(out);
 	return ret;
 }
 
@@ -181,9 +189,17 @@ char *argv[];
 	struct timeval tv;
 	ssize_t len;
 	FILE *fp;
+    int exit_code = 0;
+	char *b64_buf;
+	size_t b64_buf_len;
 
 	port = 80;
 
+	// start with a reasonable guess, 
+	// the base64_encode function will resize if necessary
+	b64_buf_len = 1024;
+	b64_buf = malloc(b64_buf_len);
+
 	if (argc == 5 || argc == 6) {
 		if (argc == 5) {
 			host = argv[1];
@@ -200,11 +216,13 @@ char *argv[];
 			fp = fopen(argv[5], "r");
 			if (fp == NULL) {
 				fprintf(stderr, "Error opening %s: %s\n", argv[5], strerror(errno));
-				exit(-1);
+				exit_code = -1;
+				goto CLEANUP;
 			} else {
 				if (!fscanf(fp, "%4095s", line)) {
 					fprintf(stderr, "Error reading auth file's content\n");
-					exit(-1);
+					exit_code = -1;
+					goto CLEANUP;
 				}
 
 				up = line;
@@ -213,7 +231,8 @@ char *argv[];
 		}
 	} else {
 		usage();
-		exit(-1);
+		exit_code = -1;
+		goto CLEANUP;
 	}
 
 	strncpy(uri, "CONNECT ", sizeof(uri));
@@ -222,15 +241,25 @@ char *argv[];
 	strncat(uri, destport, sizeof(uri) - strlen(uri) - 1);
 	strncat(uri, " HTTP/1.0", sizeof(uri) - strlen(uri) - 1);
 	if (up != NULL) {
-		strncat(uri, "\nProxy-Authorization: Basic ", sizeof(uri) - strlen(uri) - 1);
-		strncat(uri, base64_encode(up), sizeof(uri) - strlen(uri) - 1);
+		size_t encoded_len = 0;
+		int encode_result = base64_encode(up, b64_buf, &b64_buf_len, &encoded_len);
+		if (0 == encode_result && encoded_len > 0) {
+			strncat(uri, "\nProxy-Authorization: Basic ", sizeof(uri) - strlen(uri) - 1);
+			strncat(uri, b64_buf, encoded_len);
+		}
+		else {
+			exit_code = 1;
+			fprintf(stderr, "ERROR: base64 encoding failed");
+			goto CLEANUP;
+		}
 	}
 	strncat(uri, linefeed, sizeof(uri) - strlen(uri) - 1);
 
 	csock = sock_connect(host, port);
 	if(csock == -1) {
 		fprintf(stderr, "Couldn't establish connection to proxy: %s\n", strerror(errno));
-		exit(-1);
+		exit_code = -1;
+		goto CLEANUP;
 	}
 
 	sent = 0;
@@ -263,7 +292,8 @@ char *argv[];
 						if ((strncmp(version,"HTTP/",5) == 0) && (code >= 407)) {
 						}
 						fprintf(stderr, "Proxy could not open connnection to %s: %s\n", desthost, descr);
-						exit(-1);
+						exit_code = -1;
+						goto CLEANUP;
 					}
 				}
 			}
@@ -290,5 +320,13 @@ char *argv[];
 			}
 		}
 	}
-	exit(0);
+CLEANUP:
+	if (csock > 2) {
+		// close the socket
+		close(csock);
+	}
+	if (b64_buf) {
+		free(b64_buf);
+	}
+	exit(exit_code);
 }

From df9082168552bb344f9a3d14b0e0386dfeb31bba Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 13:48:03 -0500
Subject: [PATCH 4/9] add newline to error msg

---
 corkscrew.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/corkscrew.c b/corkscrew.c
index 0377c19..fe60b07 100644
--- a/corkscrew.c
+++ b/corkscrew.c
@@ -249,7 +249,7 @@ char *argv[];
 		}
 		else {
 			exit_code = 1;
-			fprintf(stderr, "ERROR: base64 encoding failed");
+			fprintf(stderr, "ERROR: base64 encoding failed\n");
 			goto CLEANUP;
 		}
 	}

From 864234d138a0505a6647eedc38c5f8a948049b95 Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 14:50:46 -0500
Subject: [PATCH 5/9] make base64 output buffer be caller-allocated and fix
 memory leak

---
 corkscrew.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/corkscrew.c b/corkscrew.c
index fe60b07..716560a 100644
--- a/corkscrew.c
+++ b/corkscrew.c
@@ -44,16 +44,16 @@ char linefeed[] = "\r\n\r\n"; /* it is better and tested with oops & squid */
 const static char base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 #ifdef ANSI_FUNC
-int base64_encode (char *out, char *in, size_t *outlen, size_t *encoded_len)
+int base64_encode (char **outp, char *in, size_t *outlen, size_t *encoded_len)
 #else
-int base64_encode (out, in, outlen, encoded_len)
-char *out;
+int base64_encode (outp, in, outlen, encoded_len)
+char **outp;
 char *in;
 size_t *outlen;
 size_t *encoded_len;
 #endif
 {
-	char *src, *end;
+	char *src, *end, *out;
 	int ret;
 	size_t outlen_min;
 
@@ -61,6 +61,7 @@ size_t *encoded_len;
 
 	int i,inlen;
 
+    out = *outp;
 	if (!in || !out || !outlen || !*outlen) {
 		return -1; // bad input
 	}
@@ -74,7 +75,7 @@ size_t *encoded_len;
 	outlen_min =  4 * ((inlen + 2) / 3) + 1;
 	if (*outlen < outlen_min) {
 		*outlen = outlen_min;
-		out = realloc(out, outlen_min);
+		*outp = realloc(*outp, outlen_min);
 	}
 
 	ret = 0;
@@ -125,7 +126,7 @@ size_t *encoded_len;
 		break;
 	}
 
-	*encoded_len = strlen(out);
+	*encoded_len = strlen(*outp);
 	return ret;
 }
 
@@ -242,7 +243,7 @@ char *argv[];
 	strncat(uri, " HTTP/1.0", sizeof(uri) - strlen(uri) - 1);
 	if (up != NULL) {
 		size_t encoded_len = 0;
-		int encode_result = base64_encode(up, b64_buf, &b64_buf_len, &encoded_len);
+		int encode_result = base64_encode(&b64_buf, up, &b64_buf_len, &encoded_len);
 		if (0 == encode_result && encoded_len > 0) {
 			strncat(uri, "\nProxy-Authorization: Basic ", sizeof(uri) - strlen(uri) - 1);
 			strncat(uri, b64_buf, encoded_len);

From 3e89cbd045d9d04525aeadc50120beaf57beba70 Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 14:52:10 -0500
Subject: [PATCH 6/9] add self to AUTHORS

---
 AUTHORS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/AUTHORS b/AUTHORS
index 4967a7a..8a3999e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,3 +1,4 @@
 Pat Padgett <agroman@agroman.net>
 Bryan Chan <bryanpkc@gmail.com>
 Rémy Sanchez <remy@delos.ltd>
+Chad S. Lauritsen <csl4jc@gmail.com>

From 3c179432f10f6abd48e77238dd86adb4080d9b3d Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 15:25:02 -0500
Subject: [PATCH 7/9] fix uninitialized buffer

---
 corkscrew.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/corkscrew.c b/corkscrew.c
index 716560a..195d5ba 100644
--- a/corkscrew.c
+++ b/corkscrew.c
@@ -286,6 +286,7 @@ char *argv[];
 				if (len<=0)
 					break;
 				else {
+					memset(descr, 0, sizeof(descr));
 					sscanf(buffer,"%s%d%[^\n]",version,&code,descr);
 					if ((strncmp(version,"HTTP/",5) == 0) && (code >= 200) && (code < 300))
 						setup = 1;

From ed075bd3f1add32872d4b8c2f184157051e20c58 Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 16:00:38 -0500
Subject: [PATCH 8/9] fix initialization warning, and remove changes submitted
 in #4

---
 corkscrew.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/corkscrew.c b/corkscrew.c
index 195d5ba..a1f2d49 100644
--- a/corkscrew.c
+++ b/corkscrew.c
@@ -195,13 +195,14 @@ char *argv[];
 	size_t b64_buf_len;
 
 	port = 80;
+	csock = -1;
 
 	// start with a reasonable guess, 
 	// the base64_encode function will resize if necessary
 	b64_buf_len = 1024;
 	b64_buf = malloc(b64_buf_len);
 
-	if (argc == 5 || argc == 6) {
+	if ((argc == 5) || (argc == 6)) {
 		if (argc == 5) {
 			host = argv[1];
 			port = atoi(argv[2]);
@@ -209,7 +210,7 @@ char *argv[];
 			destport = argv[4];
 			up = getenv("CORKSCREW_AUTH");
 		}
-		if (argc == 6) {
+		if ((argc == 6)) {
 			host = argv[1];
 			port = atoi(argv[2]);
 			desthost = argv[3];
@@ -286,7 +287,6 @@ char *argv[];
 				if (len<=0)
 					break;
 				else {
-					memset(descr, 0, sizeof(descr));
 					sscanf(buffer,"%s%d%[^\n]",version,&code,descr);
 					if ((strncmp(version,"HTTP/",5) == 0) && (code >= 200) && (code < 300))
 						setup = 1;

From 782375e97e8385339e6dd03e9ddb6391a0bc2281 Mon Sep 17 00:00:00 2001
From: "Chad S. Lauritsen" <chad.s.lauritsen@sherwin.com>
Date: Mon, 3 Dec 2018 16:03:31 -0500
Subject: [PATCH 9/9] remove changes submitted in #4

---
 .gitignore | 2 --
 AUTHORS    | 1 -
 2 files changed, 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index 58cb08f..33eda18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,5 +20,3 @@ stamp-h1
 # binaries
 corkscrew
 *.o
-.*.swp
-.*.swo
diff --git a/AUTHORS b/AUTHORS
index 8a3999e..4967a7a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,4 +1,3 @@
 Pat Padgett <agroman@agroman.net>
 Bryan Chan <bryanpkc@gmail.com>
 Rémy Sanchez <remy@delos.ltd>
-Chad S. Lauritsen <csl4jc@gmail.com>