1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

proxy auth

Simplifies proxy code to use the existing libwebsocket_set_proxy.

Enables libwebsocket_set_proxy() to parse username:password@ at front of
servername in both http_proxy and info->http_proxy_address.

If given the base64 version of the credentials are sent in the CONNECT
header to the proxy.

Port is now taken from info->http_proxy_address server:port syntax, but if
a port is given in the now deprecated info->http_proxy_port (ie, is nonzero)
then it is allowed to be missed out and the info port used instead for
backwards compatibility.

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2015-11-08 10:15:01 +08:00
parent 140ac6e9cb
commit 6e405565f5
5 changed files with 53 additions and 35 deletions

View file

@ -27,11 +27,18 @@ struct libwebsocket *libwebsocket_client_connect_2(
if (context->http_proxy_port) {
plen = sprintf((char *)context->service_buffer,
"CONNECT %s:%u HTTP/1.0\x0d\x0a"
"User-agent: libwebsockets\x0d\x0a"
/*Proxy-authorization: basic aGVsbG86d29ybGQ= */
"\x0d\x0a",
"User-agent: libwebsockets\x0d\x0a",
lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
wsi->u.hdr.ah->c_port);
if (context->proxy_basic_auth_token)
plen += sprintf((char *)context->service_buffer + plen,
"Proxy-authorization: basic %s\x0d\x0a",
context->proxy_basic_auth_token);
plen += sprintf((char *)context->service_buffer + plen,
"\x0d\x0a");
ads = context->http_proxy_address;
#ifdef LWS_USE_IPV6
@ -54,7 +61,7 @@ struct libwebsocket *libwebsocket_client_connect_2(
/*
* prepare the actual connection (to the proxy, if any)
*/
lwsl_client("libwebsocket_client_connect_2: address %s\n", ads);
lwsl_client("%s: address %s\n", __func__, ads);
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {

View file

@ -176,39 +176,21 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
lws_server_get_canonical_hostname(context, info);
/* split the proxy ads:port if given */
/* either use proxy from info, or try get it from env var */
if (info->http_proxy_address) {
strncpy(context->http_proxy_address, info->http_proxy_address,
sizeof(context->http_proxy_address) - 1);
context->http_proxy_address[
sizeof(context->http_proxy_address) - 1] = '\0';
context->http_proxy_port = info->http_proxy_port;
/* override for backwards compatibility */
if (info->http_proxy_port)
context->http_proxy_port = info->http_proxy_port;
libwebsocket_set_proxy(context, info->http_proxy_address);
} else {
#ifdef LWS_HAVE_GETENV
p = getenv("http_proxy");
if (p) {
strncpy(context->http_proxy_address, p,
sizeof(context->http_proxy_address) - 1);
context->http_proxy_address[
sizeof(context->http_proxy_address) - 1] = '\0';
p = strchr(context->http_proxy_address, ':');
if (p == NULL) {
lwsl_err("http_proxy needs to be ads:port\n");
goto bail;
}
*p = '\0';
context->http_proxy_port = atoi(p + 1);
}
if (p)
libwebsocket_set_proxy(context, p);
#endif
}
if (context->http_proxy_address[0])
lwsl_notice(" Proxy %s:%u\n",
context->http_proxy_address,
context->http_proxy_port);
lwsl_notice(
" per-conn mem: %u + %u headers + protocol rx buf\n",
sizeof(struct libwebsocket),

View file

@ -672,28 +672,54 @@ LWS_VISIBLE int
libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy)
{
char *p;
char authstring[96];
if (!proxy)
return -1;
p = strchr(proxy, '@');
if (p) { /* auth is around */
if ((p - proxy) > sizeof(authstring) - 1)
goto auth_too_long;
strncpy(authstring + 6, proxy, p - proxy);
// null termination not needed on input
if (lws_b64_encode_string(authstring, (p - proxy),
context->proxy_basic_auth_token,
sizeof context->proxy_basic_auth_token) < 0)
goto auth_too_long;
lwsl_notice(" Proxy auth in use\n");
proxy = p + 1;
} else
context->proxy_basic_auth_token[0] = '\0';
strncpy(context->http_proxy_address, proxy,
sizeof(context->http_proxy_address) - 1);
context->http_proxy_address[
sizeof(context->http_proxy_address) - 1] = '\0';
p = strchr(context->http_proxy_address, ':');
if (!p) {
if (!p && !context->http_proxy_port) {
lwsl_err("http_proxy needs to be ads:port\n");
return -1;
} else {
*p = '\0';
context->http_proxy_port = atoi(p + 1);
}
*p = '\0';
context->http_proxy_port = atoi(p + 1);
lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address,
context->http_proxy_port);
return 0;
auth_too_long:
lwsl_err("proxy auth too long\n");
return -1;
}
/**

View file

@ -1047,7 +1047,9 @@ struct libwebsocket_extension {
* @ssl_cipher_list: List of valid ciphers to use (eg,
* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
* or you can leave it as NULL to get "DEFAULT"
* @http_proxy_address: If non-NULL, attempts to proxy via the given address
* @http_proxy_address: If non-NULL, attempts to proxy via the given address.
* If proxy auth is required, use format
* "username:password@server:port"
* @http_proxy_port: If http_proxy_address was non-NULL, uses this port at the address
* @gid: group id to change to after setting listen socket, or -1.
* @uid: user id to change to after setting listen socket, or -1.

View file

@ -452,6 +452,7 @@ struct libwebsocket_context {
const char *iface;
char http_proxy_address[128];
char canonical_hostname[128];
char proxy_basic_auth_token[128];
unsigned int http_proxy_port;
unsigned int options;
time_t last_timeout_check_s;