use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.
the class SessionManager method createComponentSession.
public LocalComponentSession createComponentSession(JID address, Connection conn) {
if (serverName == null) {
throw new IllegalStateException("Server not initialized");
}
StreamID id = nextStreamID();
LocalComponentSession session = new LocalComponentSession(serverName, conn, id);
conn.init(session);
// Register to receive close notification on this session so we can
// remove the external component from the list of components
conn.registerCloseListener(componentSessionListener, session);
// Set the bind address as the address of the session
session.setAddress(address);
// Add to component session.
localSessionManager.getComponentsSessions().add(session);
// Keep track of the cluster node hosting the new external component
componentSessionsCache.put(address.toString(), server.getNodeID().toByteArray());
return session;
}
use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.
the class ComponentStanzaHandler method processUnknowPacket.
@Override
boolean processUnknowPacket(Element doc) throws UnauthorizedException {
String tag = doc.getName();
if ("handshake".equals(tag)) {
// External component is trying to authenticate
if (!((LocalComponentSession) session).authenticate(doc.getStringValue())) {
Log.debug("Closing session that failed to authenticate: {}", session);
session.close();
}
return true;
} else if ("error".equals(tag) && "stream".equals(doc.getNamespacePrefix())) {
Log.debug("Closing session because of received stream error {}. Affected session: {}", doc.asXML(), session);
session.close();
return true;
} else if ("bind".equals(tag)) {
// Handle subsequent bind packets
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");
String allowMultiple = doc.attributeValue("allowMultiple");
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 (allowMultiple != null && 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
final String subdomain;
int index = extraDomain.indexOf(XMPPServer.getInstance().getServerInfo().getXMPPDomain());
if (index > -1) {
subdomain = extraDomain.substring(0, index - 1);
} else {
subdomain = extraDomain;
}
InternalComponentManager.getInstance().addComponent(subdomain, component);
session.getConnection().registerCloseListener(handback -> InternalComponentManager.getInstance().removeComponent(subdomain, (ComponentSession.ExternalComponent) handback), 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;
}
return false;
}
use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.
the class ComponentStanzaHandler method processIQ.
@Override
protected void processIQ(IQ packet) throws UnauthorizedException {
if (session.getStatus() != Session.STATUS_AUTHENTICATED) {
// Session is not authenticated so return error
IQ reply = new IQ();
reply.setChildElement(packet.getChildElement().createCopy());
reply.setID(packet.getID());
reply.setTo(packet.getFrom());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.not_authorized);
session.process(reply);
return;
}
// Keep track of the component that sent an IQ get/set
if (packet.getType() == IQ.Type.get || packet.getType() == IQ.Type.set) {
// Handle subsequent bind packets
LocalComponentSession componentSession = (LocalComponentSession) session;
// Get the external component of this session
LocalComponentSession.LocalExternalComponent component = (LocalComponentSession.LocalExternalComponent) componentSession.getExternalComponent();
component.track(packet);
}
super.processIQ(packet);
}
use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.
the class InternalComponentManager method process.
/**
* Processes packets that were sent to this service. Currently only packets that were sent from
* registered components are being processed. In the future, we may also process packet of
* trusted clients. Trusted clients may be able to execute ad-hoc commands such as adding or
* removing components.
*
* @param packet the packet to process.
*/
@Override
public void process(Packet packet) throws PacketException {
List<Component> components = getComponents(packet.getFrom());
// Only process packets that were sent by registered components
if (!components.isEmpty()) {
if (packet instanceof IQ && IQ.Type.result == ((IQ) packet).getType()) {
IQ iq = (IQ) packet;
Element childElement = iq.getChildElement();
if (childElement != null) {
String namespace = childElement.getNamespaceURI();
if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
// Add a disco item to the server for the component that supports disco
Element identity = childElement.element("identity");
if (identity == null) {
// Do nothing since there are no identities in the disco#info packet
return;
}
try {
XMPPServer.getInstance().getIQDiscoItemsHandler().addComponentItem(packet.getFrom().toBareJID(), identity.attributeValue("name"));
for (Component component : components) {
if (component instanceof ComponentSession.ExternalComponent) {
ComponentSession.ExternalComponent externalComponent = (ComponentSession.ExternalComponent) component;
externalComponent.setName(identity.attributeValue("name"));
externalComponent.setType(identity.attributeValue("type"));
externalComponent.setCategory(identity.attributeValue("category"));
}
}
} catch (Exception e) {
Log.error("Error processing disco packet of components: " + components + " - " + packet.toXML(), e);
}
// Store the IQ disco#info returned by the component
addComponentInfo(iq);
// Notify listeners that a component answered the disco#info request
notifyComponentInfo(iq);
// Alert other cluster nodes
CacheFactory.doClusterTask(new NotifyComponentInfo(iq));
} else if ("query".equals(childElement.getQName().getName()) && "jabber:iq:version".equals(namespace)) {
try {
List<Element> elements = childElement.elements();
for (Component component : components) {
if (component instanceof LocalComponentSession.LocalExternalComponent) {
LocalComponentSession.LocalExternalComponent externalComponent = (LocalComponentSession.LocalExternalComponent) component;
LocalComponentSession session = externalComponent.getSession();
if (session != null && session.getAddress() == iq.getFrom()) {
if (elements.size() > 0) {
for (Element element : elements) {
session.setSoftwareVersionData(element.getName(), element.getStringValue());
}
}
}
}
}
} catch (Exception e) {
Log.error(e.getMessage(), e);
}
} else if ("query".equals(childElement.getQName().getName()) && "http://jabber.org/protocol/disco#info".equals(namespace)) {
// XEP-0232 if responses service discovery can include detailed information about the software application
for (Component component : components) {
if (component instanceof LocalComponentSession.LocalExternalComponent) {
LocalComponentSession.LocalExternalComponent externalComponent = (LocalComponentSession.LocalExternalComponent) component;
LocalComponentSession session = externalComponent.getSession();
if (session != null && session.getAddress() == iq.getFrom()) {
IQDiscoInfoHandler.setSoftwareVersionDataFormFromDiscoInfo(childElement, session);
}
}
}
}
}
}
}
}
Aggregations