Merge lp:~ddormer/kali/kali-update into lp:kali

Proposed by Darren Dormer
Status: Merged
Approved by: Tristan Seligmann
Approved revision: 143
Merged at revision: 136
Proposed branch: lp:~ddormer/kali/kali-update
Merge into: lp:kali
Diff against target: 201 lines (+56/-19)
3 files modified
config.py.sample (+1/-0)
kali/controller.py (+15/-10)
kali/protocol.py (+40/-9)
To merge this branch: bzr merge lp:~ddormer/kali/kali-update
Reviewer Review Type Date Requested Status
Tristan Seligmann Approve
Review via email: mp+81250@code.launchpad.net

Description of the change

-Changed InspircdServices in protocol.py to work with the new Spanning Tree 1.2 protocol.
-Changes have also been made in controller.py and the various services (nickserv, ares, oper) to correctly interact with InspircdServices.
-Added usual noob code. :D

To post a comment you must log in.
Revision history for this message
Jonathan Jacobs (jjacobs) wrote :

Can you file a bug for this branch (like "Use new spanning tree 1.2 protocol") and link the branch to it? Then for future branches can you name the branch bugnumber-branch-name, I wouldn't worry about it for this particular branch.

Revision history for this message
Jeremy Thurgood (jerith) wrote :

Great stuff so far, thanks for taking this on.

Where do the sids and cids come from?

I don't see any unit tests around this stuff. Does Kali have any?
 * If so, can you update them?
 * If not, can you add some?

Revision history for this message
Darren Dormer (ddormer) wrote :

Thanks :>

I'll sort the branch stuff out now.
SID and CID are manually assigned for Kali, and the automatically
assigned/generated ones from (and for) the IRCd are included in the SERVER
command during initial connection.
I could try adding unit tests, but I'd prefer someone else handle that.

On Fri, Nov 4, 2011 at 4:03 PM, Jeremy Thurgood <email address hidden> wrote:

> Great stuff so far, thanks for taking this on.
>
> Where do the sids and cids come from?
>
> I don't see any unit tests around this stuff. Does Kali have any?
> * If so, can you update them?
> * If not, can you add some?
> --
> https://code.launchpad.net/~protato/kali/kali-update/+merge/81250
> You are the owner of lp:~protato/kali/kali-update.
>

lp:~ddormer/kali/kali-update updated
141. By Darren Dormer

Cleaned up newServiceUID and newCID functions a bit

Revision history for this message
Tristan Seligmann (mithrandi) wrote :

Having manually assigned CIDs for every pseudouser seems rather error-prone; it's too easy to accidentally use the same CID in two places, especially in the scenario where we eventually can have Kali plugins from external packages.

What about having a method on the controller to return a new CID instead? It can allocate them sequentially, the same way InspIRCd apparently does it, so that can be done when the pseudouser is being broadcast thus avoiding any possibility of collisions.

review: Needs Fixing
lp:~ddormer/kali/kali-update updated
142. By Darren Dormer

Replaced manually added CIDs with a generator

Revision history for this message
Darren Dormer (ddormer) wrote :

> Having manually assigned CIDs for every pseudouser seems rather error-prone;
> it's too easy to accidentally use the same CID in two places, especially in
> the scenario where we eventually can have Kali plugins from external packages.
>
> What about having a method on the controller to return a new CID instead? It
> can allocate them sequentially, the same way InspIRCd apparently does it, so
> that can be done when the pseudouser is being broadcast thus avoiding any
> possibility of collisions.

I've removed the manually assigned CIDs and replaced them with a generator, I'm not sure that it's in the correct place but I'm sure you'll tell me if it isn't :)

Revision history for this message
Tristan Seligmann (mithrandi) wrote :

You probably want itertools.product, not itertools.combinations; something like this:

self.ids = itertools.product(*[string.ascii_uppercase] * 6)

It's a little ugly because the signature of itertools.product is stupid, but I think that should do the trick. Otherwise, I think this looks good.

review: Needs Fixing
lp:~ddormer/kali/kali-update updated
143. By Darren Dormer

ID Generator now uses itertools.product which is more ideal

Revision history for this message
Darren Dormer (ddormer) wrote :

Ah I see, that returns a much better result. :)
I've replaced the itertools.combinations with itertools.product.

Revision history for this message
Tristan Seligmann (mithrandi) wrote :

