mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
Compare commits
6 Commits
328f86affc
...
d74993a42c
| Author | SHA1 | Date | |
|---|---|---|---|
| d74993a42c | |||
| 51464e400f | |||
| 1c5e6c3fc2 | |||
| e563dfc903 | |||
| befbcceb7f | |||
| 56f9ad68fb |
+5
-2
@@ -12,6 +12,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- core: add condition on connected relay api clients in default value of option weechat.look.hotlist_add_conditions
|
||||
- core: add `/mute` in default command for key `Alt`+`=` (toggle filters)
|
||||
- relay/api: add field "last_read_line_id" in GET /api/buffers
|
||||
|
||||
### Added
|
||||
|
||||
@@ -24,12 +25,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
- irc: fix tag in message with list of names when joining a channel
|
||||
- fset: remove error displayed in core buffer when clicking with the mouse below the last option displayed
|
||||
- irc: limit size of data received from the server to prevent memory exhaustion
|
||||
- irc: fix out-of-bounds read on incoming DCC command with a quoted filename ending the message
|
||||
- irc: fix out-of-bounds read on incoming DCC command with a quoted filename ending the message ([#2322](https://github.com/weechat/weechat/issues/2322))
|
||||
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3))
|
||||
- relay: limit size of received websocket frame and HTTP body to prevent memory exhaustion
|
||||
- relay: limit size of partial message received while reading an HTTP request to prevent memory exhaustion
|
||||
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
|
||||
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
|
||||
- xfer: replace directory separator in remote nick by underscore in download filename to prevent writing the file outside the download directory
|
||||
- xfer: replace directory separator in remote nick by underscore in download filename to prevent writing the file outside the download directory ([#2321](https://github.com/weechat/weechat/issues/2321))
|
||||
- xfer: fix out-of-bounds read when receiving empty line in DCC chat ([#2323](https://github.com/weechat/weechat/issues/2323))
|
||||
|
||||
## Version 4.9.1 (2026-05-31)
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ if(ENABLE_MAN OR ENABLE_DOC)
|
||||
set(SCRIPTING_LANG de en fr it ja pl sr)
|
||||
set(FAQ_LANG de en es fr it ja pl sr)
|
||||
set(QUICKSTART_LANG cs de en es fr it ja pl ru sr)
|
||||
set(RELAY_API_LANG en fr)
|
||||
set(RELAY_API_LANG en fr sr)
|
||||
set(RELAY_WEECHAT_LANG en fr ja sr)
|
||||
set(DEV_LANG en fr ja sr)
|
||||
|
||||
|
||||
@@ -541,7 +541,8 @@ HTTP/1.1 200 OK
|
||||
"plugin": "core",
|
||||
"name": "weechat"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823423765,
|
||||
@@ -571,7 +572,8 @@ HTTP/1.1 200 OK
|
||||
"tls_version": "TLS1.3",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823649069,
|
||||
@@ -599,7 +601,8 @@ HTTP/1.1 200 OK
|
||||
"nick": "alice",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -655,7 +658,8 @@ HTTP/1.1 200 OK
|
||||
"message": "Plugins loaded: alias, buflist, charset, exec, fifo, fset, guile, irc, javascript, logger, lua, perl, php, python, relay, ruby, script, spell, tcl, trigger, typing, xfer",
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
@@ -702,6 +706,7 @@ HTTP/1.1 200 OK
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": [],
|
||||
"last_read_line_id": -1,
|
||||
"nicklist_root": {
|
||||
"id": 0,
|
||||
"parent_group_id": -1,
|
||||
@@ -900,7 +905,8 @@ HTTP/1.1 200 OK
|
||||
"key": "up",
|
||||
"command": "/fset -up"
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -551,7 +551,8 @@ HTTP/1.1 200 OK
|
||||
"plugin": "core",
|
||||
"name": "weechat"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823423765,
|
||||
@@ -580,7 +581,8 @@ HTTP/1.1 200 OK
|
||||
"tls_version": "TLS1.3",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823649069,
|
||||
@@ -607,7 +609,8 @@ HTTP/1.1 200 OK
|
||||
"nick": "alice",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -663,7 +666,8 @@ HTTP/1.1 200 OK
|
||||
"message": "Plugins loaded: alias, buflist, charset, exec, fifo, fset, guile, irc, javascript, logger, lua, perl, php, python, relay, ruby, script, spell, tcl, trigger, typing, xfer",
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
@@ -709,6 +713,7 @@ HTTP/1.1 200 OK
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": [],
|
||||
"last_read_line_id": -1,
|
||||
"nicklist_root": {
|
||||
"id": 0,
|
||||
"parent_group_id": -1,
|
||||
@@ -906,7 +911,8 @@ HTTP/1.1 200 OK
|
||||
"key": "up",
|
||||
"command": "/fset -up"
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -543,7 +543,8 @@ HTTP/1.1 200 OK
|
||||
"plugin": "core",
|
||||
"name": "weechat"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823423765,
|
||||
@@ -573,7 +574,8 @@ HTTP/1.1 200 OK
|
||||
"tls_version": "TLS1.3",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823649069,
|
||||
@@ -601,7 +603,8 @@ HTTP/1.1 200 OK
|
||||
"nick": "alice",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -657,7 +660,8 @@ HTTP/1.1 200 OK
|
||||
"message": "Учитани додаци: alias, buflist, charset, exec, fifo, fset, guile, irc, javascript, logger, lua, perl, php, python, relay, ruby, script, spell, tcl, trigger, typing, xfer",
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
@@ -704,6 +708,7 @@ HTTP/1.1 200 OK
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": [],
|
||||
"last_read_line_id": -1,
|
||||
"nicklist_root": {
|
||||
"id": 0,
|
||||
"parent_group_id": -1,
|
||||
@@ -902,7 +907,8 @@ HTTP/1.1 200 OK
|
||||
"key": "up",
|
||||
"command": "/fset -up"
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -350,9 +350,13 @@ relay_api_msg_buffer_to_json (struct t_gui_buffer *buffer,
|
||||
{
|
||||
struct t_hdata *hdata;
|
||||
struct t_gui_buffer *pointer;
|
||||
struct t_gui_lines *ptr_lines;
|
||||
struct t_gui_line *ptr_line;
|
||||
struct t_gui_line_data *ptr_line_data;
|
||||
cJSON *json, *json_local_vars, *json_lines, *json_nicklist_root;
|
||||
const char *ptr_string;
|
||||
char *string;
|
||||
int last_read_line_id;
|
||||
|
||||
hdata = relay_hdata_buffer;
|
||||
pointer = buffer;
|
||||
@@ -405,6 +409,24 @@ relay_api_msg_buffer_to_json (struct t_gui_buffer *buffer,
|
||||
if (json_lines)
|
||||
cJSON_AddItemToObject (json, "lines", json_lines);
|
||||
}
|
||||
last_read_line_id = -1;
|
||||
ptr_lines = weechat_hdata_pointer (relay_hdata_buffer, buffer, "own_lines");
|
||||
if (ptr_lines)
|
||||
{
|
||||
ptr_line = weechat_hdata_pointer (relay_hdata_lines, ptr_lines, "last_read_line");
|
||||
if (ptr_line)
|
||||
{
|
||||
ptr_line_data = weechat_hdata_pointer (relay_hdata_line, ptr_line, "data");
|
||||
if (ptr_line_data)
|
||||
{
|
||||
last_read_line_id = weechat_hdata_integer (relay_hdata_line_data,
|
||||
ptr_line_data, "id");
|
||||
}
|
||||
}
|
||||
}
|
||||
cJSON_AddItemToObject (
|
||||
json, "last_read_line_id",
|
||||
cJSON_CreateNumber (last_read_line_id));
|
||||
|
||||
/* nicks */
|
||||
if (nicks)
|
||||
|
||||
@@ -26,8 +26,8 @@ struct t_relay_client;
|
||||
enum t_relay_status;
|
||||
|
||||
#define RELAY_API_VERSION_MAJOR 0
|
||||
#define RELAY_API_VERSION_MINOR 4
|
||||
#define RELAY_API_VERSION_PATCH 1
|
||||
#define RELAY_API_VERSION_MINOR 5
|
||||
#define RELAY_API_VERSION_PATCH 0
|
||||
#define RELAY_API_VERSION_NUMBER \
|
||||
((RELAY_API_VERSION_MAJOR << 16) \
|
||||
+ (RELAY_API_VERSION_MINOR << 8) \
|
||||
|
||||
@@ -17,7 +17,7 @@ info:
|
||||
license:
|
||||
name: CC BY-NC-SA 4.0
|
||||
url: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
version: 0.4.1
|
||||
version: 0.5.0
|
||||
|
||||
externalDocs:
|
||||
url: https://weechat.org/doc/
|
||||
@@ -1043,6 +1043,11 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Line'
|
||||
last_read_line_id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: identifier of the last line read in the buffer (-1 if read marker is not displayed)
|
||||
example: -1
|
||||
nicklist_root:
|
||||
$ref: '#/components/schemas/NickGroup'
|
||||
required:
|
||||
|
||||
@@ -1006,6 +1006,14 @@ relay_http_recv (struct t_relay_client *client, const char *data, int size)
|
||||
|
||||
if (client->partial_message)
|
||||
{
|
||||
/*
|
||||
* limit the size of the partial message: once the maximum is reached,
|
||||
* ignore the extra data (protection against a client sending a huge
|
||||
* amount of data without any end-of-line and dribbling it, which would
|
||||
* consume all the memory)
|
||||
*/
|
||||
if (strlen (client->partial_message) >= RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH)
|
||||
return;
|
||||
new_partial = realloc (client->partial_message,
|
||||
strlen (client->partial_message) +
|
||||
strlen (data) + 1);
|
||||
|
||||
@@ -64,6 +64,15 @@ enum t_relay_client_http_status
|
||||
*/
|
||||
#define RELAY_HTTP_BODY_MAX_LENGTH (8 * 1024 * 1024)
|
||||
|
||||
/*
|
||||
* maximum length of the partial message accumulated while reading an HTTP
|
||||
* request: once this limit is reached, the extra data is ignored; this
|
||||
* protects against a client sending a huge amount of data without any
|
||||
* end-of-line (an unterminated method or header line), which would consume
|
||||
* all the memory
|
||||
*/
|
||||
#define RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH (8 * 1024 * 1024)
|
||||
|
||||
struct t_relay_http_request
|
||||
{
|
||||
enum t_relay_client_http_status status; /* HTTP status */
|
||||
|
||||
@@ -162,7 +162,7 @@ xfer_chat_recv_cb (const void *pointer, void *data, int fd)
|
||||
{
|
||||
ctcp_action = 0;
|
||||
length = strlen (ptr_buf);
|
||||
if (ptr_buf[length - 1] == '\r')
|
||||
if ((length > 0) && (ptr_buf[length - 1] == '\r'))
|
||||
{
|
||||
ptr_buf[length - 1] = '\0';
|
||||
length--;
|
||||
|
||||
@@ -177,6 +177,7 @@ TEST(RelayApiMsg, BufferToJson)
|
||||
WEE_CHECK_OBJ_STR("core", json_local_vars, "plugin");
|
||||
WEE_CHECK_OBJ_STR("weechat", json_local_vars, "name");
|
||||
POINTERS_EQUAL(NULL, cJSON_GetObjectItem (json, "lines"));
|
||||
WEE_CHECK_OBJ_NUM(-1, json, "last_read_line_id");
|
||||
POINTERS_EQUAL(NULL, cJSON_GetObjectItem (json, "nicks"));
|
||||
cJSON_Delete (json);
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ extern "C"
|
||||
#include "src/plugins/relay/relay-client.h"
|
||||
#include "src/plugins/relay/relay-config.h"
|
||||
#include "src/plugins/relay/relay-http.h"
|
||||
#include "src/plugins/relay/relay-server.h"
|
||||
#include "src/plugins/relay/relay-websocket.h"
|
||||
#include "src/plugins/weechat-plugin.h"
|
||||
|
||||
@@ -1021,6 +1022,69 @@ TEST(RelayHttp, Recv)
|
||||
/* TODO: write tests */
|
||||
}
|
||||
|
||||
/*
|
||||
* Test functions:
|
||||
* relay_http_recv (partial message accumulated is bounded)
|
||||
*
|
||||
* Check that data received without any end-of-line does not grow the partial
|
||||
* message buffer without limit.
|
||||
*/
|
||||
|
||||
TEST(RelayHttp, RecvLimit)
|
||||
{
|
||||
struct t_relay_server *server;
|
||||
struct t_relay_client *client;
|
||||
char *chunk;
|
||||
int chunk_size, i;
|
||||
size_t length1, length2;
|
||||
|
||||
/* disable auto-open of relay buffer (it would pollute other tests) */
|
||||
config_file_option_set (relay_config_look_auto_open_buffer, "off", 1);
|
||||
|
||||
server = relay_server_new ("weechat", RELAY_PROTOCOL_WEECHAT, NULL,
|
||||
9000,
|
||||
NULL, /* path */
|
||||
1, /* ipv4 */
|
||||
0, /* ipv6 */
|
||||
0, /* tls */
|
||||
0); /* unix_socket */
|
||||
CHECK(server);
|
||||
client = relay_client_new (-1, "test", server);
|
||||
CHECK(client);
|
||||
|
||||
chunk_size = 1024 * 1024;
|
||||
chunk = (char *)malloc (chunk_size + 1);
|
||||
CHECK(chunk);
|
||||
memset (chunk, 'a', chunk_size);
|
||||
chunk[chunk_size] = '\0';
|
||||
|
||||
/* feed more than the maximum, with no end-of-line (16 MB) */
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
relay_http_recv (client, chunk, chunk_size);
|
||||
}
|
||||
CHECK(client->partial_message);
|
||||
length1 = strlen (client->partial_message);
|
||||
|
||||
/* the partial message must be bounded (not ~16 MB) */
|
||||
CHECK(length1 <= RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH + (size_t)chunk_size);
|
||||
|
||||
/* feeding more data must not grow it any further */
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
relay_http_recv (client, chunk, chunk_size);
|
||||
}
|
||||
length2 = strlen (client->partial_message);
|
||||
LONGS_EQUAL(length1, length2);
|
||||
|
||||
free (chunk);
|
||||
relay_client_free (client);
|
||||
relay_server_free (server);
|
||||
|
||||
/* restore auto-open of relay buffer */
|
||||
config_file_option_reset (relay_config_look_auto_open_buffer, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test functions:
|
||||
* relay_http_compress
|
||||
|
||||
Reference in New Issue
Block a user