• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include "private-lib-core.h"
26 
27 #if defined(LWS_CLIENT_HTTP_PROXYING)
28 
29 int
lws_set_proxy(struct lws_vhost * vhost,const char * proxy)30 lws_set_proxy(struct lws_vhost *vhost, const char *proxy)
31 {
32 	char authstring[96];
33 	int brackets = 0;
34 	char *p;
35 
36 	if (!proxy)
37 		return -1;
38 
39 	/* we have to deal with a possible redundant leading http:// */
40 	if (!strncmp(proxy, "http://", 7))
41 		proxy += 7;
42 
43 	p = strrchr(proxy, '@');
44 	if (p) { /* auth is around */
45 
46 		if (lws_ptr_diff_size_t(p, proxy) > sizeof(authstring) - 1)
47 			goto auth_too_long;
48 
49 		lws_strncpy(authstring, proxy, lws_ptr_diff_size_t(p, proxy) + 1);
50 		// null termination not needed on input
51 		if (lws_b64_encode_string(authstring, lws_ptr_diff(p, proxy),
52 				vhost->proxy_basic_auth_token,
53 		    sizeof vhost->proxy_basic_auth_token) < 0)
54 			goto auth_too_long;
55 
56 		lwsl_vhost_info(vhost, " Proxy auth in use");
57 
58 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
59 		proxy = p + 1;
60 #endif
61 	} else
62 		vhost->proxy_basic_auth_token[0] = '\0';
63 
64 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
65 
66 #if defined(LWS_WITH_IPV6)
67 	/*
68 	 * isolating the address / port is complicated by IPv6 overloading
69 	 * the meaning of : in the address.  The convention to solve it is to
70 	 * put [] around the ipv6 address part, eg, "[::1]:443".  This must be
71 	 * parsed to "::1" as the address and the port as 443.
72 	 *
73 	 * IPv4 addresses like myproxy:443 continue to be parsed as normal.
74 	 */
75 
76 	if (proxy[0] == '[')
77 		brackets = 1;
78 #endif
79 
80 	lws_strncpy(vhost->http.http_proxy_address, proxy + brackets,
81 		    sizeof(vhost->http.http_proxy_address));
82 
83 	p = vhost->http.http_proxy_address;
84 
85 #if defined(LWS_WITH_IPV6)
86 	if (brackets) {
87 		/* original is IPv6 format "[::1]:443" */
88 
89 		p = strchr(vhost->http.http_proxy_address, ']');
90 		if (!p) {
91 			lwsl_vhost_err(vhost, "malformed proxy '%s'", proxy);
92 
93 			return -1;
94 		}
95 		*p++ = '\0';
96 	}
97 #endif
98 
99 	p = strchr(p, ':');
100 	if (!p && !vhost->http.http_proxy_port) {
101 		lwsl_vhost_err(vhost, "http_proxy needs to be ads:port");
102 
103 		return -1;
104 	}
105 	if (p) {
106 		*p = '\0';
107 		vhost->http.http_proxy_port = (unsigned int)atoi(p + 1);
108 	}
109 
110 	lwsl_vhost_info(vhost, " Proxy %s:%u", vhost->http.http_proxy_address,
111 					    vhost->http.http_proxy_port);
112 #endif
113 
114 	return 0;
115 
116 auth_too_long:
117 	lwsl_vhost_err(vhost, "proxy auth too long");
118 
119 	return -1;
120 }
121 #endif
122