- add propagate field
- don't propagate PMs
- filter commands sent to client via udp by nick/channel
alcuin-9995.diff alcuin-9995.tar.gz
1 | |
2 | diff --git a/Makefile b/Makefile |
3 | index 7ab6ef1..5b21c74 100644 |
4 | |
5 | |
6 | |
7 | rm -rf alcuin-$(VERSION) |
8 | |
9 | clean: |
10 | - rm -rf genesis.diff alcuin-$(VERSION).diff.escaped alcuin-$(VERSION) |
11 | + rm -rf alcuin-$(VERSION).diff alcuin-$(VERSION).diff.escaped alcuin-$(VERSION) |
12 | rm *.tar.gz |
13 | - rm *.diff.escaped |
14 | find . -name "*.swp" -delete |
15 | find . -name "*.pyc" -delete |
16 | |
17 | diff --git a/lib/client.py b/lib/client.py |
18 | index f3dc6ab..25ec4ab 100644 |
19 | |
20 | |
21 | |
22 | else: |
23 | self.__handle_command = self.__registration_handler |
24 | |
25 | + def is_addressed_to_me(self, message): |
26 | + command = self.__parse_udp_message(message) |
27 | + if command[0] == 'PRIVMSG': |
28 | + if command[1][0][0] == '#' or command[1][0] == self.nickname: |
29 | + return True |
30 | + else: |
31 | + return False |
32 | + else: |
33 | + return True |
34 | + |
35 | def get_prefix(self): |
36 | return "%s!%s@%s" % (self.nickname, self.user, self.host) |
37 | prefix = property(get_prefix) |
38 | |
39 | def write_queue_size(self): |
40 | return len(self.__writebuffer) |
41 | |
42 | + def __parse_udp_message(self, message): |
43 | + data = " ".join(message.split()[1:]) + "\r\n" |
44 | + lines = self.__linesep_regexp.split(data) |
45 | + lines = lines[:-1] |
46 | + commands = [] |
47 | + for line in lines: |
48 | + if not line: |
49 | + # Empty line. Ignore. |
50 | + continue |
51 | + x = line.split(" ", 1) |
52 | + command = x[0].upper() |
53 | + if len(x) == 1: |
54 | + arguments = [] |
55 | + else: |
56 | + if len(x[1]) > 0 and x[1][0] == ":": |
57 | + arguments = [x[1][1:]] |
58 | + else: |
59 | + y = string.split(x[1], " :", 1) |
60 | + arguments = string.split(y[0]) |
61 | + if len(y) == 2: |
62 | + arguments.append(y[1]) |
63 | + commands.append([command, arguments]) |
64 | + return commands[0] |
65 | + |
66 | def __parse_read_buffer(self): |
67 | lines = self.__linesep_regexp.split(self.__readbuffer) |
68 | self.__readbuffer = lines[-1] |
69 | |
70 | targetname = arguments[0] |
71 | message = arguments[1] |
72 | client = server.get_client(targetname) |
73 | + self.server.print_debug(self.server.nicknames) |
74 | |
75 | - if client: |
76 | - formatted_message = ":%s %s %s :%s" % (self.prefix, command, targetname, message) |
77 | - client.message(formatted_message) |
78 | - self.server.peer_broadcast(formatted_message) |
79 | - elif server.has_channel(targetname): |
80 | + if server.has_channel(targetname): |
81 | channel = server.get_channel(targetname) |
82 | self.message_channel( |
83 | channel, command, "%s :%s" % (channel.name, message)) |
84 | self.channel_log(channel, message) |
85 | else: |
86 | - # this isn't reliably true so let's not send the error |
87 | - return |
88 | - self.reply("401 %s %s :No such nick/channel" |
89 | - % (self.nickname, targetname)) |
90 | + formatted_message = ":%s %s %s :%s" % (self.prefix, command, targetname, message) |
91 | + if(client): |
92 | + client.message(formatted_message) |
93 | + self.server.peer_broadcast(formatted_message, False) |
94 | |
95 | def part_handler(): |
96 | if len(arguments) < 1: |
97 | diff --git a/lib/infosec.py b/lib/infosec.py |
98 | index a431c2f..b0c9c86 100644 |
99 | |
100 | |
101 | |
102 | import struct |
103 | import sys |
104 | |
105 | -PACKET_SIZE = 580 |
106 | +PACKET_SIZE = 581 |
107 | MAX_MESSAGE_SIZE = 512 |
108 | MAX_SECRET_SIZE = 24 |
109 | TS_ACCEPTABLE_SKEW = 60 * 15 |
110 | |
111 | def __init__(self, server=None): |
112 | self.server = server |
113 | |
114 | - def pack(self, peer, message, timestamp=None): |
115 | + def pack(self, peer, message, propagate, timestamp=None): |
116 | # if we are rebroadcasting we need to use the original timestamp |
117 | if(timestamp == None): |
118 | int_ts = int(time.time()) |
119 | |
120 | self.server.print_debug("added %d to recent" % int_ts) |
121 | |
122 | # build the packet and return it |
123 | - packet = struct.pack("!L64s512s", int_ts, digest_bytes, ciphertext_bytes) |
124 | + packet = struct.pack("!L64s?512s", int_ts, digest_bytes, propagate, ciphertext_bytes) |
125 | return packet |
126 | |
127 | def unpack(self, peer, packet): |
128 | try: |
129 | - int_ts, digest, ciphertext_bytes = struct.unpack("!L64s512s", packet) |
130 | + int_ts, digest, propagate, ciphertext_bytes = struct.unpack("!L64s?512s", packet) |
131 | except: |
132 | self.server.print_error("Discarding malformed packet?") |
133 | - return None, None |
134 | + return None, None, None |
135 | |
136 | # Check the timestamp and digest |
137 | digest_check = hashlib.sha512(peer.remote_secret + ciphertext_bytes).digest() |
138 | |
139 | if(int_ts not in self._ts_range()): |
140 | self.server.print_debug("rejected message with timestamp out of range") |
141 | - return None, None |
142 | + return None, None, None |
143 | elif(self.server.recent.has(int_ts)): |
144 | self.server.print_debug("rejected known message: %d" % int_ts) |
145 | - return None, None |
146 | + return None, None, None |
147 | elif(digest_check != digest): |
148 | self.server.print_debug("name: %s" % peer.name) |
149 | self.server.print_debug("remote_secret: %s" % peer.remote_secret) |
150 | self.server.print_debug("ciphertext_bytes: %s" % binascii.hexlify(ciphertext_bytes)) |
151 | self.server.print_debug("digest_check: %s" % binascii.hexlify(digest_check)) |
152 | self.server.print_debug("rejected bad digest: %s" % binascii.hexlify(digest)) |
153 | - return None, None |
154 | + return None, None, None |
155 | else: |
156 | # Return the cleartext |
157 | serpent = Serpent(self._pad(peer.remote_secret, MAX_SECRET_SIZE)) |
158 | cleartext = serpent.decrypt(ciphertext_bytes).rstrip() |
159 | self.server.print_debug("received, validated, and decrypted udp packet: %s" % cleartext) |
160 | self.server.recent.insert(int_ts) |
161 | - return cleartext, int_ts |
162 | + # self.server.print_debug("%s %d %s") % cleartext, int_ts, propagate |
163 | + return cleartext, int_ts, propagate |
164 | |
165 | def _pad(self, text, size): |
166 | return text.ljust(size) |
167 | diff --git a/lib/peer.py b/lib/peer.py |
168 | index e108328..5c25d25 100644 |
169 | |
170 | |
171 | |
172 | self.socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) |
173 | self.infosec = Infosec(server) |
174 | |
175 | - def send(self, msg, timestamp=None): |
176 | + def send(self, msg, propagate, timestamp=None): |
177 | try: |
178 | full_message = str.encode(msg) |
179 | self.server.print_debug("sending message: %s" % full_message) |
180 | - self.socket.sendto(self.infosec.pack(self, full_message, timestamp), (self.address, self.port)) |
181 | + self.socket.sendto(self.infosec.pack(self, full_message, propagate, timestamp), (self.address, self.port)) |
182 | except Exception as ex: |
183 | print("Exception while attempting to encode message: %s" % ex) |
184 | diff --git a/lib/server.py b/lib/server.py |
185 | index 9e8cbe5..bdd44d5 100644 |
186 | |
187 | |
188 | |
189 | -VERSION = "9996" |
190 | +VERSION = "9995" |
191 | |
192 | import os |
193 | import select |
194 | |
195 | |
196 | def handle_udp_data(self, data): |
197 | for peer in self.peers: |
198 | - message, timestamp = self.infosec.unpack(peer, data) |
199 | + message, timestamp, propagate = self.infosec.unpack(peer, data) |
200 | if(message != None): |
201 | self.print_debug("valid message from peer: %s" % peer.name) |
202 | # send the message to all clients |
203 | for c in self.clients: |
204 | - self.clients[c].message(message) |
205 | - # send the message to all other peers |
206 | - self.rebroadcast(peer, message, timestamp) |
207 | + # self.clients[c].udp_socket_readable_notification(message) |
208 | + if (self.clients[c].is_addressed_to_me(message)): |
209 | + self.clients[c].message(message) |
210 | + # send the message to all other peers if it should be propagated |
211 | + if(propagate == True): |
212 | + self.rebroadcast(peer, message, timestamp) |
213 | else: |
214 | self.print_debug("Unknown peer address: %s" % peer.address) |
215 | |
216 | - def peer_broadcast(self, message): |
217 | + def peer_broadcast(self, message, propagate=True): |
218 | for peer in self.peers: |
219 | - peer.send(message) |
220 | + peer.send(message, propagate) |
221 | |
222 | def rebroadcast(self, source_peer, message, timestamp): |
223 | for peer in self.peers: |
224 |