1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* $RCSfile: ComponentSocketReader.java,v $
* $Revision: 3174 $
* $Date: 2005-12-08 17:41:00 -0300 (Thu, 08 Dec 2005) $
*
* Copyright (C) 2007 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.openfire.net;
import org.dom4j.Element;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.RoutingTable;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.component.InternalComponentManager;
import org.jivesoftware.openfire.session.ComponentSession;
import org.jivesoftware.openfire.session.LocalComponentSession;
import org.jivesoftware.util.Log;
import org.xmlpull.v1.XmlPullParserException;
import org.xmpp.component.ComponentException;
import org.xmpp.packet.PacketError;
import java.io.IOException;
import java.net.Socket;
/**
* A SocketReader specialized for component connections. This reader will be used when the open
* stream contains a jabber:component:accept namespace.
*
* @author Gaston Dombiak
*/
public class ComponentSocketReader extends SocketReader {
public ComponentSocketReader(PacketRouter router, RoutingTable routingTable, String serverName,
Socket socket, SocketConnection connection, boolean useBlockingMode) {
super(router, routingTable, serverName, socket, connection, useBlockingMode);
}
/**
* Only <tt>bind<tt> packets will be processed by this class to bind more domains
* to existing external components. Any other type of packet is unknown and thus
* rejected generating the connection to be closed.
*
* @param doc the unknown DOM element that was received
* @return false if packet is unknown otherwise true.
*/
protected boolean processUnknowPacket(Element doc) {
// Handle subsequent bind packets
if ("bind".equals(doc.getName())) {
LocalComponentSession componentSession = (LocalComponentSession) session;
// Get the external component of this session
ComponentSession.ExternalComponent component = componentSession.getExternalComponent();
String initialDomain = component.getInitialSubdomain();
String extraDomain = doc.attributeValue("name");
if (extraDomain == null || "".equals(extraDomain)) {
// No new bind domain was specified so return a bad_request error
Element reply = doc.createCopy();
reply.add(new PacketError(PacketError.Condition.bad_request).getElement());
connection.deliverRawText(reply.asXML());
}
else if (extraDomain.equals(initialDomain)) {
// Component is binding initial domain that is already registered
// Send confirmation that the new domain has been registered
connection.deliverRawText("<bind/>");
}
else if (extraDomain.endsWith(initialDomain)) {
// Only accept subdomains under the initial registered domain
if (component.getSubdomains().contains(extraDomain)) {
// Domain already in use so return a conflict error
Element reply = doc.createCopy();
reply.add(new PacketError(PacketError.Condition.conflict).getElement());
connection.deliverRawText(reply.asXML());
}
else {
try {
// Get the requested subdomain
String subdomain = extraDomain;
int index = extraDomain.indexOf(serverName);
if (index > -1) {
subdomain = extraDomain.substring(0, index -1);
}
InternalComponentManager.getInstance().addComponent(subdomain, component);
// Send confirmation that the new domain has been registered
connection.deliverRawText("<bind/>");
}
catch (ComponentException e) {
Log.error("Error binding extra domain: " + extraDomain + " to component: " +
component, e);
// Return internal server error
Element reply = doc.createCopy();
reply.add(new PacketError(
PacketError.Condition.internal_server_error).getElement());
connection.deliverRawText(reply.asXML());
}
}
}
else {
// Return forbidden error since we only allow subdomains of the intial domain
// to be used by the same external component
Element reply = doc.createCopy();
reply.add(new PacketError(PacketError.Condition.forbidden).getElement());
connection.deliverRawText(reply.asXML());
}
return true;
}
// This is an unknown packet so return false (and close the connection)
return false;
}
boolean createSession(String namespace) throws UnauthorizedException, XmlPullParserException,
IOException {
if ("jabber:component:accept".equals(namespace)) {
// The connected client is a component so create a ComponentSession
session = LocalComponentSession.createSession(serverName, reader, connection);
return true;
}
return false;
}
String getNamespace() {
return "jabber:component:accept";
}
String getName() {
return "Component SR - " + hashCode();
}
boolean validateHost() {
return false;
}
}