Okay, the wraparound case isn't handled at present (you'll just get a StopIteration exception if the iterator is exhausted), but that's probably not important right now. Could you open a bug report about this so it doesn't get forgotten, though?

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'config.py.sample'
2--- config.py.sample 2009-01-11 21:05:56 +0000
3+++ config.py.sample 2012-01-15 17:06:23 +0000
4@@ -8,5 +8,6 @@
5
6 password = 'blahblahpass'
7 name = 'services.irc.net'
8+sid = '9A5'
9 numeric = 1
10 desc = 'FooNet IRC services'
11
12=== modified file 'kali/controller.py'
13--- kali/controller.py 2009-01-25 01:21:56 +0000
14+++ kali/controller.py 2012-01-15 17:06:23 +0000
15@@ -1,4 +1,4 @@
16-import time, types, inspect
17+import time, types, inspect, itertools, string
18 from textwrap import dedent
19
20 from zope.interface import implements
21@@ -200,19 +200,21 @@
22 """
23 self.ctrl = controller
24 self.store = self.ctrl.store
25+ self.cid = ''.join(n for n in self.ctrl.ids.next())
26+ self.uid = self.ctrl.params['sid'] + self.cid
27 self.avatars = {}
28
29 def event_connected(self, protocol):
30 self.protocol = protocol
31- self.protocol.newServiceNick(self.nick, self.name, self.modes)
32 self.signon = time.time()
33+ self.protocol.newServiceUID(self.cid, self.nick, self.name, self.signon, self.modes)
34
35 def event_idle(self, source, dest):
36 if dest.lower() == self.nick.lower():
37 self.protocol.sendMessage('IDLE', source, '%ld' % self.signon, '0', prefix=self.nick)
38
39 def event_privmsg(self, source, dest, msg):
40- if dest.lower() == self.nick.lower():
41+ if dest.lower() == self.uid.lower():
42 self.command(source, msg)
43
44 def locateCommand(self, avatar, params):
45@@ -257,7 +259,7 @@
46 """
47 Send a notice from C{nick} via the protocol.
48 """
49- self.protocol.notice(self.nick, nick, msg)
50+ self.protocol.notice(self.uid, nick, msg)
51
52 def kill(self, nick, msg):
53 """
54@@ -300,7 +302,7 @@
55 self.modes.remove(mode)
56
57
58-class User(record('nick user host name modes signon server'), _ModesMixin):
59+class User(record('cid nick user host name modes signon server'), _ModesMixin):
60 """
61 Represents the state of a single IRC user.
62
63@@ -358,6 +360,8 @@
64 self.users = {}
65 self.channels = {}
66
67+ self.ids = itertools.product(*[string.ascii_uppercase] * 6)
68+
69 def addService(self, service):
70 self.handlers.append(service)
71
72@@ -385,9 +389,10 @@
73 return self.channels[channelName.lower()]
74
75 def createUser(self, user):
76- nick = user['nick']
77- u = self.users[nick.lower()] = User(
78- nick=nick,
79+ cid = user['cid']
80+ u = self.users[cid.lower()] = User(
81+ cid = cid,
82+ nick=user['nick'],
83 user=user['username'],
84 host=user['hostname'],
85 name=user['realname'],
86@@ -411,8 +416,8 @@
87 self.event('left', channel, user)
88 self.users.pop(nick.lower())
89
90- def event_opertype(self, nick, opertype):
91- user = self.users[nick.lower()]
92+ def event_opertype(self, cid, opertype):
93+ user = self.users[cid.lower()]
94 user.opertype = opertype
95
96 def event_newserver(self, server, location):
97
98=== modified file 'kali/protocol.py'
99--- kali/protocol.py 2009-01-17 23:53:49 +0000
100+++ kali/protocol.py 2012-01-15 17:06:23 +0000
101@@ -208,7 +208,7 @@
102 class InspircdServices(IRCServices):
103 serviceModes = 'd'
104
105- userParamModes = ('', '')
106+ userParamModes = ('s', '')
107 channelParamModes = 'fjklJL'
108 channelParamListModes = 'begI'
109 channelUserModes = 'ahovq'
110@@ -220,7 +220,7 @@
111 channelPrefixes = '#'
112
113 def startHandshake(self):
114- self.sendMessage('SERVER', self.params['name'], self.params['password'], '0', ':%(desc)s' % self.params)
115+ self.sendMessage('SERVER', self.params['name'], self.params['password'], '0', self.params['sid'], ':%(desc)s' % self.params)
116
117 def getTargetKind(self, target):
118 """
119@@ -232,7 +232,7 @@
120 raise EmptyTarget(target)
121 return dict.fromkeys(self.channelPrefixes, 'channel').get(target[0], 'user')
122
123- def irc_SERVER(self, source, name, password, hopcount, description):
124+ def irc_SERVER(self, source, name, password, hopcount, sid, description):
125 hopcount = int(hopcount)
126 if hopcount == 0:
127 # authentication phase
128@@ -240,10 +240,10 @@
129 raise IRCBadMessage(source)
130
131 # XXX: actually check auth
132- self.sendMessage('BURST', '%ld' % time.time())
133- self.sendMessage('VERSION', ':Ares X')
134+ self.sendMessage('BURST', '%ld' % time.time(), prefix=self.params['sid'])
135+ self.sendMessage('VERSION', ':Ares X', prefix=self.params['sid'])
136 self.services.event('connected', self)
137- self.sendMessage('ENDBURST')
138+ self.sendMessage('ENDBURST', prefix=self.params['sid'])
139 else:
140 self.services.event('newserver', name, description)
141
142@@ -263,11 +263,11 @@
143 user['servicestamp'] = 0
144 self.services.createUser(user)
145
146- def irc_OPERTYPE(self, nick, opertype):
147- self.services.event('opertype', nick.decode('ascii'), opertype)
148+ def irc_OPERTYPE(self, cid, opertype):
149+ self.services.event('opertype', cid.decode('ascii'), opertype)
150 # InspIRCd doesn't send MODE +o, so we fake it here to keep
151 # our modes in sync with the network.
152- self.services.event('modeadded', None, nick.decode('ascii'), 'user', ('o', None))
153+ self.services.event('modeadded', None, cid.decode('ascii'), 'user', ('o', None))
154
155 def irc_BURST(self, prefix, stamp):
156 pass
157@@ -356,6 +356,12 @@
158 for channel in channels.split(','):
159 self.services.event('joined', channel, source)
160
161+ def irc_PING(self, sid, source, target):
162+ self.sendMessage('PONG', self.params['sid'], source, prefix=self.params['sid'])
163+
164+ def irc_PRIVMSG(self, source, target, msg):
165+ self.services.event('privmsg', source, target, msg)
166+
167 def irc_PART(self, source, channel, message=''):
168 self.services.event('parted', channel, source, message)
169
170@@ -364,6 +370,31 @@
171 server = self.params['name']
172 self.sendMessage('NICK', '%ld' % time.time(), nick.encode('ascii'), host, host, user, '+' + modes, '0.0.0.0', ':%s' % name)
173
174+ def irc_UID(self, source, *params):
175+ if len(params) == 1:
176+ pass
177+ else:
178+ paramNames = 'cid timestamp nick hostname fakehost username ip signontime modes modeparams realname'.split()
179+
180+ user = dict(zip(paramNames, params))
181+ user['cid'] = user['cid'].decode('ascii')
182+ user['nick'] = user['nick'].decode('ascii')
183+ user['modes'] = user['modes'].lstrip('+')
184+ user['modeparams'] = user['modeparams'].lstrip('+')
185+ user['timestamp'] = int(user['timestamp'])
186+ user['server'] = source
187+ user['servicestamp'] = 0
188+ self.services.createUser(user)
189+
190+ def newCID(self, cid, nick, realname, hostname, fakehost, ident, signon, modes, server=None):
191+ if server is None:
192+ server = self.params['name']
193+ self.sendMessage('UID', '%s%s' % (self.params['sid'], cid.encode('ascii')), '%ld' % time.time(), nick, hostname, \
194+ fakehost, ident, '0.0.0.0', '%ld' % signon, '+' + modes, ':%s' % realname, prefix=self.params['sid'])
195+
196+ def newServiceUID(self, cid, nick, realname, signon, modes):
197+ return self.newCID(cid, nick, realname, 'services.', 'services.', nick.lower(), signon, ''.join(set(modes + self.serviceModes)), ':%s' % realname)
198+
199
200 class ServicesFactory(ReconnectingClientFactory):
201 """

Subscribers

People subscribed via source and target branches

to all changes: