Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix memory leak #5

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
122 changes: 81 additions & 41 deletions corkscrew.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,47 +43,56 @@ 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 **outp, char *in, size_t *outlen, size_t *encoded_len)
#else
char * base64_encode (in)
int base64_encode (outp, in, outlen, encoded_len)
char **outp;
char *in;
size_t *outlen;
size_t *encoded_len;
#endif
{
char *src, *end;
char *buf, *ret;
char *src, *end, *out;
int ret;
size_t outlen_min;

unsigned int tmp;

int i,len;
int i,inlen;
bryanpkc marked this conversation as resolved.
Show resolved Hide resolved

len = strlen(in);
if (!in)
return NULL;
else
len = strlen(in);
out = *outp;
bryanpkc marked this conversation as resolved.
Show resolved Hide resolved
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;
*outp = realloc(*outp, 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;
Expand All @@ -92,32 +101,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(*outp);
return ret;
}

Expand Down Expand Up @@ -181,8 +190,17 @@ char *argv[];
struct timeval tv;
ssize_t len;
FILE *fp;
int exit_code = 0;
bryanpkc marked this conversation as resolved.
Show resolved Hide resolved
char *b64_buf;
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) {
Expand All @@ -200,11 +218,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;
Expand All @@ -213,7 +233,8 @@ char *argv[];
}
} else {
usage();
exit(-1);
exit_code = -1;
goto CLEANUP;
}

strncpy(uri, "CONNECT ", sizeof(uri));
Expand All @@ -222,15 +243,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(&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);
}
else {
exit_code = 1;
fprintf(stderr, "ERROR: base64 encoding failed\n");
bryanpkc marked this conversation as resolved.
Show resolved Hide resolved
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;
Expand Down Expand Up @@ -263,7 +294,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;
}
}
}
Expand All @@ -290,5 +322,13 @@ char *argv[];
}
}
}
exit(0);
CLEANUP:
if (csock > 2) {
bryanpkc marked this conversation as resolved.
Show resolved Hide resolved
// close the socket
close(csock);
}
if (b64_buf) {
free(b64_buf);
}
exit(exit_code);
}