42 if origin.type == "c2s" then |
42 if origin.type == "c2s" then |
43 stanza.attr.from = origin.full_jid; -- quick fix to prevent impersonation (FIXME this would be incorrect when the origin is not c2s) |
43 stanza.attr.from = origin.full_jid; -- quick fix to prevent impersonation (FIXME this would be incorrect when the origin is not c2s) |
44 end |
44 end |
45 |
45 |
46 if not to then |
46 if not to then |
47 core_handle_stanza(origin, stanza); |
47 core_handle_stanza(origin, stanza); |
48 elseif hosts[to] and hosts[to].type == "local" then |
48 elseif hosts[to] and hosts[to].type == "local" then |
49 core_handle_stanza(origin, stanza); |
49 core_handle_stanza(origin, stanza); |
50 elseif stanza.name == "iq" and not select(3, jid_split(to)) then |
50 elseif stanza.name == "iq" and not select(3, jid_split(to)) then |
51 core_handle_stanza(origin, stanza); |
51 core_handle_stanza(origin, stanza); |
52 elseif origin.type == "c2s" or origin.type == "s2sin" then |
52 elseif origin.type == "c2s" or origin.type == "s2sin" then |
170 --- ...later |
170 --- ...later |
171 |
171 |
172 -- Deliver |
172 -- Deliver |
173 local to = stanza.attr.to; |
173 local to = stanza.attr.to; |
174 local node, host, resource = jid_split(to); |
174 local node, host, resource = jid_split(to); |
|
175 local to_bare = node and (node.."@"..host) or host; -- bare JID |
|
176 local from = stanza.attr.from; |
|
177 local from_node, from_host, from_resource = jid_split(from); |
|
178 local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID |
175 |
179 |
176 if stanza.name == "presence" and (stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable") then resource = nil; end |
180 if stanza.name == "presence" and (stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable") then resource = nil; end |
177 |
181 |
178 local host_session = hosts[host] |
182 local host_session = hosts[host] |
179 if host_session and host_session.type == "local" then |
183 if host_session and host_session.type == "local" then |
186 if stanza.name == "presence" then |
190 if stanza.name == "presence" then |
187 if stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" then |
191 if stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" then |
188 if stanza.attr.type == "probe" then |
192 if stanza.attr.type == "probe" then |
189 if is_authorized_to_see_presence(origin, node, host) then |
193 if is_authorized_to_see_presence(origin, node, host) then |
190 for k in pairs(user.sessions) do -- return presence for all resources |
194 for k in pairs(user.sessions) do -- return presence for all resources |
191 if user.sessions[k].presence then |
195 local pres = user.sessions[k].presence; |
192 local pres = user.sessions[k].presence; |
196 if pres then |
193 pres.attr.to = origin.full_jid; |
197 pres.attr.to = from; -- FIXME use from_bare? |
194 pres.attr.from = user.sessions[k].full_jid; |
198 pres.attr.from = user.sessions[k].full_jid; |
195 send(origin, pres); |
199 send(origin, pres); |
196 pres.attr.to = nil; |
200 pres.attr.to = nil; |
197 pres.attr.from = nil; |
201 pres.attr.from = nil; |
198 end |
202 end |
199 end |
203 end |
200 else |
204 else |
201 send(origin, st.presence({from=user.."@"..host, to=origin.username.."@"..origin.host, type="unsubscribed"})); |
205 send(origin, st.presence({from=to_bare, to=origin.username.."@"..origin.host, type="unsubscribed"})); |
202 end |
206 end |
203 elseif stanza.attr.type == "subscribe" then |
207 elseif stanza.attr.type == "subscribe" then |
204 -- TODO |
208 -- TODO |
205 elseif stanza.attr.type == "unsubscribe" then |
209 elseif stanza.attr.type == "unsubscribe" then |
206 -- TODO |
210 -- TODO |
207 elseif stanza.attr.type == "subscribed" then |
211 elseif stanza.attr.type == "subscribed" then |
208 -- TODO |
212 -- TODO |
|
213 -- sender.roster[recipient.bare_jid]. subscription = from or both |
|
214 -- sender.rosterpush recipient |
|
215 -- send presence for all sender resources to recipient.bare_jid |
209 elseif stanza.attr.type == "unsubscribed" then |
216 elseif stanza.attr.type == "unsubscribed" then |
210 -- TODO |
217 -- TODO |
211 end -- discard any other type |
218 end -- discard any other type |
212 else -- sender is available or unavailable |
219 else -- sender is available or unavailable |
213 for k in pairs(user.sessions) do -- presence broadcast to all user resources |
220 for k in pairs(user.sessions) do -- presence broadcast to all user resources |
214 if user.sessions[k].full_jid then |
221 if user.sessions[k].full_jid then |
215 stanza.attr.to = user.sessions[k].full_jid; |
222 stanza.attr.to = user.sessions[k].full_jid; -- reset at the end of function |
216 send(user.sessions[k], stanza); |
223 send(user.sessions[k], stanza); |
217 end |
224 end |
218 end |
225 end |
219 end |
226 end |
220 elseif stanza.name == "message" then -- select a resource to recieve message |
227 elseif stanza.name == "message" then -- select a resource to recieve message |
229 else |
236 else |
230 -- TODO send IQ error |
237 -- TODO send IQ error |
231 end |
238 end |
232 else |
239 else |
233 -- User + resource is online... |
240 -- User + resource is online... |
234 stanza.attr.to = res.full_jid; |
241 stanza.attr.to = res.full_jid; -- reset at the end of function |
235 send(res, stanza); -- Yay \o/ |
242 send(res, stanza); -- Yay \o/ |
236 end |
243 end |
237 else |
244 else |
238 -- user not online |
245 -- user not online |
239 if user_exists(node, host) then |
246 if user_exists(node, host) then |
240 if stanza.name == "presence" then |
247 if stanza.name == "presence" then |
241 if stanza.attr.type == "probe" and is_authorized_to_see_presence(origin, node, host) then -- FIXME what to do for not c2s? |
248 if stanza.attr.type == "probe" and is_authorized_to_see_presence(origin, node, host) then -- FIXME what to do for not c2s? |
242 -- TODO send last recieved unavailable presence |
249 -- TODO send last recieved unavailable presence (or we MAY do nothing, which is fine too) |
243 else |
250 else |
244 -- TODO send unavailable presence |
251 -- TODO send unavailable presence |
245 end |
252 end |
246 elseif stanza.name == "message" then |
253 elseif stanza.name == "message" then |
247 -- TODO send message error, or store offline messages |
254 -- TODO send message error, or store offline messages |
250 end |
257 end |
251 else -- user does not exist |
258 else -- user does not exist |
252 -- TODO we would get here for nodeless JIDs too. Do something fun maybe? Echo service? Let plugins use xmpp:server/resource addresses? |
259 -- TODO we would get here for nodeless JIDs too. Do something fun maybe? Echo service? Let plugins use xmpp:server/resource addresses? |
253 if stanza.name == "presence" then |
260 if stanza.name == "presence" then |
254 if stanza.attr.type == "probe" then |
261 if stanza.attr.type == "probe" then |
255 send(origin, st.presence({from = stanza.attr.to, to = stanza.attr.from, type = "unsubscribed"})); |
262 send(origin, st.presence({from = to_bare, to = from_bare, type = "unsubscribed"})); |
256 end |
263 end |
257 -- else ignore |
264 -- else ignore |
258 else |
265 else |
259 send(origin, st.error_reply(stanza, "cancel", "service-unavailable")); |
266 send(origin, st.error_reply(stanza, "cancel", "service-unavailable")); |
260 end |
267 end |
261 end |
268 end |
262 end |
269 end |
263 elseif origin.type == "c2s" then |
270 elseif origin.type == "c2s" then |
264 -- Remote host |
271 -- Remote host |
|
272 local xmlns = stanza.attr.xmlns; |
265 --stanza.attr.xmlns = "jabber:server"; |
273 --stanza.attr.xmlns = "jabber:server"; |
266 stanza.attr.xmlns = nil; |
274 stanza.attr.xmlns = nil; |
267 log("debug", "sending s2s stanza: %s", tostring(stanza)); |
275 log("debug", "sending s2s stanza: %s", tostring(stanza)); |
268 send_s2s(origin.host, host, stanza); |
276 send_s2s(origin.host, host, stanza); -- TODO handle remote routing errors |
|
277 stanza.attr.xmlns = xmlns; -- reset |
269 else |
278 else |
270 log("warn", "received stanza from unhandled connection type: %s", origin.type); |
279 log("warn", "received stanza from unhandled connection type: %s", origin.type); |
271 end |
280 end |
272 stanza.attr.to = to; -- reset |
281 stanza.attr.to = to; -- reset |
273 end |
282 end |