Logo Search packages:      
Sourcecode: jabberd14 version File versions  Download package

void dialback_in_read ( mio  m,
int  flags,
void *  arg,
xmlnode  x,
char *  unused1,
int  unused2 
)

callback for mio for accepted sockets

Our task is:

  • Verify the stream root element
  • Check the type of server-to-server stream (we support: dialback, xmpp+dialback)
  • For xmpp+dialback: send stream:features (we support: starttls)
  • Reset the mio callback. Stanzas are handled by dialback_in_read_db()

Parameters:
m the connection on which the stream root element has been received
flags the mio action, everything but MIO_XML_ROOT is ignored
arg the db instance
x the stream root element
unused1 unused/ignored
unused2 unused/ignored

Definition at line 337 of file dialback_in.cc.

References mio_st::authed_other_side, dbic_struct::d, dialback_get_loopcheck_token(), dialback_in_dbic_new(), dialback_in_read_db(), dialback_miod_hash(), dialback_miod_new(), mio_st::fd, xmppd::ns_decl_list::get_nsprefix(), db_struct::hosts_auth, db_struct::hosts_tls, db_struct::hosts_xmpp, dbic_struct::id, db_struct::in_ok_db, mio_st::in_root, j_strcmp(), dbic_struct::m, mio_close(), mio_is_encrypted(), mio_reset(), mio_ssl_starttls_possible(), mio_ssl_verify(), mio_write(), mio_write_root(), dbic_struct::other_domain, dbic_struct::we_domain, xhash_get_by_domain(), xmlnode_free(), xmlnode_get_attrib_ns(), xmlnode_insert_cdata(), xmlnode_insert_tag_ns(), xmlnode_new_tag_ns(), xmlnode_pool(), xmlnode_put_attrib_ns(), xmlnode_serialize_string(), dbic_struct::xmpp_version, and xstream_header().

