use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.
the class MessageRouter method route.
/**
* <p>Performs the actual packet routing.</p>
* <p>You routing is considered 'quick' and implementations may not take
* excessive amounts of time to complete the routing. If routing will take
* a long amount of time, the actual routing should be done in another thread
* so this method returns quickly.</p>
* <h2>Warning</h2>
* <p>Be careful to enforce concurrency DbC of concurrent by synchronizing
* any accesses to class resources.</p>
*
* @param packet The packet to route
* @throws NullPointerException If the packet is null
*/
public void route(Message packet) {
if (packet == null) {
throw new NullPointerException();
}
ClientSession session = sessionManager.getSession(packet.getFrom());
try {
// Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false);
if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
JID recipientJID = packet.getTo();
// If the server receives a message stanza with no 'to' attribute, it MUST treat the message as if the 'to' address were the bare JID <localpart@domainpart> of the sending entity.
if (recipientJID == null) {
recipientJID = packet.getFrom().asBareJID();
}
// Check if the message was sent to the server hostname
if (recipientJID.getNode() == null && recipientJID.getResource() == null && serverName.equals(recipientJID.getDomain())) {
if (packet.getElement().element("addresses") != null) {
// Message includes multicast processing instructions. Ask the multicastRouter
// to route this packet
multicastRouter.route(packet);
} else {
// Message was sent to the server hostname so forward it to a configurable
// set of JID's (probably admin users)
sendMessageToAdmins(packet);
}
return;
}
boolean isAcceptable = true;
if (session instanceof LocalClientSession) {
// Check if we could process messages from the recipient.
// If not, return a not-acceptable error as per XEP-0016:
// If the user attempts to send an outbound stanza to a contact and that stanza type is blocked, the user's server MUST NOT route the stanza to the contact but instead MUST return a <not-acceptable/> error
Message dummyMessage = packet.createCopy();
dummyMessage.setFrom(packet.getTo());
dummyMessage.setTo(packet.getFrom());
if (!((LocalClientSession) session).canProcess(dummyMessage)) {
packet.setTo(session.getAddress());
packet.setFrom((JID) null);
packet.setError(PacketError.Condition.not_acceptable);
session.process(packet);
isAcceptable = false;
}
}
if (isAcceptable) {
boolean isPrivate = packet.getElement().element(QName.get("private", "urn:xmpp:carbons:2")) != null;
try {
// Deliver stanza to requested route
routingTable.routePacket(recipientJID, packet, false);
} catch (Exception e) {
log.error("Failed to route packet: " + packet.toXML(), e);
routingFailed(recipientJID, packet);
}
// When a client sends a <message/> of type "chat"
if (packet.getType() == Message.Type.chat && !isPrivate && session != null) {
// && session.isMessageCarbonsEnabled() ??? // must the own session also be carbon enabled?
List<JID> routes = routingTable.getRoutes(packet.getFrom().asBareJID(), null);
for (JID route : routes) {
// The sending server SHOULD NOT send a forwarded copy to the sending full JID if it is a Carbons-enabled resource.
if (!route.equals(session.getAddress())) {
ClientSession clientSession = sessionManager.getSession(route);
if (clientSession != null && clientSession.isMessageCarbonsEnabled()) {
Message message = new Message();
// The wrapping message SHOULD maintain the same 'type' attribute value
message.setType(packet.getType());
// the 'from' attribute MUST be the Carbons-enabled user's bare JID
message.setFrom(packet.getFrom().asBareJID());
// and the 'to' attribute SHOULD be the full JID of the resource receiving the copy
message.setTo(route);
// The content of the wrapping message MUST contain a <sent/> element qualified by the namespace "urn:xmpp:carbons:2", which itself contains a <forwarded/> qualified by the namespace "urn:xmpp:forward:0" that contains the original <message/> stanza.
message.addExtension(new Sent(new Forwarded(packet)));
clientSession.process(message);
}
}
}
}
}
} else {
packet.setTo(session.getAddress());
packet.setFrom((JID) null);
packet.setError(PacketError.Condition.not_authorized);
session.process(packet);
}
// Invoke the interceptors after we have processed the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true);
} catch (PacketRejectedException e) {
// An interceptor rejected this packet
if (session != null && e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
// A message for the rejection will be sent to the sender of the rejected packet
Message reply = new Message();
reply.setID(packet.getID());
reply.setTo(session.getAddress());
reply.setFrom(packet.getTo());
reply.setType(packet.getType());
reply.setThread(packet.getThread());
reply.setBody(e.getRejectionMessage());
session.process(reply);
}
}
}
use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.
the class MultiplexerPacketHandler method route.
/**
* Processes a route packet that is wrapping a stanza sent by a client that is connected
* to the connection manager.
*
* @param route the route packet.
*/
public void route(Route route) {
StreamID streamID = route.getStreamID();
if (streamID == null) {
// No stream ID was included so return a bad_request error
Element extraError = DocumentHelper.createElement(QName.get("id-required", "http://jabber.org/protocol/connectionmanager#errors"));
sendErrorPacket(route, PacketError.Condition.bad_request, extraError);
}
LocalClientSession session = multiplexerManager.getClientSession(connectionManagerDomain, streamID);
if (session == null) {
// Specified Client Session does not exist
sendErrorPacket(route, PacketError.Condition.item_not_found, null);
return;
}
SessionPacketRouter router = new SessionPacketRouter(session);
// Connection Manager already validate JIDs so just skip this expensive operation
router.setSkipJIDValidation(true);
try {
router.route(route.getChildElement());
} catch (UnknownStanzaException use) {
Element extraError = DocumentHelper.createElement(QName.get("unknown-stanza", "http://jabber.org/protocol/connectionmanager#errors"));
sendErrorPacket(route, PacketError.Condition.bad_request, extraError);
} catch (Exception e) {
Log.error("Error processing wrapped packet: " + route.getChildElement().asXML(), e);
sendErrorPacket(route, PacketError.Condition.internal_server_error, null);
}
}
use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.
the class SessionManager method createClientSession.
/**
* Creates a new <tt>ClientSession</tt> with the specified streamID.
*
* @param conn the connection to create the session from.
* @param id the streamID to use for the new session.
* @param language The language to use for the new session.
* @return a newly created session.
*/
public LocalClientSession createClientSession(Connection conn, StreamID id, Locale language) {
if (serverName == null) {
throw new IllegalStateException("Server not initialized");
}
LocalClientSession session = new LocalClientSession(serverName, conn, id, language);
conn.init(session);
// Register to receive close notification on this session so we can
// remove and also send an unavailable presence if it wasn't
// sent before
conn.registerCloseListener(clientSessionListener, session);
// Add to pre-authenticated sessions.
localSessionManager.getPreAuthenticatedSessions().put(session.getAddress().getResource(), session);
// Increment the counter of user sessions
connectionsCounter.incrementAndGet();
return session;
}
use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.
the class SessionManager method broadcastPresenceOfOtherResource.
/**
* Sends the presences of other connected resources to the resource that just connected.
*
* @param session the newly created session.
*/
private void broadcastPresenceOfOtherResource(LocalClientSession session) {
if (!SessionManager.isOtherResourcePresenceEnabled()) {
return;
}
Presence presence;
// Get list of sessions of the same user
JID searchJID = new JID(session.getAddress().getNode(), session.getAddress().getDomain(), null);
List<JID> addresses = routingTable.getRoutes(searchJID, null);
for (JID address : addresses) {
if (address.equals(session.getAddress())) {
continue;
}
// Send the presence of an existing session to the session that has just changed
// the presence
ClientSession userSession = routingTable.getClientRoute(address);
presence = userSession.getPresence().createCopy();
presence.setTo(session.getAddress());
session.process(presence);
}
}
use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.
the class SaslServerFactoryImpl method createSaslServer.
@Override
public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map<String, ?> props, CallbackHandler cbh) throws SaslException {
if (!Arrays.asList(getMechanismNames(props)).contains(mechanism)) {
Log.debug("This implementation is unable to create a SaslServer instance for the {} mechanism using the provided properties.", mechanism);
return null;
}
switch(mechanism.toUpperCase()) {
case "PLAIN":
if (cbh == null) {
Log.debug("Unable to instantiate {} SaslServer: A callbackHandler with support for Password, Name, and AuthorizeCallback required.", mechanism);
return null;
}
return new SaslServerPlainImpl(protocol, serverName, props, cbh);
case "SCRAM-SHA-1":
return new ScramSha1SaslServer();
case "ANONYMOUS":
if (!props.containsKey(LocalSession.class.getCanonicalName())) {
Log.debug("Unable to instantiate {} SaslServer: Provided properties do not contain a LocalSession instance.", mechanism);
return null;
} else {
final LocalSession session = (LocalSession) props.get(LocalSession.class.getCanonicalName());
return new AnonymousSaslServer(session);
}
case "EXTERNAL":
if (!props.containsKey(LocalSession.class.getCanonicalName())) {
Log.debug("Unable to instantiate {} SaslServer: Provided properties do not contain a LocalSession instance.", mechanism);
return null;
} else {
final Object session = props.get(LocalSession.class.getCanonicalName());
if (session instanceof LocalClientSession) {
return new ExternalClientSaslServer((LocalClientSession) session);
}
if (session instanceof LocalIncomingServerSession) {
return new ExternalServerSaslServer((LocalIncomingServerSession) session);
}
Log.debug("Unable to instantiate {} Sasl Server: Provided properties contains neither LocalClientSession nor LocalIncomingServerSession instance.", mechanism);
return null;
}
case JiveSharedSecretSaslServer.NAME:
return new JiveSharedSecretSaslServer();
default:
// Fail fast - this should not be possible, as the first check in this method already verifies wether the mechanism is supported.
throw new IllegalStateException();
}
}
Aggregations