ae778f53b4
Possibly fix problem you told me OBS-URL: https://build.opensuse.org/request/show/204955 OBS-URL: https://build.opensuse.org/package/show/server:proxy/cntlm?expand=0&rev=21
367 lines
11 KiB
Diff
367 lines
11 KiB
Diff
Index: utils.c
|
|
===================================================================
|
|
--- utils.c (revision 305)
|
|
+++ utils.c (revision 306)
|
|
@@ -508,6 +508,7 @@
|
|
data->body_len = 0;
|
|
data->empty = 1;
|
|
data->port = 0;
|
|
+ data->http_version = -1;
|
|
data->headers = NULL;
|
|
data->method = NULL;
|
|
data->url = NULL;
|
|
@@ -535,6 +536,7 @@
|
|
dst->body_len = src->body_len;
|
|
dst->empty = src->empty;
|
|
dst->port = src->port;
|
|
+ dst->http_version = src->http_version;
|
|
|
|
if (src->headers)
|
|
dst->headers = hlist_dup(src->headers);
|
|
@@ -584,6 +586,7 @@
|
|
data->body_len = 0;
|
|
data->empty = 1;
|
|
data->port = 0;
|
|
+ data->http_version = -1;
|
|
|
|
if (data->headers) hlist_free(data->headers);
|
|
if (data->method) free(data->method);
|
|
@@ -623,6 +626,7 @@
|
|
if (data->http) free(data->http);
|
|
if (data->msg) free(data->msg);
|
|
if (data->body) free(data->body);
|
|
+ memset(data, 0, sizeof(struct rr_data_s));
|
|
free(data);
|
|
}
|
|
|
|
Index: forward.c
|
|
===================================================================
|
|
--- forward.c (revision 305)
|
|
+++ forward.c (revision 306)
|
|
@@ -188,6 +188,7 @@
|
|
|
|
if (debug) {
|
|
printf("\nSending PROXY auth request...\n");
|
|
+ printf("HEAD: %s %s %s\n", auth->method, auth->url, auth->http);
|
|
hlist_dump(auth->headers);
|
|
}
|
|
|
|
@@ -316,7 +317,7 @@
|
|
* request is NOT freed
|
|
*/
|
|
rr_data_t forward_request(void *thread_data, rr_data_t request) {
|
|
- int i, w, loop, plugin, retry = 0;
|
|
+ int i, loop, plugin, retry = 0;
|
|
int *rsocket[2], *wsocket[2];
|
|
rr_data_t data[2], rc = NULL;
|
|
hlist_t tl;
|
|
@@ -368,7 +369,7 @@
|
|
sd = proxy_connect(tcreds);
|
|
if (sd <= 0) {
|
|
tmp = gen_502_page(request->http, "Parent proxy unreacheable");
|
|
- w = write(cd, tmp, strlen(tmp));
|
|
+ i = write(cd, tmp, strlen(tmp));
|
|
free(tmp);
|
|
rc = (void *)-1;
|
|
goto bailout;
|
|
@@ -446,7 +447,9 @@
|
|
&& strcasecmp(hostname, data[0]->hostname)) {
|
|
if (debug)
|
|
printf("\n******* F RETURN: %s *******\n", data[0]->url);
|
|
- if (authok)
|
|
+ if (authok && data[0]->http_version >= 11
|
|
+ && (hlist_subcmp(data[0]->headers, "Proxy-Connection", "keep-alive")
|
|
+ || hlist_subcmp(data[0]->headers, "Connection", "keep-alive")))
|
|
proxy_alive = 1;
|
|
|
|
rc = dup_rr_data(data[0]);
|
|
@@ -465,7 +468,7 @@
|
|
/*
|
|
* Modify request headers.
|
|
*
|
|
- * Try to request keep-alive for every connection. We keep them in a pool
|
|
+ * Try to request keep-alive for every client supporting HTTP/1.1+. We keep them in a pool
|
|
* for future reuse.
|
|
*/
|
|
if (loop == 0 && data[0]->req) {
|
|
@@ -474,13 +477,14 @@
|
|
*/
|
|
if (http_parse_basic(data[loop]->headers, "Proxy-Authorization", tcreds) > 0) {
|
|
if (debug)
|
|
- printf("NTLM-to-basic: Credentials parsed: %s\\%s at %s\n", tcreds->domain, tcreds->user, tcreds->workstation);
|
|
+ printf("NTLM-to-basic: Credentials parsed: %s\\%s at %s\n",
|
|
+ tcreds->domain, tcreds->user, tcreds->workstation);
|
|
} else if (ntlmbasic) {
|
|
if (debug)
|
|
printf("NTLM-to-basic: Returning client auth request.\n");
|
|
|
|
tmp = gen_407_page(data[loop]->http);
|
|
- w = write(cd, tmp, strlen(tmp));
|
|
+ i = write(cd, tmp, strlen(tmp));
|
|
free(tmp);
|
|
|
|
free_rr_data(data[0]);
|
|
@@ -499,13 +503,14 @@
|
|
}
|
|
|
|
/*
|
|
- * Also remove runaway P-A from the client (e.g. Basic from N-t-B), which might
|
|
- * cause some ISAs to deny us, even if the connection is already auth'd.
|
|
+ * Force proxy keep-alive if the client can handle it (HTTP >= 1.1)
|
|
*/
|
|
- data[0]->headers = hlist_mod(data[0]->headers, "Proxy-Connection", "keep-alive", 1);
|
|
+ if (data[0]->http_version >= 11)
|
|
+ data[0]->headers = hlist_mod(data[0]->headers, "Proxy-Connection", "keep-alive", 1);
|
|
|
|
/*
|
|
- * Remove all Proxy-Authorization headers from client
|
|
+ * Also remove runaway P-A from the client (e.g. Basic from N-t-B), which might
|
|
+ * cause some ISAs to deny us, even if the connection is already auth'd.
|
|
*/
|
|
while (hlist_get(data[loop]->headers, "Proxy-Authorization")) {
|
|
data[loop]->headers = hlist_del(data[loop]->headers, "Proxy-Authorization");
|
|
@@ -623,8 +628,10 @@
|
|
if (plugin & PLUG_SENDHEAD) {
|
|
if (debug) {
|
|
printf("Sending headers (%d)...\n", *wsocket[loop]);
|
|
- if (loop == 0)
|
|
+ if (loop == 0) {
|
|
+ printf("HEAD: %s %s %s\n", data[loop]->method, data[loop]->url, data[loop]->http);
|
|
hlist_dump(data[loop]->headers);
|
|
+ }
|
|
}
|
|
|
|
/*
|
|
@@ -672,8 +679,14 @@
|
|
* This way, we also tell our caller that proxy keep-alive is impossible.
|
|
*/
|
|
if (loop == 1) {
|
|
- proxy_alive = hlist_subcmp(data[loop]->headers, "Proxy-Connection", "keep-alive");
|
|
- if (!proxy_alive) {
|
|
+ proxy_alive = hlist_subcmp(data[1]->headers, "Proxy-Connection", "keep-alive")
|
|
+ && data[0]->http_version >= 11;
|
|
+ if (proxy_alive) {
|
|
+ data[1]->headers = hlist_mod(data[1]->headers, "Proxy-Connection", "keep-alive", 1);
|
|
+ data[1]->headers = hlist_mod(data[1]->headers, "Connection", "keep-alive", 1);
|
|
+ } else {
|
|
+ data[1]->headers = hlist_mod(data[1]->headers, "Proxy-Connection", "close", 1);
|
|
+ data[1]->headers = hlist_mod(data[1]->headers, "Connection", "close", 1);
|
|
if (debug)
|
|
printf("PROXY CLOSING CONNECTION\n");
|
|
rc = (void *)-1;
|
|
Index: utils.h
|
|
===================================================================
|
|
--- utils.h (revision 305)
|
|
+++ utils.h (revision 306)
|
|
@@ -89,6 +89,7 @@
|
|
int body_len;
|
|
int empty;
|
|
int port;
|
|
+ int http_version;
|
|
char *method;
|
|
char *url;
|
|
char *rel_url;
|
|
Index: http.c
|
|
===================================================================
|
|
--- http.c (revision 305)
|
|
+++ http.c (revision 306)
|
|
@@ -84,7 +84,7 @@
|
|
*/
|
|
int headers_recv(int fd, rr_data_t data) {
|
|
int i, bsize;
|
|
- int len;
|
|
+ int len, is_http = 0;
|
|
char *buf;
|
|
char *tok, *s3 = 0;
|
|
char *orig = NULL;
|
|
@@ -108,12 +108,22 @@
|
|
orig = strdup(buf);
|
|
len = strlen(buf);
|
|
tok = strtok_r(buf, " ", &s3);
|
|
- if (tok && (!strncasecmp(buf, "HTTP/", 5) || !strncasecmp(tok, "ICY", 3))) {
|
|
+ if (tok && ((is_http = !strncasecmp(tok, "HTTP/", 5)) || !strncasecmp(tok, "ICY", 3))) {
|
|
data->req = 0;
|
|
data->empty = 0;
|
|
data->http = strdup(tok);
|
|
data->msg = NULL;
|
|
|
|
+ /*
|
|
+ * Let's find out the numeric version of the HTTP version: 09, 10, 11.
|
|
+ * Set to -1 if header is misformatted.
|
|
+ */
|
|
+ if (is_http && (tok = strchr(data->http, '/')) && strlen(tok) >= 4 && isdigit(tok[1]) && isdigit(tok[3])) {
|
|
+ data->http_version = (tok[1] - 0x30) * 10 + (tok[3] - 0x30);
|
|
+ } else {
|
|
+ data->http_version = -1;
|
|
+ }
|
|
+
|
|
tok = strtok_r(NULL, " ", &s3);
|
|
if (tok) {
|
|
ccode = strdup(tok);
|
|
@@ -156,6 +166,16 @@
|
|
goto bailout;
|
|
}
|
|
|
|
+ /*
|
|
+ * Let's find out the numeric version of the HTTP version: 09, 10, 11.
|
|
+ * Set to -1 if header is misformatted.
|
|
+ */
|
|
+ if ((tok = strchr(data->http, '/')) && strlen(tok) >= 4 && isdigit(tok[1]) && isdigit(tok[3])) {
|
|
+ data->http_version = (tok[1] - 0x30) * 10 + (tok[3] - 0x30);
|
|
+ } else {
|
|
+ data->http_version = -1;
|
|
+ }
|
|
+
|
|
if ((tok = strstr(data->url, "://"))) {
|
|
tok += 3;
|
|
} else {
|
|
@@ -367,7 +387,7 @@
|
|
*/
|
|
int chunked_data_send(int dst, int src) {
|
|
char *buf;
|
|
- int bsize;
|
|
+ int bsize, len;
|
|
int i, w, csize;
|
|
|
|
char *err = NULL;
|
|
@@ -408,11 +428,14 @@
|
|
} while (csize != 0);
|
|
|
|
/* Take care of possible trailer */
|
|
+ w = len = i = 0;
|
|
do {
|
|
i = so_recvln(src, &buf, &bsize);
|
|
- if (dst >= 0 && i > 0)
|
|
- w = write(dst, buf, strlen(buf));
|
|
- } while (i > 0 && buf[0] != '\r' && buf[0] != '\n');
|
|
+ if (dst >= 0 && i > 0) {
|
|
+ len = strlen(buf);
|
|
+ w = write(dst, buf, len);
|
|
+ }
|
|
+ } while (w == len && i > 0 && buf[0] != '\r' && buf[0] != '\n');
|
|
|
|
free(buf);
|
|
return 1;
|
|
Index: direct.c
|
|
===================================================================
|
|
--- direct.c (revision 305)
|
|
+++ direct.c (revision 306)
|
|
@@ -198,6 +198,8 @@
|
|
syslog(LOG_WARNING, "Connection failed for %s:%d (%s)", request->hostname, request->port, strerror(errno));
|
|
tmp = gen_502_page(request->http, strerror(errno));
|
|
w = write(cd, tmp, strlen(tmp));
|
|
+ // We don't really care about the result - shut up GCC warning (unused-but-set-variable)
|
|
+ if (!w) w = 1;
|
|
free(tmp);
|
|
|
|
rc = (void *)-1;
|
|
@@ -282,10 +284,21 @@
|
|
data[0]->url = strdup(data[0]->rel_url);
|
|
}
|
|
|
|
- data[0]->headers = hlist_mod(data[0]->headers, "Connection", "keep-alive", 1);
|
|
- data[0]->headers = hlist_del(data[0]->headers, "Proxy-Authorization");
|
|
+ /*
|
|
+ * Force proxy keep-alive if the client can handle it (HTTP >= 1.1)
|
|
+ */
|
|
+ if (data[0]->http_version >= 11)
|
|
+ data[0]->headers = hlist_mod(data[0]->headers, "Connection", "keep-alive", 1);
|
|
|
|
/*
|
|
+ * Also remove runaway P-A from the client (e.g. Basic from N-t-B), which might
|
|
+ * cause some ISAs to deny us, even if the connection is already auth'd.
|
|
+ */
|
|
+ while (hlist_get(data[loop]->headers, "Proxy-Authorization")) {
|
|
+ data[loop]->headers = hlist_del(data[loop]->headers, "Proxy-Authorization");
|
|
+ }
|
|
+
|
|
+ /*
|
|
* Try to get auth from client if present
|
|
*/
|
|
if (http_parse_basic(data[0]->headers, "Authorization", tcreds) > 0 && debug)
|
|
@@ -373,18 +386,25 @@
|
|
*/
|
|
if (loop == 1) {
|
|
conn_alive = !hlist_subcmp(data[1]->headers, "Connection", "close")
|
|
- && http_has_body(data[0], data[1]) != -1;
|
|
+ && http_has_body(data[0], data[1]) != -1
|
|
+ && data[0]->http_version >= 11;
|
|
if (conn_alive) {
|
|
data[1]->headers = hlist_mod(data[1]->headers, "Proxy-Connection", "keep-alive", 1);
|
|
data[1]->headers = hlist_mod(data[1]->headers, "Connection", "keep-alive", 1);
|
|
} else {
|
|
data[1]->headers = hlist_mod(data[1]->headers, "Proxy-Connection", "close", 1);
|
|
+ data[1]->headers = hlist_mod(data[1]->headers, "Connection", "close", 1);
|
|
rc = (void *)-1;
|
|
}
|
|
}
|
|
|
|
- if (debug)
|
|
+ if (debug) {
|
|
printf("Sending headers (%d)...\n", *wsocket[loop]);
|
|
+ if (loop == 0) {
|
|
+ printf("HEAD: %s %s %s\n", data[loop]->method, data[loop]->url, data[loop]->http);
|
|
+ hlist_dump(data[loop]->headers);
|
|
+ }
|
|
+ }
|
|
|
|
/*
|
|
* Send headers
|
|
Index: main.c
|
|
===================================================================
|
|
--- main.c (revision 305)
|
|
+++ main.c (revision 306)
|
|
@@ -462,6 +462,8 @@
|
|
bs[0] = 5;
|
|
bs[1] = 0xFF;
|
|
w = write(cd, bs, 2);
|
|
+ // We don't really care about the result - shut up GCC warning (unused-but-set-variable)
|
|
+ if (!w) w = 1;
|
|
goto bailout;
|
|
} else {
|
|
bs[0] = 5;
|
|
@@ -1400,6 +1402,8 @@
|
|
* If we fail, exit with error.
|
|
*/
|
|
if (strlen(cpidfile)) {
|
|
+ int len;
|
|
+
|
|
umask(0);
|
|
cd = open(cpidfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
if (cd < 0) {
|
|
@@ -1409,7 +1413,11 @@
|
|
|
|
tmp = new(50);
|
|
snprintf(tmp, 50, "%d\n", getpid());
|
|
- w = write(cd, tmp, strlen(tmp));
|
|
+ w = write(cd, tmp, (len = strlen(tmp)));
|
|
+ if (w != len) {
|
|
+ syslog(LOG_ERR, "Error writing to the PID file\n");
|
|
+ myexit(1);
|
|
+ }
|
|
free(tmp);
|
|
close(cd);
|
|
}
|
|
@@ -1517,6 +1525,8 @@
|
|
inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
|
|
tmp = gen_denied_page(inet_ntoa(caddr.sin_addr));
|
|
w = write(cd, tmp, strlen(tmp));
|
|
+ // We don't really care about the result - shut up GCC warning (unused-but-set-variable)
|
|
+ if (!w) w = 1;
|
|
free(tmp);
|
|
close(cd);
|
|
continue;
|
|
Index: scanner.c
|
|
===================================================================
|
|
--- scanner.c (revision 305)
|
|
+++ scanner.c (revision 306)
|
|
@@ -153,6 +153,8 @@
|
|
tmp = new(MINIBUF_SIZE);
|
|
snprintf(tmp, MINIBUF_SIZE, "%s 200 OK\r\n", request->http);
|
|
w = write(cd, tmp, strlen(tmp));
|
|
+ // We don't really care about the result - shut up GCC warning (unused-but-set-variable)
|
|
+ if (!w) w = 1;
|
|
free(tmp);
|
|
}
|
|
|