Referenced by dialback(), and dialback_in_read_db().

                                                                                          {
    db d = (db)arg;
    xmlnode x2;
    miod md;
    char strid[10];
    dbic c = NULL;
    int version = 0;
    int dbns_defined = 0;
    int can_offer_starttls = 0;
    int can_do_sasl_external = 0;
    const char *we_domain = NULL;
    const char *other_domain = NULL;
    const char *loopcheck = NULL;

    log_debug2(ZONE, LOGT_IO, "dbin read: fd %d flag %d", m->fd, flags);

    if(flags != MIO_XML_ROOT)
        return;

    snprintf(strid, sizeof(strid), "%X", m); /* for hashes for later */

    /* check stream version and possible features */
    version = j_atoi(xmlnode_get_attrib_ns(x, "version", NULL), 0);
    try {
      m->in_root->get_nsprefix(NS_DIALBACK);
      dbns_defined = 1;
    } catch (std::invalid_argument) {
    }
    we_domain = xmlnode_get_attrib_ns(x, "to", NULL);
    other_domain = m->authed_other_side ? m->authed_other_side : xmlnode_get_attrib_ns(x, "from", NULL);
    can_offer_starttls = m->authed_other_side==NULL && mio_ssl_starttls_possible(m, we_domain) ? 1 : 0;
    can_do_sasl_external = m->authed_other_side==NULL && (mio_is_encrypted(m) > 0 && mio_ssl_verify(m, other_domain)) ? 1 : 0;

    /* disable by configuration */
    if (j_strcmp(static_cast<char*>(xhash_get_by_domain(d->hosts_tls, other_domain)), "no") == 0)
      can_offer_starttls = 0;
    if (j_strcmp(static_cast<char*>(xhash_get_by_domain(d->hosts_auth, other_domain)), "db") == 0)
      can_do_sasl_external = 0;
    if (j_strcmp(static_cast<char*>(xhash_get_by_domain(d->hosts_xmpp, other_domain)), "no") == 0)
      version = 0;
    else if (j_strcmp(static_cast<char*>(xhash_get_by_domain(d->hosts_xmpp, other_domain)), "force") == 0 && version == 0) {
      jid key = NULL;

        key = jid_new(xmlnode_pool(x), we_domain);
      mio_write_root(m, xstream_header(other_domain, jid_full(key)), 0);
        mio_write(m, NULL, "<stream:error><unsupported-version xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>We are configured to not support pre-XMPP 1.0 connections.</text></stream:error>", -1);
        mio_close(m);
        xmlnode_free(x);
        return;
    }

    log_debug2(ZONE, LOGT_IO, "outgoing conn: can_offer_starttls=%i, can_do_sasl_external=%i", can_offer_starttls, can_do_sasl_external);

    /* validate namespace */
    /*
    if (xmlnode_list_get_nsprefix(m->in_last_ns_root, NS_SERVER) == NULL) {
      jid key = NULL;
        key = jid_new(xmlnode_pool(x), we_domain);
      mio_write_root(m, xstream_header(other_domain, jid_full(key)), 0);
      / * XXX now that we have namespace handling - shouldn't we generate another error? do we need to check this at all? * /
        mio_write(m, NULL, "<stream:error><bad-namespace-prefix xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>Sorry, but the namespace '" NS_SERVER "' has to be defined on the stream root.</text></stream:error>", -1);
        mio_close(m);
        xmlnode_free(x);
        return;
    }
    */

    /* deprecated non-dialback protocol, reject connection */
    if(version < 1 && !dbns_defined) {
      jid key = NULL;
        key = jid_new(xmlnode_pool(x), we_domain);
      mio_write_root(m, xstream_header(other_domain, jid_full(key)), 0);
        mio_write(m, NULL, "<stream:error><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>Legacy Access Denied!</text></stream:error>", -1);
        mio_close(m);
        xmlnode_free(x);
        return;
    }

    /* no support for dialback and we won't be able to offer SASL to this host? */
    if (!dbns_defined && !can_do_sasl_external && m->authed_other_side==NULL) {
      jid key = NULL;
        key = jid_new(xmlnode_pool(x), we_domain);
      mio_write_root(m, xstream_header(other_domain, jid_full(key)), 0);
      mio_write(m, NULL, "<stream:error><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>It seems you do not support dialback, and we cannot validate your TLS certificate. No authentication is possible. We are sorry.</text></stream:error>", -1);
      mio_close(m);
      xmlnode_free(x);
      return;
    }

    /* are we connecting to ourselves? */
    loopcheck = xmlnode_get_attrib_ns(x, "check", NS_JABBERD_LOOPCHECK);
    if (loopcheck != NULL && j_strcmp(loopcheck, dialback_get_loopcheck_token(d)) == 0) {
      jid key = NULL;
        key = jid_new(xmlnode_pool(x), we_domain);
      mio_write_root(m, xstream_header(other_domain, jid_full(key)), 0);
      mio_write(m, NULL, "<stream:error><remote-connection-failed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>Server connected to itself. Probably caused by a DNS misconfiguration, or a domain not used for Jabber/XMPP communications.</text></stream:error>", -1);
      mio_close(m);
      xmlnode_free(x);
      return;
    }

    /* dialback connection */
    c = dialback_in_dbic_new(d, m, we_domain, other_domain, version);

    /* restarted after SASL? authorize the connection */
    if (m->authed_other_side) {
      jid key = NULL;

      key = jid_new(xmlnode_pool(x),c->we_domain);
      jid_set(key, m->authed_other_side, JID_RESOURCE);
      jid_set(key, c->id, JID_USER); /* special user of the id attrib makes this key unique */
      dialback_miod_hash(dialback_miod_new(c->d, c->m), c->d->in_ok_db, key);
    }

    /* write our header */
    x2 = xstream_header(c->other_domain, c->we_domain);
    if (j_strcmp(static_cast<char*>(xhash_get_by_domain(c->d->hosts_auth, c->other_domain)), "sasl") != 0)
      xmlnode_put_attrib_ns(x2, "db", "xmlns", NS_XMLNS, NS_DIALBACK); /* flag ourselves as dialback capable */
    if (c->xmpp_version >= 1) {
      xmlnode_put_attrib_ns(x2, "version", NULL, NULL, "1.0");    /* flag us as XMPP capable */
    }
    xmlnode_put_attrib_ns(x2, "id", NULL, NULL, c->id); /* send random id as a challenge */
    mio_write_root(m, x2, 0);
    xmlnode_free(x);

    /* reset to a dialback packet reader */
    mio_reset(m, dialback_in_read_db, (void *)c);

    /* write stream features */
    if (c->xmpp_version >= 1) {
      xmlnode features = xmlnode_new_tag_ns("features", "stream", NS_STREAM);
      if (can_offer_starttls) {
          xmlnode starttls = NULL;

          starttls = xmlnode_insert_tag_ns(features, "starttls", NULL, NS_XMPP_TLS);
      }
      if (can_do_sasl_external) {
          xmlnode mechanisms = NULL;
          xmlnode mechanism = NULL;

          mechanisms = xmlnode_insert_tag_ns(features, "mechanisms", NULL, NS_XMPP_SASL);
          mechanism = xmlnode_insert_tag_ns(mechanisms, "mechanism", NULL, NS_XMPP_SASL);
          xmlnode_insert_cdata(mechanism, "EXTERNAL", -1);
      }
      log_debug2(ZONE, LOGT_IO, "sending stream features: %s", xmlnode_serialize_string(features, xmppd::ns_decl_list(), 0));
      mio_write(m, features, NULL, 0);
    }
}


Generated by  Doxygen 1.6.0   Back to index