@OnWebSocketMessage public void onTextMethod(String stanza) { XMPPPacketReader reader = null; try { reader = readerPool.borrowObject(); Document doc = reader.read(new StringReader(stanza)); if (xmppSession == null) { initiateSession(doc.getRootElement()); } else { processStanza(doc.getRootElement()); } } catch (Exception ex) { Log.error("Failed to process XMPP stanza", ex); } finally { if (reader != null) { readerPool.returnObject(reader); } } }
private static LocalOutgoingServerSession attemptDialbackOverTLS(Connection connection, XMPPPacketReader reader, String localDomain, String remoteDomain, String id) { final Logger log = LoggerFactory.getLogger( Log.getName() + "[Dialback over TLS for: " + localDomain + " to: " + remoteDomain + " (Stream ID: " + id + ")]" ); if (ServerDialback.isEnabled() || ServerDialback.isEnabledForSelfSigned()) { log.debug("Trying to connecting using dialback over TLS."); ServerDialback method = new ServerDialback(connection, localDomain); OutgoingServerSocketReader newSocketReader = new OutgoingServerSocketReader(reader); if (method.authenticateDomain(newSocketReader, localDomain, remoteDomain, id)) { log.debug("Dialback over TLS was successful."); StreamID streamID = new BasicStreamIDFactory().createStreamID(id); LocalOutgoingServerSession session = new LocalOutgoingServerSession(localDomain, connection, newSocketReader, streamID); connection.init(session); // Set the hostname as the address of the session session.setAddress(new JID(null, remoteDomain, null)); return session; } else { log.debug("Dialback over TLS failed"); return null; } } else { log.debug("Skipping server dialback attempt as it has been disabled by local configuration."); return null; } }
/** * Creates a dedicated reader for a socket. * * @param router the router for sending packets that were read. * @param routingTable the table that keeps routes to registered services. * @param serverName the name of the server this socket is working for. * @param socket the socket to read from. * @param connection the connection being read. * @param useBlockingMode true means that the server will use a thread per connection. */ public SocketReader(PacketRouter router, RoutingTable routingTable, String serverName, Socket socket, SocketConnection connection, boolean useBlockingMode) { this.serverName = serverName; this.router = router; this.routingTable = routingTable; this.connection = connection; connection.setSocketReader(this); // Reader is associated with a new XMPPPacketReader reader = new XMPPPacketReader(); reader.setXPPFactory(factory); // Set the blocking reading mode to use readingMode = new BlockingReadingMode(socket, this); }
@Override public void messageReceived(IoSession session, Object message) throws Exception { // Get the stanza handler for this session StanzaHandler handler = (StanzaHandler) session.getAttribute(HANDLER); // Get the parser to use to process stanza. For optimization there is going // to be a parser for each running thread. Each Filter will be executed // by the Executor placed as the first Filter. So we can have a parser associated // to each Thread final XMPPPacketReader parser = PARSER_CACHE.get(); // Update counter of read btyes updateReadBytesCounter(session); //System.out.println("RCVD: " + message); // Let the stanza handler process the received stanza try { handler.process((String) message, parser); } catch (Exception e) { Log.error("Closing connection due to error while processing message: " + message, e); final Connection connection = (Connection) session.getAttribute(CONNECTION); if ( connection != null ) { connection.close(); } } }
private static LocalOutgoingServerSession attemptDialbackOverTLS(Connection connection, XMPPPacketReader reader, String domain, String hostname, String id) { final Logger log = LoggerFactory.getLogger(LocalOutgoingServerSession.class.getName()+"['"+hostname+"']"); if (ServerDialback.isEnabled() || ServerDialback.isEnabledForSelfSigned()) { log.debug("Trying to connecting using dialback over TLS."); ServerDialback method = new ServerDialback(connection, domain); OutgoingServerSocketReader newSocketReader = new OutgoingServerSocketReader(reader); if (method.authenticateDomain(newSocketReader, domain, hostname, id)) { log.debug("Dialback over TLS was successful."); StreamID streamID = new BasicStreamIDFactory().createStreamID(id); LocalOutgoingServerSession session = new LocalOutgoingServerSession(domain, connection, newSocketReader, streamID); connection.init(session); // Set the hostname as the address of the session session.setAddress(new JID(null, hostname, null)); return session; } else { log.debug("Dialback over TLS failed"); return null; } } else { log.debug("Skipping server dialback attempt as it has been disabled by local configuration."); return null; } }
private synchronized void initializePool() { if (readerPool == null) { readerPool = new GenericObjectPool<XMPPPacketReader>(new XMPPPPacketReaderFactory()); readerPool.setMaxTotal(-1); readerPool.setBlockWhenExhausted(false); readerPool.setTestOnReturn(true); readerPool.setTimeBetweenEvictionRunsMillis(JiveConstants.MINUTE); } }
@Override public boolean validateObject(PooledObject<XMPPPacketReader> po) { // reset the input for the pooled parser try { po.getObject().getXPPParser().resetInput(); return true; } catch (XmlPullParserException xppe) { Log.error("Failed to reset pooled parser; evicting from pool", xppe); return false; } }
private static LocalOutgoingServerSession attemptSASLexternal(SocketConnection connection, MXParser xpp, XMPPPacketReader reader, String localDomain, String remoteDomain, String id, StringBuilder openingStream) throws DocumentException, IOException, XmlPullParserException { final Logger log = LoggerFactory.getLogger( Log.getName() + "[EXTERNAL SASL for: " + localDomain + " to: " + remoteDomain + " (Stream ID: " + id + ")]" ); log.debug("Starting EXTERNAL SASL."); if (doExternalAuthentication(localDomain, connection, reader)) { log.debug("EXTERNAL SASL was successful."); // SASL was successful so initiate a new stream connection.deliverRawText(openingStream.toString()); // Reset the parser //xpp.resetInput(); // // Reset the parser to use the new secured reader xpp.setInput(new InputStreamReader(connection.getTLSStreamHandler().getInputStream(), StandardCharsets.UTF_8)); // Skip the opening stream sent by the server for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) { eventType = xpp.next(); } // SASL authentication was successful so create new OutgoingServerSession id = xpp.getAttributeValue("", "id"); StreamID streamID = new BasicStreamIDFactory().createStreamID(id); LocalOutgoingServerSession session = new LocalOutgoingServerSession(localDomain, connection, new OutgoingServerSocketReader(reader), streamID); connection.init(session); // Set the hostname as the address of the session session.setAddress(new JID(null, remoteDomain, null)); // Set that the session was created using TLS+SASL (no server dialback) session.usingServerDialback = false; return session; } else { log.debug("EXTERNAL SASL failed."); return null; } }
private static boolean doExternalAuthentication(String localDomain, SocketConnection connection, XMPPPacketReader reader) throws DocumentException, IOException, XmlPullParserException { StringBuilder sb = new StringBuilder(); sb.append("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"EXTERNAL\">"); sb.append(StringUtils.encodeBase64(localDomain)); sb.append("</auth>"); connection.deliverRawText(sb.toString()); Element response = reader.parseDocument().getRootElement(); return response != null && "success".equals(response.getName()); }
@Override protected XMPPPacketReader initialValue() { XMPPPacketReader parser = new XMPPPacketReader(); factory.setNamespaceAware(true); parser.setXPPFactory(factory); return parser; }
@Override protected XMPPPacketReader initialValue() { final XMPPPacketReader parser = new XMPPPacketReader(); parser.setXPPFactory( factory ); return parser; }
public void process(String stanza, XMPPPacketReader reader) throws Exception { boolean initialStream = stanza.startsWith("<stream:stream"); if (!sessionCreated || initialStream) { if (!initialStream) { // Ignore <?xml version="1.0"?> return; } // Found an stream:stream tag... if (!sessionCreated) { sessionCreated = true; MXParser parser = reader.getXPPParser(); parser.setInput(new StringReader(stanza)); createSession(parser); } return; } // Verify if end of stream was requested if (stanza.equals("</stream:stream>")) { session.close(); return; } // Ignore <?xml version="1.0"?> stanzas sent by clients if (stanza.startsWith("<?xml")) { return; } // Create DOM object from received stanza Element doc = reader.read(new StringReader(stanza)).getRootElement(); if (doc == null) { return; } process(doc); }
public void process(String stanza, XMPPPacketReader reader) throws Exception { boolean initialStream = stanza.startsWith("<stream:stream"); if (!sessionCreated || initialStream) { if (!initialStream) { return; // Ignore <?xml version="1.0"?> } if (!sessionCreated) { sessionCreated = true; MXParser parser = reader.getXPPParser(); parser.setInput(new StringReader(stanza)); createSession(parser); } return; } // If end of stream was requested if (stanza.equals("</stream:stream>")) { session.close(); return; } // Ignore <?xml version="1.0"?> if (stanza.startsWith("<?xml")) { return; } // Create DOM object Element doc = reader.read(new StringReader(stanza)).getRootElement(); if (doc == null) { return; } processDoc(doc); }
private static LocalOutgoingServerSession attemptSASLexternal(SocketConnection connection, MXParser xpp, XMPPPacketReader reader, String domain, String hostname, String id, StringBuilder openingStream) throws DocumentException, IOException, XmlPullParserException { final Logger log = LoggerFactory.getLogger(LocalOutgoingServerSession.class.getName()+"['"+hostname+"']"); log.debug("Starting EXTERNAL SASL."); if (doExternalAuthentication(domain, connection, reader)) { log.debug("EXTERNAL SASL was successful."); // SASL was successful so initiate a new stream connection.deliverRawText(openingStream.toString()); // Reset the parser xpp.resetInput(); // Skip the opening stream sent by the server for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) { eventType = xpp.next(); } // SASL authentication was successful so create new OutgoingServerSession id = xpp.getAttributeValue("", "id"); StreamID streamID = new BasicStreamIDFactory().createStreamID(id); LocalOutgoingServerSession session = new LocalOutgoingServerSession(domain, connection, new OutgoingServerSocketReader(reader), streamID); connection.init(session); // Set the hostname as the address of the session session.setAddress(new JID(null, hostname, null)); // Set that the session was created using TLS+SASL (no server dialback) session.usingServerDialback = false; return session; } else { log.debug("EXTERNAL SASL failed."); return null; } }
private static boolean doExternalAuthentication(String domain, SocketConnection connection, XMPPPacketReader reader) throws DocumentException, IOException, XmlPullParserException { StringBuilder sb = new StringBuilder(); sb.append("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"EXTERNAL\">"); sb.append(StringUtils.encodeBase64(domain)); sb.append("</auth>"); connection.deliverRawText(sb.toString()); Element response = reader.parseDocument().getRootElement(); return response != null && "success".equals(response.getName()); }
private boolean secureConnection(XMPPPacketReader reader, StringBuilder openingStream) throws Exception { Log.debug("CM - Indicating we want TLS to " + serverName); connection.deliverRawText("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"); MXParser xpp = reader.getXPPParser(); // Wait for the <proceed> response Element proceed = reader.parseDocument().getRootElement(); if (proceed != null && proceed.getName().equals("proceed")) { Log.debug("CM - Negotiating TLS with " + serverName); connection.startTLS(true, serverName); Log.debug("CM - TLS negotiation with " + serverName + " was successful"); // TLS negotiation was successful so initiate a new stream connection.deliverRawText(openingStream.toString()); // Reset the parser to use the new secured reader xpp.setInput( new InputStreamReader(connection.getTLSStreamHandler().getInputStream(), CHARSET)); // Skip new stream element for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) { eventType = xpp.next(); } // Get new stream features features = reader.parseDocument().getRootElement(); return true; } else { Log.debug("CM - Error, <proceed> was not received"); } return false; }
private boolean doHandshake(String streamID, XMPPPacketReader reader) throws Exception { String password = JiveGlobals.getXMLProperty("xmpp.password"); if (password == null) { // No password was configued in the connection manager Log.debug("CM - No password was found. Configure xmpp.password property"); return false; } MessageDigest digest; // Create a message digest instance. try { digest = MessageDigest.getInstance("SHA"); } catch (NoSuchAlgorithmException e) { Log.error(LocaleUtils.getLocalizedString("admin.error"), e); return false; } digest.update(streamID.getBytes()); String key = StringUtils.encodeHex(digest.digest(password.getBytes())); Log.debug("OS - Sent handshake to host: " + serverName + " id: " + streamID); // Send handshake to server StringBuilder sb = new StringBuilder(); sb.append("<handshake>").append(key).append("</handshake>"); connection.deliverRawText(sb.toString()); // Wait for the <handshake> response Element proceed = reader.parseDocument().getRootElement(); if (proceed != null && proceed.getName().equals("handshake")) { Log.debug("OS - Handshake was SUCCESSFUL with host: " + serverName + " id: " + streamID); return true; } Log.debug("OS - Handshake FAILED with host: " + serverName + " id: " + streamID); return false; }
public void testEmptyElement() throws Exception { String stanza = "<message/>"; XmlPullParserFactory factory = XmlPullParserFactory.newInstance(MXParser.class.getName(), null); factory.setNamespaceAware(true); XMPPPacketReader xmppReader = new XMPPPacketReader(); xmppReader.setXPPFactory(factory); Element doc = xmppReader.read(new StringReader(stanza)).getRootElement(); assertNotNull(doc); assertEquals(stanza, doc.asXML()); }