Esempio n. 1
0
  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);
    }
  }
Esempio n. 2
0
  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();
        }
      }
    }
  }