mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
relay/api: fix connection to remote using an IPv6 address with square brackets (closes #2156)
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
- ruby: fix builtin functions not available ([#2109](https://github.com/weechat/weechat/issues/2109))
|
||||
- php: fix return value of function hdata_longlong
|
||||
- tcl: fix return value of function hdata_longlong ([#2119](https://github.com/weechat/weechat/issues/2119))
|
||||
- relay/api: fix connection to remote using an IPv6 address with square brackets ([#2156](https://github.com/weechat/weechat/issues/2156))
|
||||
- relay/api: allow clients without authentication when no relay password is defined and option relay.network.allow_empty_password is on ([#2158](https://github.com/weechat/weechat/issues/2158))
|
||||
- relay/api: fix connection to remote without password ([#2158](https://github.com/weechat/weechat/issues/2158))
|
||||
- relay/api: fix timezone of dates sent to clients ([#2151](https://github.com/weechat/weechat/issues/2151))
|
||||
|
||||
@@ -57,13 +57,17 @@ relay_remote_network_get_url_resource (struct t_relay_remote *remote,
|
||||
const char *resource)
|
||||
{
|
||||
char *url;
|
||||
int colon_in_address;
|
||||
|
||||
if (!remote || !remote->address || !resource || !resource[0])
|
||||
return NULL;
|
||||
|
||||
weechat_asprintf (&url, "%s://%s:%d/api/%s",
|
||||
colon_in_address = (strchr (remote->address, ':')) ? 1 : 0;
|
||||
weechat_asprintf (&url, "%s://%s%s%s:%d/api/%s",
|
||||
(remote->tls) ? "https" : "http",
|
||||
(colon_in_address) ? "[" : "",
|
||||
remote->address,
|
||||
(colon_in_address) ? "]" : "",
|
||||
remote->port,
|
||||
resource);
|
||||
|
||||
|
||||
@@ -185,7 +185,107 @@ relay_remote_name_valid (const char *name)
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if a remote URL is valid;
|
||||
* Extracts TLS, address and port from remote URL.
|
||||
*
|
||||
* If address is an IPv6 like "[::1]", the square brackets are removed.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error, invalid URL
|
||||
*/
|
||||
|
||||
int
|
||||
relay_remote_parse_url (const char *url,
|
||||
int *tls, char **address, int *port)
|
||||
{
|
||||
const char *ptr_url;
|
||||
char *pos, *str_port, *error;
|
||||
long number;
|
||||
|
||||
if (tls)
|
||||
*tls = 0;
|
||||
if (address)
|
||||
*address = NULL;
|
||||
if (port)
|
||||
*port = RELAY_REMOTE_DEFAULT_PORT;
|
||||
|
||||
if (!url || !url[0])
|
||||
return 0;
|
||||
|
||||
/* check scheme and extract TLS flag */
|
||||
if (strncmp (url, "http://", 7) == 0)
|
||||
{
|
||||
ptr_url = url + 7;
|
||||
}
|
||||
else if (strncmp (url, "https://", 8) == 0)
|
||||
{
|
||||
if (tls)
|
||||
*tls = 1;
|
||||
ptr_url = url + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if there is an IPv6 address with square brackets, like "[::1]" */
|
||||
if (ptr_url[0] == '[')
|
||||
{
|
||||
/* extract IPv6 address between square brackets */
|
||||
pos = strchr (ptr_url, ']');
|
||||
if (!pos)
|
||||
return 0;
|
||||
if (address)
|
||||
*address = weechat_strndup (ptr_url + 1, pos - ptr_url - 1);
|
||||
ptr_url = pos + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* extract another address */
|
||||
pos = strrchr (ptr_url, ':');
|
||||
if (!pos)
|
||||
pos = strchr (ptr_url, '/');
|
||||
if (!pos)
|
||||
pos = strchr (ptr_url, '?');
|
||||
if (address)
|
||||
{
|
||||
*address = (pos) ?
|
||||
weechat_strndup (ptr_url, pos - ptr_url) : strdup (ptr_url);
|
||||
}
|
||||
}
|
||||
|
||||
/* extract port number */
|
||||
pos = strrchr (ptr_url, ':');
|
||||
if (pos)
|
||||
{
|
||||
ptr_url = pos + 1;
|
||||
pos = strchr (ptr_url, '/');
|
||||
if (!pos)
|
||||
pos = strchr (ptr_url, '?');
|
||||
str_port = (pos) ?
|
||||
weechat_strndup (ptr_url, pos - ptr_url) : strdup (ptr_url);
|
||||
if (!str_port)
|
||||
return 0;
|
||||
error = NULL;
|
||||
number = strtol (str_port, &error, 10);
|
||||
if (error && !error[0] && (number >= 0) && (number <= 65535))
|
||||
{
|
||||
if (port)
|
||||
*port = number;
|
||||
free (str_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
free (str_port);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if a remote URL is valid.
|
||||
*
|
||||
* Returns:
|
||||
* 1: URL is valid
|
||||
@@ -195,23 +295,7 @@ relay_remote_name_valid (const char *name)
|
||||
int
|
||||
relay_remote_url_valid (const char *url)
|
||||
{
|
||||
const char *pos;
|
||||
|
||||
if (!url || !url[0])
|
||||
return 0;
|
||||
|
||||
/* URL must start with "https://" or "http://" */
|
||||
if ((strncmp (url, "https://", 8) != 0) && (strncmp (url, "http://", 7) != 0))
|
||||
return 0;
|
||||
|
||||
pos = strchr (url + 7, ':');
|
||||
|
||||
/* invalid port? */
|
||||
if (pos && !isdigit ((unsigned char)pos[1]))
|
||||
return 0;
|
||||
|
||||
/* URL is valid */
|
||||
return 1;
|
||||
return relay_remote_parse_url (url, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -229,76 +313,6 @@ relay_remote_send_signal (struct t_relay_remote *remote)
|
||||
weechat_hook_signal_send (signal, WEECHAT_HOOK_SIGNAL_POINTER, remote);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts address from URL.
|
||||
*
|
||||
* Note: result must be free after use.
|
||||
*/
|
||||
|
||||
char *
|
||||
relay_remote_get_address (const char *url)
|
||||
{
|
||||
const char *ptr_start;
|
||||
char *pos;
|
||||
|
||||
if (!url)
|
||||
return NULL;
|
||||
|
||||
if (strncmp (url, "http://", 7) == 0)
|
||||
ptr_start = url + 7;
|
||||
else if (strncmp (url, "https://", 8) == 0)
|
||||
ptr_start = url + 8;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
pos = strchr (ptr_start, ':');
|
||||
if (!pos)
|
||||
pos = strchr (ptr_start, '?');
|
||||
|
||||
return (pos) ?
|
||||
weechat_strndup (ptr_start, pos - ptr_start) : strdup (ptr_start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts port from URL.
|
||||
*/
|
||||
|
||||
int
|
||||
relay_remote_get_port (const char *url)
|
||||
{
|
||||
char *pos, *pos2, *str_port, *error;
|
||||
long port;
|
||||
|
||||
if (!url)
|
||||
goto error;
|
||||
|
||||
pos = strchr (url + 7, ':');
|
||||
if (!pos)
|
||||
goto error;
|
||||
|
||||
pos++;
|
||||
|
||||
pos2 = strchr (pos, '/');
|
||||
if (pos2)
|
||||
str_port = weechat_strndup (pos, pos2 - pos);
|
||||
else
|
||||
str_port = strdup (pos);
|
||||
if (!str_port)
|
||||
goto error;
|
||||
|
||||
error = NULL;
|
||||
port = strtol (str_port, &error, 10);
|
||||
if (error && !error[0])
|
||||
{
|
||||
free (str_port);
|
||||
return (int)port;
|
||||
}
|
||||
free (str_port);
|
||||
|
||||
error:
|
||||
return RELAY_REMOTE_DEFAULT_PORT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates and initializes new remote structure.
|
||||
*
|
||||
@@ -415,9 +429,7 @@ void
|
||||
relay_remote_set_url (struct t_relay_remote *remote, const char *url)
|
||||
{
|
||||
free (remote->address);
|
||||
remote->address = relay_remote_get_address (url);
|
||||
remote->port = relay_remote_get_port (url);
|
||||
remote->tls = (weechat_strncmp (url, "https:", 6) == 0) ? 1 : 0;
|
||||
relay_remote_parse_url (url, &remote->tls, &remote->address, &remote->port);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "CppUTest/TestHarness.h"
|
||||
|
||||
#include "tests/tests.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <stdio.h>
|
||||
@@ -28,9 +30,21 @@ extern "C"
|
||||
#include "src/plugins/relay/relay.h"
|
||||
#include "src/plugins/relay/relay-remote.h"
|
||||
|
||||
extern char *relay_remote_get_address (const char *url);
|
||||
extern int relay_remote_parse_url (const char *url,
|
||||
int *tls, char **address, int *port);
|
||||
}
|
||||
|
||||
#define WEE_CHECK_PARSE_URL(__result, __result_tls, __result_address, \
|
||||
__result_port, __url) \
|
||||
tls = -1; \
|
||||
address = NULL; \
|
||||
port = -1; \
|
||||
relay_remote_parse_url (__url, &tls, &address, &port); \
|
||||
LONGS_EQUAL(__result_tls, tls); \
|
||||
STRCMP_EQUAL(__result_address, address); \
|
||||
LONGS_EQUAL(__result_port, port); \
|
||||
free (address);
|
||||
|
||||
TEST_GROUP(RelayRemote)
|
||||
{
|
||||
};
|
||||
@@ -89,6 +103,57 @@ TEST(RelayRemote, NameValid)
|
||||
/* TODO: write tests */
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* relay_remote_parse_url
|
||||
*/
|
||||
|
||||
TEST(RelayRemote, ParseUrl)
|
||||
{
|
||||
int tls, port;
|
||||
char *address;
|
||||
|
||||
LONGS_EQUAL(0, relay_remote_parse_url (NULL, NULL, NULL, NULL));
|
||||
LONGS_EQUAL(0, relay_remote_parse_url ("", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(0, relay_remote_parse_url ("zzz", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(0, relay_remote_parse_url ("http://[::1", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(0, relay_remote_parse_url ("https://[::1", NULL, NULL, NULL));
|
||||
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("http://example.com", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com/", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com?option=1", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com/?option=1", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com:9876", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com:9876/", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com:9876?option=1", NULL, NULL, NULL));
|
||||
LONGS_EQUAL(1, relay_remote_parse_url ("https://example.com:9876/?option=1", NULL, NULL, NULL));
|
||||
|
||||
WEE_CHECK_PARSE_URL(1, 0, "", RELAY_REMOTE_DEFAULT_PORT, "http://");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "", RELAY_REMOTE_DEFAULT_PORT, "https://");
|
||||
|
||||
WEE_CHECK_PARSE_URL(1, 0, "localhost", RELAY_REMOTE_DEFAULT_PORT, "http://localhost");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "localhost", RELAY_REMOTE_DEFAULT_PORT, "https://localhost");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", RELAY_REMOTE_DEFAULT_PORT, "https://example.com");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", RELAY_REMOTE_DEFAULT_PORT, "https://example.com/");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", RELAY_REMOTE_DEFAULT_PORT, "https://example.com?option=1");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", RELAY_REMOTE_DEFAULT_PORT, "https://example.com/?option=1");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", 9876, "https://example.com:9876");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", 9876, "https://example.com:9876/");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", 9876, "https://example.com:9876?option=1");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "example.com", 9876, "https://example.com:9876/?option=1");
|
||||
|
||||
WEE_CHECK_PARSE_URL(1, 0, "::1", RELAY_REMOTE_DEFAULT_PORT, "http://[::1]");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", RELAY_REMOTE_DEFAULT_PORT, "https://[::1]");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", RELAY_REMOTE_DEFAULT_PORT, "https://[::1]/");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", RELAY_REMOTE_DEFAULT_PORT, "https://[::1]?option=1");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", RELAY_REMOTE_DEFAULT_PORT, "https://[::1]/?option=1");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", 9876, "https://[::1]:9876");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", 9876, "https://[::1]:9876/");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", 9876, "https://[::1]:9876?option=1");
|
||||
WEE_CHECK_PARSE_URL(1, 1, "::1", 9876, "https://[::1]:9876/?option=1");
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* relay_remote_url_valid
|
||||
@@ -109,38 +174,6 @@ TEST(RelayRemote, SendSignal)
|
||||
/* TODO: write tests */
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* relay_remote_get_address
|
||||
*/
|
||||
|
||||
TEST(RelayRemote, GetAddress)
|
||||
{
|
||||
POINTERS_EQUAL(NULL, relay_remote_get_address (NULL));
|
||||
POINTERS_EQUAL(NULL, relay_remote_get_address (""));
|
||||
POINTERS_EQUAL(NULL, relay_remote_get_address ("zzz"));
|
||||
|
||||
STRCMP_EQUAL("", relay_remote_get_address ("http://"));
|
||||
STRCMP_EQUAL("", relay_remote_get_address ("https://"));
|
||||
|
||||
STRCMP_EQUAL("localhost", relay_remote_get_address ("https://localhost"));
|
||||
STRCMP_EQUAL("example.com", relay_remote_get_address ("https://example.com"));
|
||||
STRCMP_EQUAL("example.com", relay_remote_get_address ("https://example.com:8000"));
|
||||
STRCMP_EQUAL("example.com", relay_remote_get_address ("https://example.com:8000/"));
|
||||
STRCMP_EQUAL("example.com", relay_remote_get_address ("https://example.com:8000/?option=1"));
|
||||
STRCMP_EQUAL("example.com", relay_remote_get_address ("https://example.com?option=1"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* relay_remote_get_port
|
||||
*/
|
||||
|
||||
TEST(RelayRemote, GetPort)
|
||||
{
|
||||
/* TODO: write tests */
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* relay_remote_alloc
|
||||
|
||||
Reference in New Issue
Block a user