Mercurial > prosody-modules
comparison mod_ircd/mod_ircd.in.lua @ 468:640e6c0b563d
mod_ircd: Scrub invalid UTF-8 sequences, welcome message
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 01 Nov 2011 19:18:30 +0100 |
parents | 0fcd34ee7301 |
children | ff03a325aa41 |
comparison
equal
deleted
inserted
replaced
467:266bf13729ae | 468:640e6c0b563d |
---|---|
51 --c.connect_host = "127.0.0.1" | 51 --c.connect_host = "127.0.0.1" |
52 --c:connect_component(component_jid, component_secret); | 52 --c:connect_component(component_jid, component_secret); |
53 | 53 |
54 local jid = require "util.jid"; | 54 local jid = require "util.jid"; |
55 local nodeprep = require "util.encodings".stringprep.nodeprep; | 55 local nodeprep = require "util.encodings".stringprep.nodeprep; |
56 | |
57 local function utf8_clean (s) | |
58 local push, join = table.insert, table.concat; | |
59 local r, i = {}, 1; | |
60 if not(s and #s > 0) then | |
61 return "" | |
62 end | |
63 while true do | |
64 local c = s:sub(i,i) | |
65 local b = c:byte(); | |
66 local w = ( | |
67 (b >= 9 and b <= 10 and 0) or | |
68 (b >= 32 and b <= 126 and 0) or | |
69 (b >= 192 and b <= 223 and 1) or | |
70 (b >= 224 and b <= 239 and 2) or | |
71 (b >= 240 and b <= 247 and 3) or | |
72 (b >= 248 and b <= 251 and 4) or | |
73 (b >= 251 and b <= 252 and 5) or nil | |
74 ) | |
75 if not w then | |
76 push(r, "?") | |
77 else | |
78 local n = i + w; | |
79 if w == 0 then | |
80 push(r, c); | |
81 elseif n > #s then | |
82 push(r, ("?"):format(b)); | |
83 else | |
84 local e = s:sub(i+1,n); | |
85 if e:match('^[\128-\191]*$') then | |
86 push(r, c); | |
87 push(r, e); | |
88 i = n; | |
89 else | |
90 push(r, ("?"):format(b)); | |
91 end | |
92 end | |
93 end | |
94 i = i + 1; | |
95 if i > #s then | |
96 break | |
97 end | |
98 end | |
99 return join(r); | |
100 end | |
56 | 101 |
57 local function parse_line(line) | 102 local function parse_line(line) |
58 local ret = {}; | 103 local ret = {}; |
59 if line:sub(1,1) == ":" then | 104 if line:sub(1,1) == ":" then |
60 ret.from, line = line:match("^:(%w+)%s+(.*)$"); | 105 ret.from, line = line:match("^:(%w+)%s+(.*)$"); |
126 end | 171 end |
127 command = command:upper(); | 172 command = command:upper(); |
128 if not session.nick then | 173 if not session.nick then |
129 if not (command == "USER" or command == "NICK") then | 174 if not (command == "USER" or command == "NICK") then |
130 module:log("debug", "Client tried to send command %s before registering", command); | 175 module:log("debug", "Client tried to send command %s before registering", command); |
131 return session.send{from=muc_server, 451, command, "You have not registered"} | 176 return session.send{from=muc_server, "451", command, "You have not registered"} |
132 end | 177 end |
133 end | 178 end |
134 if commands[command] then | 179 if commands[command] then |
135 local ret = commands[command](session, parts); | 180 local ret = commands[command](session, parts); |
136 if ret then | 181 if ret then |
137 return session.send(ret); | 182 return session.send(ret); |
138 end | 183 end |
139 else | 184 else |
140 session.send{from=muc_server, 421, session.nick, command, "Unknown command"}; | 185 session.send{from=muc_server, "421", session.nick, command, "Unknown command"}; |
141 return module:log("debug", "Unknown command: %s", command); | 186 return module:log("debug", "Unknown command: %s", command); |
142 end | 187 end |
143 end | 188 end |
144 function session.send(data) | 189 function session.send(data) |
145 if type(data) == "string" then | 190 if type(data) == "string" then |
172 sessions[conn] = nil; | 217 sessions[conn] = nil; |
173 end | 218 end |
174 | 219 |
175 function commands.NICK(session, args) | 220 function commands.NICK(session, args) |
176 if session.nick then | 221 if session.nick then |
177 session.send(":"..muc_server.." 484 * "..nick.." :I'm afraid I can't let you do that, "..session.nick); | 222 session.send{from = muc_server, "484", "*", nick, "I'm afraid I can't let you do that"}; |
178 --TODO Loop throug all rooms and change nick, with help from Verse. | 223 --TODO Loop throug all rooms and change nick, with help from Verse. |
179 return; | 224 return; |
180 end | 225 end |
181 local nick = args[1]; | 226 local nick = args[1]; |
182 nick = nick:gsub("[^%w_]",""); | 227 nick = nick:gsub("[^%w_]",""); |
183 if nicks[nick] then | 228 if nicks[nick] then |
184 session.send{from=muc_server, 433, nick, "The nickname "..nick.." is already in use"}; | 229 session.send{from=muc_server, "433", nick, "The nickname "..nick.." is already in use"}; |
185 return; | 230 return; |
186 end | 231 end |
187 local full_jid = jid.join(nick, component_jid, "ircd"); | 232 local full_jid = jid.join(nick, component_jid, "ircd"); |
188 jids[full_jid] = session; | 233 jids[full_jid] = session; |
189 nicks[nick] = session; | 234 nicks[nick] = session; |
190 session.nick = nick; | 235 session.nick = nick; |
191 session.full_jid = full_jid; | 236 session.full_jid = full_jid; |
192 session.type = "c2s"; | 237 session.type = "c2s"; |
193 session.send{from = muc_server, 001, nick, "Welcome to XMPP via the "..session.host.." gateway "..session.nick}; | 238 session.send{from = muc_server, "001", nick, "Welcome to IRC gateway to XMPP!"}; |
194 session.send{from=nick, "MODE", nick, "+i"}; -- why | 239 session.send{from = muc_server, "002", nick, module.host.." running Prosody "..prosody.version}; |
240 session.send{from = muc_server, "003", nick, os.date(nil, prosody.start_time)} | |
241 session.send{from = muc_server, "004", table.concat({muc_server, "alpha", "i", "ov"}, " ")}; | |
242 session.send{from = nick, "MODE", nick, "+i"}; -- why | |
195 end | 243 end |
196 | 244 |
197 function commands.USER(session, params) | 245 function commands.USER(session, params) |
198 -- FIXME | 246 -- FIXME |
199 -- Empty command for now | 247 -- Empty command for now |
278 local channel, message = unpack(args); | 326 local channel, message = unpack(args); |
279 if message and #message > 0 then | 327 if message and #message > 0 then |
280 if message:sub(1,8) == "\1ACTION " then | 328 if message:sub(1,8) == "\1ACTION " then |
281 message = "/me ".. message:sub(9,-2) | 329 message = "/me ".. message:sub(9,-2) |
282 end | 330 end |
283 -- TODO clean out invalid chars | 331 message = utf8_clean(message); |
284 if channel:sub(1,1) == "#" then | 332 if channel:sub(1,1) == "#" then |
285 if session.rooms[channel] then | 333 if session.rooms[channel] then |
286 module:log("debug", "%s sending PRIVMSG \"%s\" to %s", session.nick, message, channel); | 334 module:log("debug", "%s sending PRIVMSG \"%s\" to %s", session.nick, message, channel); |
287 session.rooms[channel]:send_message(message); | 335 session.rooms[channel]:send_message(message); |
288 end | 336 end |
320 end | 368 end |
321 session.send{from=muc_server, 315, session.nick, channel, "End of /WHO list"}; | 369 session.send{from=muc_server, 315, session.nick, channel, "End of /WHO list"}; |
322 end | 370 end |
323 end | 371 end |
324 | 372 |
325 function commands._MODE(session, args) -- FIXME | 373 function commands.MODE(session, args) -- FIXME |
326 local channel, target = unpack(args); | 374 local channel, target = unpack(args); |
327 if target then | 375 if target then |
328 -- do stuff? | 376 -- do stuff? |
329 --room:set_affiliation(...) | 377 --room:set_affiliation(...) |
378 session.send{from=muc_server, "324", session.nick, channel, "+i"} | |
330 else | 379 else |
331 -- What's 324? And +J ? | 380 -- What's 324? And +J ? |
332 session.send{from=muc_server, 324, session.nick, channel, "+J"} | 381 session.send{from=muc_server, "324", session.nick, channel, "+J"} |
333 end | 382 end |
334 end | 383 end |
335 | 384 |
336 function commands.QUIT(session, args) | 385 function commands.QUIT(session, args) |
337 session.send{"ERROR", "Closing Link: "..session.nick}; | 386 session.send{"ERROR", "Closing Link: "..session.nick}; |