mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-09-21 23:47:52 +08:00
Fix parsing of IPv6 addresses in socks proxy urls.
This commit is contained in:
@@ -172,6 +172,7 @@ Clients:
|
||||
- Fix `-f` and `-s` options in mosquitto_rr.
|
||||
- Add websockets support.
|
||||
- Using `-x` now sets the clients to use MQTT v5.0.
|
||||
- Fix parsing of IPv6 addresses in socks proxy urls.
|
||||
|
||||
Build:
|
||||
- Increased CMake minimal required version to 3.14, which is required for the
|
||||
|
||||
+74
-75
@@ -1543,11 +1543,11 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
|
||||
char *str;
|
||||
size_t i;
|
||||
char *username = NULL, *password = NULL, *host = NULL, *port = NULL;
|
||||
char *username_or_host = NULL;
|
||||
size_t start;
|
||||
size_t len;
|
||||
bool have_auth = false;
|
||||
bool in_ipv6_address = false;
|
||||
int port_int;
|
||||
char *auth_at;
|
||||
|
||||
if(!strncmp(url, "socks5h://", strlen("socks5h://"))){
|
||||
str = url + strlen("socks5h://");
|
||||
@@ -1564,66 +1564,13 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
|
||||
* socks5h://host
|
||||
*/
|
||||
|
||||
/* Parse credentials */
|
||||
start = 0;
|
||||
for(i=0; i<strlen(str); i++){
|
||||
if(str[i] == ':'){
|
||||
if(i == start){
|
||||
goto cleanup;
|
||||
}
|
||||
if(have_auth){
|
||||
/* Have already seen a @ , so this must be of form
|
||||
* socks5h://username[:password]@host:port */
|
||||
if(host){
|
||||
/* Already seen a host, must be malformed. */
|
||||
goto cleanup;
|
||||
}
|
||||
len = i-start;
|
||||
host = malloc(len + 1);
|
||||
if(!host){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(host, &(str[start]), len);
|
||||
host[len] = '\0';
|
||||
start = i+1;
|
||||
}else if(!username_or_host){
|
||||
/* Haven't seen a @ before, so must be of form
|
||||
* socks5h://host:port or
|
||||
* socks5h://username:password@host[:port] */
|
||||
len = i-start;
|
||||
username_or_host = malloc(len + 1);
|
||||
if(!username_or_host){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(username_or_host, &(str[start]), len);
|
||||
username_or_host[len] = '\0';
|
||||
start = i+1;
|
||||
}
|
||||
}else if(str[i] == '@'){
|
||||
if(i == start){
|
||||
goto cleanup;
|
||||
}
|
||||
have_auth = true;
|
||||
if(username_or_host){
|
||||
/* Must be of form socks5h://username:password@... */
|
||||
username = username_or_host;
|
||||
username_or_host = NULL;
|
||||
|
||||
len = i-start;
|
||||
password = malloc(len + 1);
|
||||
if(!password){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(password, &(str[start]), len);
|
||||
password[len] = '\0';
|
||||
start = i+1;
|
||||
}else{
|
||||
/* Haven't seen a : yet, so must be of form
|
||||
* socks5h://username@... */
|
||||
if(username){
|
||||
/* Already got a username, must be malformed. */
|
||||
auth_at = strchr(str, '@');
|
||||
if(auth_at){
|
||||
for(i=0; &str[i] != auth_at; i++){
|
||||
if(str[i] == ':'){
|
||||
if(i == start){
|
||||
goto cleanup;
|
||||
}
|
||||
len = i-start;
|
||||
@@ -1637,9 +1584,74 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
|
||||
start = i+1;
|
||||
}
|
||||
}
|
||||
if(username){
|
||||
len = i-start;
|
||||
password = malloc(len + 1);
|
||||
if(!password){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(password, &(str[start]), len);
|
||||
password[len] = '\0';
|
||||
}else{
|
||||
len = i-start;
|
||||
username = malloc(len + 1);
|
||||
if(!username){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(username, &(str[start]), len);
|
||||
username[len] = '\0';
|
||||
}
|
||||
str = auth_at + 1;
|
||||
}
|
||||
|
||||
/* Deal with remainder */
|
||||
start = 0;
|
||||
for(i=0; i<strlen(str); i++){
|
||||
if(str[i] == '['){
|
||||
in_ipv6_address = true;
|
||||
start = i+1;
|
||||
}else if(str[i] == ']'){
|
||||
in_ipv6_address = false;
|
||||
|
||||
len = i-start;
|
||||
host = malloc(len + 1);
|
||||
if(!host){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(host, &(str[start]), len);
|
||||
host[len] = '\0';
|
||||
if(str[i+1] == ':'){
|
||||
start = i+2;
|
||||
i++;
|
||||
}else{
|
||||
start = i+1;
|
||||
}
|
||||
}else if(str[i] == ':'){
|
||||
if(in_ipv6_address){
|
||||
/* Normal IPv6 separator */
|
||||
}else{
|
||||
/* host:port separator */
|
||||
|
||||
if(host){
|
||||
/* Already seen a host, must be malformed. */
|
||||
goto cleanup;
|
||||
}
|
||||
len = i-start;
|
||||
host = malloc(len + 1);
|
||||
if(!host){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(host, &(str[start]), len);
|
||||
host[len] = '\0';
|
||||
start = i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deal with remainder - either the port, or the host */
|
||||
if(i > start){
|
||||
len = i-start;
|
||||
if(host){
|
||||
@@ -1652,18 +1664,6 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
|
||||
}
|
||||
memcpy(port, &(str[start]), len);
|
||||
port[len] = '\0';
|
||||
}else if(username_or_host){
|
||||
/* Haven't seen a @ before, so must be of form
|
||||
* socks5h://host:port */
|
||||
host = username_or_host;
|
||||
username_or_host = NULL;
|
||||
port = malloc(len + 1);
|
||||
if(!port){
|
||||
err_printf(cfg, "Error: Out of memory.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(port, &(str[start]), len);
|
||||
port[len] = '\0';
|
||||
}else{
|
||||
host = malloc(len + 1);
|
||||
if(!host){
|
||||
@@ -1704,7 +1704,6 @@ static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
free(username_or_host);
|
||||
free(username);
|
||||
free(password);
|
||||
free(host);
|
||||
|
||||
@@ -372,6 +372,12 @@
|
||||
<para>If username is not given, then no authentication is
|
||||
attempted. If the port is not given, then the default
|
||||
of 1080 is used.</para>
|
||||
<para>
|
||||
If the host is given as an IPv6 address, it must be enclosed in
|
||||
square brackets, e.g. <option>socks5h://[::1]:1080</option>.
|
||||
Note that square brackets have special meaning in some shells,
|
||||
so the proxy url may need quoting in double or single quotes.
|
||||
</para>
|
||||
<para>More SOCKS versions may be available in the future,
|
||||
depending on demand, and will use different protocol
|
||||
prefixes as described in <citerefentry>
|
||||
|
||||
@@ -464,6 +464,12 @@
|
||||
<para>If username is not given, then no authentication is
|
||||
attempted. If the port is not given, then the default
|
||||
of 1080 is used.</para>
|
||||
<para>
|
||||
If the host is given as an IPv6 address, it must be enclosed in
|
||||
square brackets, e.g. <option>socks5h://[::1]:1080</option>.
|
||||
Note that square brackets have special meaning in some shells,
|
||||
so the proxy url may need quoting in double or single quotes.
|
||||
</para>
|
||||
<para>More SOCKS versions may be available in the future,
|
||||
depending on demand, and will use different protocol
|
||||
prefixes as described in <citerefentry>
|
||||
|
||||
@@ -506,6 +506,12 @@
|
||||
<para>If username is not given, then no authentication is
|
||||
attempted. If the port is not given, then the default
|
||||
of 1080 is used.</para>
|
||||
<para>
|
||||
If the host is given as an IPv6 address, it must be enclosed in
|
||||
square brackets, e.g. <option>socks5h://[::1]:1080</option>.
|
||||
Note that square brackets have special meaning in some shells,
|
||||
so the proxy url may need quoting in double or single quotes.
|
||||
</para>
|
||||
<para>More SOCKS versions may be available in the future,
|
||||
depending on demand, and will use different protocol
|
||||
prefixes as described in <citerefentry>
|
||||
|
||||
@@ -511,6 +511,12 @@
|
||||
<para>If username is not given, then no authentication is
|
||||
attempted. If the port is not given, then the default
|
||||
of 1080 is used.</para>
|
||||
<para>
|
||||
If the host is given as an IPv6 address, it must be enclosed in
|
||||
square brackets, e.g. <option>socks5h://[::1]:1080</option>.
|
||||
Note that square brackets have special meaning in some shells,
|
||||
so the proxy url may need quoting in double or single quotes.
|
||||
</para>
|
||||
<para>More SOCKS versions may be available in the future,
|
||||
depending on demand, and will use different protocol
|
||||
prefixes as described in <citerefentry>
|
||||
|
||||
Reference in New Issue
Block a user