Alcuin 9995: propagate field

  • 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 --- a/Makefile
5 +++ b/Makefile
6 @@ -12,9 +12,8 @@ dist:
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 --- a/lib/client.py
20 +++ b/lib/client.py
21 @@ -30,6 +30,16 @@ class Client(object):
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 @@ -51,6 +61,30 @@ class Client(object):
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 @@ -294,21 +328,18 @@ class Client(object):
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 --- a/lib/infosec.py
100 +++ b/lib/infosec.py
101 @@ -7,7 +7,7 @@ import time
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 @@ -16,7 +16,7 @@ class Infosec(object):
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 @@ -34,39 +34,40 @@ class Infosec(object):
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 --- a/lib/peer.py
170 +++ b/lib/peer.py
171 @@ -13,10 +13,10 @@ class Peer(object):
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 --- a/lib/server.py
187 +++ b/lib/server.py
188 @@ -1,4 +1,4 @@
189 -VERSION = "9996"
190 +VERSION = "9995"
191
192 import os
193 import select
194 @@ -141,20 +141,23 @@ class Server(object):
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

Leave a Reply