Skip to content

Commit a8052a3

Browse files
committed
Add test for invalid service name for old protocol version
This would have previously been allowed. The test currently fails. Also add various tests for the modern protocol version, which all pass, and a test for QSB-089.
1 parent 2a302d8 commit a8052a3

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

qrexec/tests/socket/daemon.py

+89
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,95 @@ def test_bad_request_id_bad_byte_after_nul_terminator(self):
203203
self.assertEqual(data[:4], b"a\0b\0")
204204
self.assertEqual(data[4:], b"\0" * 28)
205205

206+
@unittest.expectedFailure
207+
def test_bad_old_style_request(self):
208+
agent = self.start_daemon_with_agent()
209+
agent.send_message(qrexec.MSG_HELLO, struct.pack("<L", 2))
210+
message_type, data = agent.recv_message()
211+
self.assertEqual(message_type, qrexec.MSG_HELLO)
212+
(ver,) = struct.unpack("<L", data)
213+
self.assertEqual(ver, 3)
214+
215+
target_domain_name = "target_domain"
216+
ident = b"ab"
217+
218+
self.set_policy_params(1, 0)
219+
220+
for service_name in (b"\0", b"", b"\0a", b"\0+a", b"+", b"+a"):
221+
agent.send_message(
222+
qrexec.MSG_TRIGGER_SERVICE,
223+
struct.pack("<64s32s32s", service_name,
224+
target_domain_name.encode(), ident)
225+
)
226+
message_type, data = agent.recv_message()
227+
self.assertEqual(message_type, qrexec.MSG_SERVICE_REFUSED)
228+
self.assertEqual(len(data), 32)
229+
self.assertEqual(data[:len(ident)], ident)
230+
self.assertEqual(data[len(ident):], b"\0" * (32 - len(ident)))
231+
self.assertFalse(os.path.exists(
232+
os.path.join(self.tempdir, "qrexec-policy-params")
233+
)),
234+
235+
def test_bad_new_style_request(self):
236+
"""
237+
Test that qrexec-daemon rejects various invalid requests.
238+
"""
239+
agent = self.start_daemon_with_agent()
240+
agent.handshake()
241+
242+
target_domain_name = "target_domain"
243+
ident = "ab"
244+
245+
self.set_policy_params(1, 0)
246+
247+
def recv_refused(agent):
248+
message_type, data = agent.recv_message()
249+
self.assertEqual(message_type, qrexec.MSG_SERVICE_REFUSED)
250+
self.assertEqual(len(data), 32)
251+
self.assertEqual(data[:2], b"ab")
252+
self.assertEqual(data[2:], b"\0" * 30)
253+
self.assertFalse(os.path.exists(
254+
os.path.join(self.tempdir, "qrexec-policy-params")
255+
)),
256+
257+
# missing NUL terminator
258+
agent.send_message(
259+
qrexec.MSG_TRIGGER_SERVICE3,
260+
struct.pack("<64s32s", target_domain_name.encode(), ident.encode())
261+
+ b"a",
262+
)
263+
recv_refused(agent)
264+
265+
# leading, interior or trailing NUL before NUL terminator,
266+
# empty service name with argument, or empty service name with no
267+
# argument
268+
for service_name in ("\0", "", "a\0", "\0a", "\0+a", "+", "+a", "a\0a"):
269+
self.send_trigger_service(
270+
agent, target_domain_name, service_name, ident
271+
)
272+
recv_refused(agent)
273+
274+
def test_qsb_089(self):
275+
"""
276+
Test that qrexec-daemon doesn't corrupt memory on empty request
277+
"""
278+
agent = self.start_daemon_with_agent()
279+
agent.handshake()
280+
281+
target_domain_name = "target_domain"
282+
ident = "ab"
283+
284+
self.set_policy_params(1, 0)
285+
286+
agent.send_message(
287+
qrexec.MSG_TRIGGER_SERVICE3,
288+
struct.pack("<64s32s", target_domain_name.encode(), ident.encode()))
289+
# qrexec-daemon will terminate
290+
self.assertEqual(agent.recvall(1), b"")
291+
self.assertFalse(os.path.exists(
292+
os.path.join(self.tempdir, "qrexec-policy-params")
293+
))
294+
206295
def send_trigger_service(
207296
self, agent, target_domain_name: str, service_name: str, ident: str
208297
):

qrexec/tests/socket/qrexec.py

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
MSG_JUST_EXEC = 0x201
3333
MSG_SERVICE_CONNECT = 0x202
3434
MSG_SERVICE_REFUSED = 0x203
35+
MSG_TRIGGER_SERVICE = 0x210
3536
MSG_CONNECTION_TERMINATED = 0x211
3637
MSG_TRIGGER_SERVICE3 = 0x212
3738
MSG_HELLO = 0x300

0 commit comments

Comments
 (0)