private void initDialback(S2SIOService serv, String remote_id) { try { CID cid = (CID) serv.getSessionData().get("cid"); String secret = handler.getSecretForDomain(cid.getLocalHost()); String key = Algorithms.generateDialbackKey( cid.getLocalHost(), cid.getRemoteHost(), secret, remote_id); if (!serv.isHandshakingOnly()) { Element elem = new Element( DB_RESULT_EL_NAME, key, new String[] {XMLNS_DB_ATT}, new String[] {XMLNS_DB_VAL}); addToResultRequested(serv, cid.getRemoteHost()); serv.getS2SConnection() .addControlPacket( Packet.packetInstance( elem, JID.jidInstanceNS(cid.getLocalHost()), JID.jidInstanceNS(cid.getRemoteHost()))); } serv.getS2SConnection().sendAllControlPackets(); } catch (NotLocalhostException ex) { generateStreamError(false, "host-unknown", serv); } }
private void processDialback(Packet p, S2SIOService serv) { // Get the cid for which the connection has been created, the cid calculated // from the packet may be different though if the remote server tries to // multiplexing CID cid_main = (CID) serv.getSessionData().get("cid"); CID cid_packet = new CID(p.getStanzaTo().getDomain(), p.getStanzaFrom().getDomain()); if (log.isLoggable(Level.FINEST)) { log.log( Level.FINEST, "{0}, DIALBACK packet: {1}, CID_packet: {2}", new Object[] {serv, p, cid_packet}); } CIDConnections cid_conns = null; // Some servers (ejabberd) do not send from/to attributes in the stream:open // which // violates the spec, they seem not to care though, so here we handle the // case. if (cid_main == null) { // This actually can only happen for 'accept' connection type // what we did not get in stream open we can get from here cid_main = cid_packet; serv.getSessionData().put("cid", cid_main); // For debuging purposes only.... serv.getSessionData().put("local-hostname", cid_main.getLocalHost()); serv.getSessionData().put("remote-hostname", cid_main.getRemoteHost()); } try { cid_conns = handler.getCIDConnections(cid_main, true); } catch (NotLocalhostException ex) { log.log(Level.FINER, "{0} Incorrect local hostname: {1}", new Object[] {serv, p}); generateStreamError(false, "host-unknown", serv); return; } catch (LocalhostException ex) { log.log(Level.FINER, "{0} Incorrect remote hostname: {1}", new Object[] {serv, p}); generateStreamError(false, "invalid-from", serv); return; } if (serv.connectionType() == ConnectionType.accept) { cid_conns.addIncoming(serv); } String remote_key = p.getElemCData(); // Dummy dialback implementation for now.... if ((p.getElemName() == RESULT_EL_NAME) || (p.getElemName() == DB_RESULT_EL_NAME)) { if (p.getType() == null) { CID cid = (CID) serv.getSessionData().get("cid"); boolean skipTls = this.skipTLSForHost(cid.getRemoteHost()); if (!skipTls && !serv.getSessionData().containsKey("TLS") && handler.isTlsRequired(cid.getLocalHost())) { log.log( Level.FINER, "{0}, rejecting S2S connection from {1} to {2} due to policy violation - STARTTLS is required", new Object[] {serv, cid.getRemoteHost(), cid.getLocalHost()}); handler.sendVerifyResult( DB_RESULT_EL_NAME, cid_main, cid_packet, false, null, serv.getSessionId(), null, false, new Element( "error", new Element[] { new Element( "policy-violation", new String[] {"xmlns"}, new String[] {"urn:ietf:params:xml:ns:xmpp-stanzas"}) }, new String[] {"type"}, new String[] {"cancel"})); } else { String conn_sessionId = serv.getSessionId(); handler.sendVerifyResult( DB_VERIFY_EL_NAME, cid_main, cid_packet, null, conn_sessionId, null, p.getElemCData(), true); } } else { if (p.getType() == StanzaType.valid) { if (wasResultRequested(serv, p.getStanzaFrom().toString())) { // serv.addCID(new CID(p.getStanzaTo().getDomain(), // p.getStanzaFrom().getDomain())); cid_conns.connectionAuthenticated(serv, cid_packet); } else if (log.isLoggable(Level.FINE)) { log.log( Level.FINE, "Received result with type valid for {0} but it was not requested!", p.getStanzaFrom()); } } else { if (log.isLoggable(Level.FINE)) { log.log( Level.FINE, "Invalid result for DB authentication: {0}, stopping connection: {1}", new Object[] {cid_packet, serv}); } serv.stop(); } } } if ((p.getElemName() == VERIFY_EL_NAME) || (p.getElemName() == DB_VERIFY_EL_NAME)) { if (p.getType() == null) { boolean result; try { String secret = handler.getSecretForDomain(cid_packet.getLocalHost()); String local_key = Algorithms.generateDialbackKey( cid_packet.getLocalHost(), cid_packet.getRemoteHost(), secret, p.getStanzaId()); if (local_key == null) { if (log.isLoggable(Level.FINER)) { log.log( Level.FINER, "The key is not available for connection CID: {0}, " + "or the packet CID: {1} ", new Object[] {cid_main, cid_packet}); } } result = local_key != null && local_key.equals(remote_key); } catch (NotLocalhostException ex) { if (log.isLoggable(Level.FINER)) { log.log(Level.FINER, "Could not retreive secret for " + cid_packet.getLocalHost(), ex); } result = false; } handler.sendVerifyResult( DB_VERIFY_EL_NAME, cid_main, cid_packet, result, p.getStanzaId(), serv.getSessionId(), null, false); } else { if (wasVerifyRequested(serv, p.getStanzaFrom().toString())) { handler.sendVerifyResult( DB_RESULT_EL_NAME, cid_main, cid_packet, (p.getType() == StanzaType.valid), null, p.getStanzaId(), null, false); if (p.getType() == StanzaType.valid) { cid_conns.connectionAuthenticated(p.getStanzaId(), cid_packet); } } else { if (log.isLoggable(Level.FINE)) { log.log( Level.FINE, "received verify for {0} but it was not requested!", p.getStanzaFrom()); } } if (serv.isHandshakingOnly()) { serv.stop(); } } } }