mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-25 00:44:20 +01:00
commando: limit total request size.
1MB normally, but 10MB if you have a cached rune. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -51,9 +51,15 @@ class InReq:
|
||||
def __init__(self, idnum):
|
||||
self.idnum = idnum
|
||||
self.buf = b''
|
||||
self.discard = False
|
||||
|
||||
def append(self, data):
|
||||
self.buf += data
|
||||
if not self.discard:
|
||||
self.buf += data
|
||||
|
||||
def start_discard(self):
|
||||
self.buf = b''
|
||||
self.discard = True
|
||||
|
||||
|
||||
def split_cmd(cmdstr):
|
||||
@@ -204,11 +210,28 @@ def on_custommsg(peer_id, payload, plugin, request, **kwargs):
|
||||
if peer_id not in plugin.in_reqs or idnum != plugin.in_reqs[peer_id].idnum:
|
||||
plugin.in_reqs[peer_id] = InReq(idnum)
|
||||
plugin.in_reqs[peer_id].append(data)
|
||||
|
||||
# If you have cached a rune, give 10MB, otherwise 1MB.
|
||||
# We can have hundreds of these things...
|
||||
max_cmdlen = 1000000
|
||||
if peer_id in plugin.peer_runes:
|
||||
max_cmdlen *= 10
|
||||
|
||||
if len(plugin.in_reqs[peer_id].buf) > max_cmdlen:
|
||||
plugin.in_reqs[peer_id].start_discard()
|
||||
elif mtype == COMMANDO_CMD_TERM:
|
||||
# Prepend any prior data from COMMANDO_CMD_CONTINUES:
|
||||
if peer_id in plugin.in_reqs:
|
||||
data = plugin.in_reqs[peer_id].buf + data
|
||||
discard = plugin.in_reqs[peer_id].discard
|
||||
del plugin.in_reqs[peer_id]
|
||||
# Were we ignoring this for being too long? Error out now.
|
||||
if discard:
|
||||
send_result(plugin, peer_id, idnum,
|
||||
{'error': "Command too long"})
|
||||
request.set_result({'result': 'continue'})
|
||||
return
|
||||
|
||||
method, params, runestr = split_cmd(data)
|
||||
try_command(plugin, peer_id, idnum, method, params, runestr)
|
||||
elif mtype == COMMANDO_REPLY_CONTINUES:
|
||||
|
||||
@@ -316,3 +316,10 @@ def test_megacmd(node_factory):
|
||||
'method': 'get' + 'x' * 130000,
|
||||
'rune': rrune,
|
||||
'params': {}})
|
||||
|
||||
with pytest.raises(RpcError, match='Command too long'):
|
||||
l1.rpc.call(method='commando',
|
||||
payload={'peer_id': l2.info['id'],
|
||||
'method': 'get' + 'x' * 1100000,
|
||||
'rune': rrune,
|
||||
'params': {}})
|
||||
|
||||
Reference in New Issue
Block a user