1#!/usr/bin/env python3
2
3# Check whether messages deliver or not after some access is revoked.
4
5from mosq_test_helper import *
6import signal
7
8def write_config(filename, port, per_listener):
9    with open(filename, 'w') as f:
10        f.write("per_listener_settings %s\n" % (per_listener))
11        f.write("port %d\n" % (port))
12        f.write("acl_file %s\n" % (filename.replace('.conf', '.acl')))
13
14def write_acl(filename, en):
15    with open(filename, 'w') as f:
16        f.write('user username\n')
17        f.write('topic readwrite topic/one\n')
18        if en:
19            f.write('topic readwrite topic/two\n')
20
21keepalive = 60
22username = "username"
23
24connect1_packet = mosq_test.gen_connect("acl-check", keepalive=keepalive, username=username, clean_session=False)
25connack1a_packet = mosq_test.gen_connack(rc=0)
26connack1b_packet = mosq_test.gen_connack(rc=0, flags=1)
27
28mid = 1
29subscribe1_packet = mosq_test.gen_subscribe(mid=mid, topic="topic/one", qos=1)
30suback1_packet = mosq_test.gen_suback(mid=mid, qos=1)
31
32mid = 2
33subscribe2_packet = mosq_test.gen_subscribe(mid=mid, topic="topic/two", qos=1)
34suback2_packet = mosq_test.gen_suback(mid=mid, qos=1)
35
36disconnect_packet = mosq_test.gen_disconnect()
37
38connect2_packet = mosq_test.gen_connect("helper", keepalive=keepalive, username=username)
39connack2_packet = mosq_test.gen_connack(rc=0)
40
41mid = 1
42publish1s_packet = mosq_test.gen_publish(topic="topic/one", mid=mid, qos=1, payload="message1")
43puback1s_packet = mosq_test.gen_puback(mid)
44
45mid = 2
46publish2s_packet = mosq_test.gen_publish(topic="topic/two", mid=mid, qos=1, payload="message2")
47puback2s_packet = mosq_test.gen_puback(mid)
48
49mid = 1
50publish1r_packet = mosq_test.gen_publish(topic="topic/one", mid=mid, qos=1, payload="message1")
51puback1r_packet = mosq_test.gen_puback(mid)
52
53mid = 2
54publish3s_packet = mosq_test.gen_publish(topic="topic/one", mid=mid, qos=1, payload="message3")
55puback3s_packet = mosq_test.gen_puback(mid)
56
57mid = 3
58publish3r_packet = mosq_test.gen_publish(topic="topic/one", mid=mid, qos=1, payload="message3")
59puback3r_packet = mosq_test.gen_puback(mid)
60
61mid = 3
62publish4s_packet = mosq_test.gen_publish(topic="topic/two", mid=mid, qos=1, payload="message4")
63puback4s_packet = mosq_test.gen_puback(mid)
64
65rc = 1
66
67port = mosq_test.get_port()
68
69conf_file = os.path.basename(__file__).replace('.py', '.conf')
70write_config(conf_file, port, "false")
71
72acl_file = os.path.basename(__file__).replace('.py', '.acl')
73write_acl(acl_file, True)
74
75broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
76
77try:
78    keepalive = 60
79
80    # Connect, subscribe, then disconnect
81    sock = mosq_test.do_client_connect(connect1_packet, connack1a_packet, port=port)
82    mosq_test.do_send_receive(sock, subscribe1_packet, suback1_packet, "suback1")
83    mosq_test.do_send_receive(sock, subscribe2_packet, suback2_packet, "suback2")
84    sock.send(disconnect_packet)
85    sock.close()
86
87    # Helper publish to topic/one and topic/two, will be queued for other client
88    sock = mosq_test.do_client_connect(connect2_packet, connack2_packet, port=port)
89    mosq_test.do_send_receive(sock, publish1s_packet, puback1s_packet, "puback1")
90    mosq_test.do_send_receive(sock, publish2s_packet, puback2s_packet, "puback2")
91    sock.close()
92
93    # Reload ACLs with topic/two now disabled
94    write_acl(acl_file, False)
95    broker.send_signal(signal.SIGHUP)
96
97    sock = mosq_test.do_client_connect(connect1_packet, connack1b_packet, port=port)
98    sock.settimeout(10)
99    mosq_test.expect_packet(sock, "publish1r", publish1r_packet)
100    # We don't expect messages to topic/two any more, so we don't expect the queued one
101    mosq_test.do_send_receive(sock, publish3s_packet, puback3s_packet, "puback3")
102    mosq_test.expect_packet(sock, "publish3r", publish3r_packet)
103
104    # Send this, don't expect it to succeed
105    mosq_test.do_send_receive(sock, publish4s_packet, puback4s_packet, "puback4")
106
107    # Check for non delivery with a ping
108    mosq_test.do_ping(sock)
109
110    sock.close()
111    rc = 0
112
113finally:
114    os.remove(conf_file)
115    os.remove(acl_file)
116    broker.terminate()
117    broker.wait()
118    (stdo, stde) = broker.communicate()
119    if rc:
120        print(stde.decode('utf-8'))
121        exit(rc)
122
123port = mosq_test.get_port()
124
125