in.c

来自「这是一个完全开放的」· C语言 代码 · 共 541 行 · 第 1/2 页

C
541
字号
                 ((NAD_NURI_L(nad, NAD_ENS(nad, 0)) == strlen(uri_CLIENT) && strncmp(uri_CLIENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_CLIENT)) == 0) ||                 (NAD_NURI_L(nad, NAD_ENS(nad, 0)) == strlen(uri_SERVER) && strncmp(uri_SERVER, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_SERVER)) == 0)) && (                    /* can be message */                    (NAD_ENAME_L(nad, 0) == 7 && strncmp("message", NAD_ENAME(nad, 0), 7) == 0) ||                    /* or presence */                    (NAD_ENAME_L(nad, 0) == 8 && strncmp("presence", NAD_ENAME(nad, 0), 8) == 0) ||                    /* or iq */                    (NAD_ENAME_L(nad, 0) == 2 && strncmp("iq", NAD_ENAME(nad, 0), 2) == 0)                 ) &&                 /* to and from required */                 nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "from", NULL) >= 0               )) {                log_debug(ZONE, "they sent us a non-jabber looking packet, dropping it");                nad_free(nad);                return 0;            }            _in_packet(in, nad);            return 0;        case event_CLOSED:            mio_close(in->s2s->mio, in->fd);            break;    }    return 0;}/** auth requests */static void _in_result(conn_t in, nad_t nad) {    int attr, ns;    jid_t from, to;    char *rkey;    nad_t verify;    pkt_t pkt;    attr = nad_find_attr(nad, 0, -1, "from", NULL);    if(attr < 0 || (from = jid_new(in->s2s->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {        log_debug(ZONE, "missing or invalid from on db result packet");        nad_free(nad);        return;    }    attr = nad_find_attr(nad, 0, -1, "to", NULL);    if(attr < 0 || (to = jid_new(in->s2s->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {        log_debug(ZONE, "missing or invalid to on db result packet");        jid_free(from);        nad_free(nad);        return;    }    rkey = s2s_route_key(NULL, to->domain, from->domain);    log_debug(ZONE, "auth request from id %s for route %s", in->key, rkey);    /* get current state */    if((conn_state_t) xhash_get(in->states, rkey) == conn_VALID) {        log_debug(ZONE, "route %s is already valid, replying", rkey);        /* its already valid, just reply right now */        stanza_tofrom(nad, 0);        nad_set_attr(nad, 0, -1, "type", "valid", 5);        nad->elems[0].icdata = nad->elems[0].itail = -1;        nad->elems[0].lcdata = nad->elems[0].ltail = 0;        sx_nad_write(in->s, nad);        free(rkey);        jid_free(from);        jid_free(to);        return;    }    /* not valid, so we need to verify */    /* need the key */    if(NAD_CDATA_L(nad, 0) <= 0) {        log_debug(ZONE, "no dialback key given with db result packet");        free(rkey);        nad_free(nad);        jid_free(from);        jid_free(to);        return;    }    log_debug(ZONE, "requesting verification for route %s", rkey);    free(rkey);    /* new packet */    verify = nad_new(in->s2s->router->nad_cache);    ns = nad_add_namespace(verify, uri_DIALBACK, "db");    nad_append_elem(verify, ns, "verify", 0);    nad_append_attr(verify, -1, "to", from->domain);    nad_append_attr(verify, -1, "from", to->domain);    nad_append_attr(verify, -1, "id", in->s->id);    nad_append_cdata(verify, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0), 1);    /* new packet */    pkt = (pkt_t) malloc(sizeof(struct pkt_st));    memset(pkt, 0, sizeof(struct pkt_st));    pkt->nad = verify;    pkt->to = from;    pkt->from = to;    pkt->db = 1;    /* its away */    out_packet(in->s2s, pkt);    nad_free(nad);}/** validate their key */static void _in_verify(conn_t in, nad_t nad) {    int attr;    jid_t from, to;    char *id, *dbkey, *type;        attr = nad_find_attr(nad, 0, -1, "from", NULL);    if(attr < 0 || (from = jid_new(in->s2s->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {        log_debug(ZONE, "missing or invalid from on db verify packet");        nad_free(nad);        return;    }    attr = nad_find_attr(nad, 0, -1, "to", NULL);    if(attr < 0 || (to = jid_new(in->s2s->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {        log_debug(ZONE, "missing or invalid to on db verify packet");        jid_free(from);        nad_free(nad);        return;    }    attr = nad_find_attr(nad, 0, -1, "id", NULL);    if(attr < 0) {        log_debug(ZONE, "missing id on db verify packet");        jid_free(from);        jid_free(to);        nad_free(nad);        return;    }    if(NAD_CDATA_L(nad, 0) <= 0) {        log_debug(ZONE, "no cdata on db verify packet");        jid_free(from);        jid_free(to);        nad_free(nad);        return;    }    /* extract the id */    id = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, attr) + 1));    snprintf(id, NAD_AVAL_L(nad, attr) + 1, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));    /* generate a dialback key */    dbkey = s2s_db_key(NULL, in->s2s->local_secret, from->domain, id);    /* valid */    if(NAD_CDATA_L(nad, 0) == strlen(dbkey) && strncmp(dbkey, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0)) == 0) {        log_debug(ZONE, "valid dialback key %s, verify succeeded", dbkey);        type = "valid";    } else {        log_debug(ZONE, "invalid dialback key %s, verify failed", dbkey);        type = "invalid";    }    log_debug(ZONE, "letting them know");    /* now munge the packet and send it back to them */    stanza_tofrom(nad, 0);    nad_set_attr(nad, 0, -1, "type", type, 0);    nad->elems[0].icdata = nad->elems[0].itail = -1;    nad->elems[0].lcdata = nad->elems[0].ltail = 0;    sx_nad_write(in->s, nad);    free(dbkey);    free(id);    jid_free(from);    jid_free(to);    return;}/** they're trying to send us something */static void _in_packet(conn_t in, nad_t nad) {    int attr, ns, sns;    jid_t from, to;    char *rkey;        attr = nad_find_attr(nad, 0, -1, "from", NULL);    if(attr < 0 || (from = jid_new(in->s2s->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {        log_debug(ZONE, "missing or invalid from on db verify packet");        nad_free(nad);        return;    }    attr = nad_find_attr(nad, 0, -1, "to", NULL);    if(attr < 0 || (to = jid_new(in->s2s->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {        log_debug(ZONE, "missing or invalid to on db verify packet");        jid_free(from);        nad_free(nad);        return;    }    rkey = s2s_route_key(NULL, to->domain, from->domain);    log_debug(ZONE, "received packet from %s for %s", in->key, rkey);    /* if its invalid, drop it */    if((conn_state_t) xhash_get(in->states, rkey) == conn_INVALID) {        log_debug(ZONE, "route not valid, dropping packet");        free(rkey);        nad_free(nad);        jid_free(from);        jid_free(to);        return;    }    free(rkey);    /* its good, off to the router with it */    log_debug(ZONE, "incoming packet on valid route, preparing it for the router");    /* rewrite server packets into client packets */    ns = nad_find_namespace(nad, 0, uri_SERVER, NULL);    if(ns >= 0) {        if(nad->elems[0].ns == ns)            nad->elems[0].ns = nad->nss[nad->elems[0].ns].next;        else {            for(sns = nad->elems[0].ns; sns >= 0 && nad->nss[sns].next != ns; sns = nad->nss[sns].next);            nad->nss[sns].next = nad->nss[nad->nss[sns].next].next;        }    }    ns = nad_find_namespace(nad, 0, uri_CLIENT, NULL);    if(ns < 0) {        ns = nad_add_namespace(nad, uri_CLIENT, NULL);        nad->scope = -1;        nad->nss[ns].next = nad->elems[0].ns;        nad->elems[0].ns = ns;    }    nad->elems[0].my_ns = ns;    /* wrap up the packet */    ns = nad_add_namespace(nad, uri_COMPONENT, "comp");    nad_wrap_elem(nad, 0, ns, "route");    nad_set_attr(nad, 0, -1, "to", to->domain, 0);    nad_set_attr(nad, 0, -1, "from", in->s2s->id, 0);   /* route is from s2s, not packet source */    log_debug(ZONE, "sending packet to %s", to->domain);    /* go */    sx_nad_write(in->s2s->router, nad);    jid_free(from);    jid_free(to);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?