1 /*
2  * Copyright (C) 2005-2008 Jive Software. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.jivesoftware.openfire;
17 
18 import org.dom4j.Element;
19 import org.jivesoftware.openfire.multiplex.UnknownStanzaException;
20 import org.jivesoftware.openfire.net.SASLAuthentication;
21 import org.jivesoftware.openfire.session.LocalClientSession;
22 import org.xmpp.packet.*;
23 
24 /**
25  * Handles the routing of packets to a particular session. It will invoke all of the appropriate
26  * interceptors, before and after having the server process the message.
27  *
28  * @author Alexander Wenckus
29  */
30 public class SessionPacketRouter implements PacketRouter {
31 
32     protected LocalClientSession session;
33     private PacketRouter router;
34     private boolean skipJIDValidation = false;
35 
SessionPacketRouter(LocalClientSession session)36     public SessionPacketRouter(LocalClientSession session) {
37         this.session = session;
38         router = XMPPServer.getInstance().getPacketRouter();
39     }
40 
41     /**
42      * Sets if TO addresses of Elements being routed should be validated. Doing stringprep operations
43      * is very expensive and sometimes we already validated the TO address so there is no need to
44      * validate again the address. For instance, when using Connection Managers the validation
45      * is done by the Connection Manager so we can just trust the TO address. On the other hand,
46      * the FROM address is set by the server so there is no need to validate it.<p>
47      *
48      * By default validation is enabled.
49      *
50      * @param skipJIDValidation true if validation of TO address is enabled.
51      */
setSkipJIDValidation(boolean skipJIDValidation)52     public void setSkipJIDValidation(boolean skipJIDValidation) {
53         this.skipJIDValidation = skipJIDValidation;
54     }
55 
route(Element wrappedElement)56     public void route(Element wrappedElement)
57             throws UnknownStanzaException {
58         String tag = wrappedElement.getName();
59         if ("auth".equals(tag) || "response".equals(tag)) {
60             SASLAuthentication.handle(session, wrappedElement);
61         }
62         else if ("iq".equals(tag)) {
63             route(getIQ(wrappedElement));
64         }
65         else if ("message".equals(tag)) {
66             route(new Message(wrappedElement, skipJIDValidation));
67         }
68         else if ("presence".equals(tag)) {
69             route(new Presence(wrappedElement, skipJIDValidation));
70         }
71         else {
72             throw new UnknownStanzaException();
73         }
74     }
75 
getIQ(Element doc)76     private IQ getIQ(Element doc) {
77         Element query = doc.element("query");
78         if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) {
79             return new Roster(doc);
80         }
81         else {
82             return new IQ(doc, skipJIDValidation);
83         }
84     }
85 
86     @Override
route(Packet packet)87     public void route(Packet packet) {
88         // Security: Don't allow users to send packets on behalf of other users
89         packet.setFrom(session.getAddress());
90         if(packet instanceof IQ) {
91             route((IQ)packet);
92         }
93         else if(packet instanceof Message) {
94             route((Message)packet);
95         }
96         else if(packet instanceof Presence) {
97             route((Presence)packet);
98         }
99     }
100 
101     @Override
route(IQ packet)102     public void route(IQ packet) {
103         packet.setFrom(session.getAddress());
104         router.route(packet);
105         session.incrementClientPacketCount();
106     }
107 
108     @Override
route(Message packet)109     public void route(Message packet) {
110         packet.setFrom(session.getAddress());
111         router.route(packet);
112         session.incrementClientPacketCount();
113     }
114 
115     @Override
route(Presence packet)116     public void route(Presence packet) {
117         packet.setFrom(session.getAddress());
118         router.route(packet);
119         session.incrementClientPacketCount();
120     }
121 }
122