From 4366418aeb146a966e532101e2e68dad7ed2289d Mon Sep 17 00:00:00 2001 From: "Chad S. Lauritsen" 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" 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" 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" 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" 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" 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 Bryan Chan Rémy Sanchez +Chad S. Lauritsen From 3c179432f10f6abd48e77238dd86adb4080d9b3d Mon Sep 17 00:00:00 2001 From: "Chad S. Lauritsen" 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" 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" 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 Bryan Chan Rémy Sanchez -Chad S. Lauritsen