Ejemplo n.º 1
0
/** register get handler */
static void _authreg_register_get(c2s_t c2s, sess_t sess, nad_t nad) {
    int attr, ns;
    char id[128];

    /* registrations can happen if reg is enabled and we can create users and set passwords */
    if(sess->active || !(sess->host->ar->set_password != NULL && sess->host->ar->create_user != NULL &&
        (sess->host->ar_register_enable || sess->host->ar_register_oob))) {

        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));
        return;
    }

    /* extract the id */
    attr = nad_find_attr(nad, 0, -1, "id", NULL);
    if(attr >= 0)
        snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));

    nad_free(nad);

    /* build a result packet */
    nad = nad_new();

    ns = nad_add_namespace(nad, uri_CLIENT, NULL);

    nad_append_elem(nad, ns, "iq", 0);
    nad_append_attr(nad, -1, "type", "result");

    if(attr >= 0)
        nad_append_attr(nad, -1, "id", id);

    ns = nad_add_namespace(nad, uri_REGISTER, NULL);
    nad_append_elem(nad, ns, "query", 1);
    
    nad_append_elem(nad, ns, "instructions", 2);
    nad_append_cdata(nad, sess->host->ar_register_instructions, strlen(sess->host->ar_register_instructions), 3);

    if(sess->host->ar_register_enable) {
        nad_append_elem(nad, ns, "username", 2);
        nad_append_elem(nad, ns, "password", 2);
    }

    if(sess->host->ar_register_oob) {
        int ns = nad_add_namespace(nad, uri_OOB, NULL);
        nad_append_elem(nad, ns, "x", 2);
        nad_append_elem(nad, ns, "url", 3);
        nad_append_cdata(nad, sess->host->ar_register_oob, strlen(sess->host->ar_register_oob), 4);
    }

    /* give it back to the client */
    sx_nad_write(sess->s, nad);
}
Ejemplo n.º 2
0
/** sx features callback */
static void _address_features(sx_t s, sx_plugin_t p, nad_t nad) {
    int ns;

    /* offer feature only when not authenticated yet */
    if(s->state >= state_OPEN)
        return;

    _sx_debug(ZONE, "adding address feature");

    ns = nad_add_namespace(nad, uri_ADDRESS_FEATURE, NULL);
    nad_append_elem(nad, ns, "address", 1);
    nad_append_cdata(nad, s->ip, strlen(s->ip), 2);
}
Ejemplo n.º 3
0
/** utility: generate a response nad */
static nad_t _sx_sasl_response(sx_t s, char *data, int dlen) {
    nad_t nad;
    int ns;

    nad = nad_new();
    ns = nad_add_namespace(nad, uri_SASL, NULL);

    nad_append_elem(nad, ns, "response", 0);
    if(data != NULL)
        nad_append_cdata(nad, data, dlen, 1);

    return nad;
}
Ejemplo n.º 4
0
static void _sx_compress_features(sx_t s, sx_plugin_t p, nad_t nad) {
    int ns;

    /* if the session is already compressed, or the app told us not to,
	 * or STARTTLS is required and stream is not encrypted yet, then we don't offer anything */
    if(s->compressed || !(s->flags & SX_COMPRESS_OFFER) || ((s->flags & SX_SSL_STARTTLS_REQUIRE) && s->ssf == 0))
        return;

    _sx_debug(ZONE, "offering compression");

    ns = nad_add_namespace(nad, uri_COMPRESS_FEATURE, NULL);
    nad_append_elem(nad, ns, "compression", 1);
    nad_append_elem(nad, ns, "method", 2);
    nad_append_cdata(nad, "zlib", 4, 3);
}
Ejemplo n.º 5
0
static nad_t _pbx_presence_nad(int available, char *cmd)
{
	nad_t nad;
	int ns;
	char *show = NULL;

	nad = nad_new();
	ns = nad_add_namespace(nad, uri_CLIENT, NULL);
	nad_append_elem(nad, ns, "presence", 0);

	if(!available) {
		nad_append_attr(nad, -1, "type", "unavailable");
	}
	else {
		char *cont;
		long int priority;
		char prioritystr[5]; // -128 to +127 + \0

		priority = strtol(cmd, &cont, 10);
		log_debug(ZONE, "Read %ld priority", priority);
		if(cmd == cont) priority = -1; // use -1 priority if not given
		if(priority < -128) priority = -128;
		if(priority > 127) priority = 127;
		nad_append_elem(nad, -1, "priority", 1);
		snprintf(prioritystr, 5, "%ld", priority);
		nad_append_cdata(nad, prioritystr, strlen(prioritystr), 2);
		if(cmd != cont) {
			cmd = cont;
			while(*cmd == ' ') { cmd++; }
		}


		if(!strncmp("CHAT", cmd, 4)) {
			cmd += 4;
			show = "chat";
		}
		if(!strncmp("ONLINE", cmd, 6)) {
			cmd += 6;
		}
		if(!strncmp("DND", cmd, 3)) {
			cmd += 3;
			show = "dnd";
		}
		if(!strncmp("AWAY", cmd, 4)) {
			cmd += 4;
			show = "away";
		}
		if(!strncmp("XA", cmd, 2)) {
			cmd += 2;
			show = "xa";
		}
		if(show) {
			nad_append_elem(nad, -1, "show", 1);
			nad_append_cdata(nad, show, strlen(show), 2);
		}
	}

	while(*cmd == ' ') { cmd++; }

	if(*cmd != '\0' && *cmd != '\n') {
		int len = strlen(cmd);
		nad_append_elem(nad, -1, "status", 1);
		nad_append_cdata(nad, cmd, len - (cmd[len-1] == '\n' ? 1 : 0), 2);
	}

	return nad;
}
Ejemplo n.º 6
0
Archivo: in.c Proyecto: zipo/zipo
/** 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;
    time_t now;

    attr = nad_find_attr(nad, 0, -1, "from", NULL);
    if(attr < 0 || (from = jid_new(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(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_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] received dialback auth request for route '%s'", in->fd->fd, in->ip, in->port, rkey);

    /* get current state */
    if((conn_state_t) xhash_get(in->states, rkey) == conn_VALID) {
        log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] route '%s' is already valid: sending valid", in->fd->fd, in->ip, in->port, 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_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] no dialback key given with db result packet", in->fd->fd, in->ip, in->port, rkey);
        free(rkey);
        nad_free(nad);
        jid_free(from);
        jid_free(to);
        return;
    }

    log_debug(ZONE, "requesting verification for route %s", rkey);

    /* set the route status to INPROGRESS and set timestamp */
    xhash_put(in->states, pstrdup(xhash_pool(in->states), rkey), (void *) conn_INPROGRESS);

    /* record the time that we set conn_INPROGRESS state */
    now = time(NULL);
    xhash_put(in->states_time, pstrdup(xhash_pool(in->states_time), rkey), (void *) now);

    free(rkey);

    /* new packet */
    verify = nad_new();
    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) calloc(1, 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);
}
Ejemplo n.º 7
0
static void _nad_parse_cdata(void *arg, const char *str, int len) {
    struct build_data *bd = (struct build_data *) arg;

    /* go */
    nad_append_cdata(bd->nad, (char *) str, len, bd->depth);
}
Ejemplo n.º 8
0
/** auth get handler */
static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad) {
    int ns, elem, attr;
    char username[1024], id[128];
    int ar_mechs;

    /* can't auth if they're active */
    if(sess->active) {
        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));
        return;
    }

    /* sort out the username */
    ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL);
    elem = nad_find_elem(nad, 1, ns, "username", 1);
    if(elem < 0)
    {
        log_debug(ZONE, "auth get with no username, bouncing it");

        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0));

        return;
    }

    snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
    if(stringprep_xmpp_nodeprep(username, 1024) != 0) {
        log_debug(ZONE, "auth get username failed nodeprep, bouncing it");
        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0));
        return;
    }

    ar_mechs = c2s->ar_mechanisms;
    if (sess->s->ssf>0) 
        ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms;
        
    /* no point going on if we have no mechanisms */
    if(!(ar_mechs & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST))) {
        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0));
        return;
    }
    
    /* do we have the user? */
    if((c2s->ar->user_exists)(c2s->ar, username, sess->host->realm) == 0) {
        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0));
        return;
    }

    /* extract the id */
    attr = nad_find_attr(nad, 0, -1, "id", NULL);
    if(attr >= 0)
        snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));

    nad_free(nad);

    /* build a result packet */
    nad = nad_new();

    ns = nad_add_namespace(nad, uri_CLIENT, NULL);

    nad_append_elem(nad, ns, "iq", 0);
    nad_append_attr(nad, -1, "type", "result");

    if(attr >= 0)
        nad_append_attr(nad, -1, "id", id);

    ns = nad_add_namespace(nad, uri_AUTH, NULL);
    nad_append_elem(nad, ns, "query", 1);
    
    nad_append_elem(nad, ns, "username", 2);
    nad_append_cdata(nad, username, strlen(username), 3);

    nad_append_elem(nad, ns, "resource", 2);

    /* fill out the packet with available auth mechanisms */
    if(ar_mechs & AR_MECH_TRAD_PLAIN && (c2s->ar->get_password != NULL || c2s->ar->check_password != NULL))
        nad_append_elem(nad, ns, "password", 2);

    if(ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)
        nad_append_elem(nad, ns, "digest", 2);

    /* give it back to the client */
    sx_nad_write(sess->s, nad);

    return;
}
Ejemplo n.º 9
0
static void _config_charData(void *arg, const char *str, int len)
{
    struct build_data *bd = (struct build_data *) arg;

    nad_append_cdata(bd->nad, (char *) str, len, bd->depth);
}
Ejemplo n.º 10
0
/** Send archiving preferences */
void send_arch_prefs(mod_instance_t mi, sess_t sess, pkt_t pkt) {
    module_t mod = mi->mod;
    int prefs;
    int archive=default_mode;
    int section;
    int check;
    char buff[2060]; // 2048 is jid_user maximum length
    char* ret_str=buff;
    os_t os = NULL;
    os_object_t o = NULL;
    pkt_t reply;

    // Create a new packet
    log_debug(ZONE, "Construction of reply with current settings");
    reply = pkt_create(sess->user->sm, "iq", "result", NULL, NULL);

    // Defaults
    log_debug(ZONE, "Getting defaults");
    prefs = nad_append_elem(reply->nad, nad_add_namespace(reply->nad, archive_uri, NULL), "prefs", 2);

    // Load defaults
    snprintf(buff, 2060, "(jid=%s)", jid_user(sess->jid));
    if((storage_get(sess->user->sm->st, tbl_name "_settings", jid_user(sess->jid), buff, &os) == st_SUCCESS) &&
        (os_iter_first(os)) && ((o=os_iter_object(os))!=NULL))
            os_object_get_int(os, o, "setting", &archive);

    // Set defaults
    switch(archive) {
        case A_ALWAYS:
            nad_set_attr(reply->nad, prefs, -1,"default", "always", 6);
            break;
        case A_ROSTER:
            nad_set_attr(reply->nad, prefs, -1,"default", "roster", 6);
            break;
        default:
            nad_set_attr(reply->nad, prefs, -1,"default", "never", 5);
            break;
    }


    // Cleanup
    if(o != NULL) {
        os_object_free(o);
        o=NULL;
    }
    if(os != NULL) {
        os_free(os);
        os=NULL;
    }

    // Always archiving
    log_debug(ZONE, "Getting what to archive always");
    section = nad_append_elem(reply->nad, -1, "always", 3);
    if(storage_get(sess->user->sm->st, tbl_name "_settings", jid_user(sess->jid), "(setting=1)", &os) == st_SUCCESS)
    if(os_iter_first(os))
        do {
            o = os_iter_object(os);
            if((o != NULL) && (os_object_get_str(os, o, "jid", &ret_str)) && (ret_str != NULL)) {
                nad_append_elem(reply->nad, -1, "jid", 4);
                nad_append_cdata(reply->nad, ret_str, strlen(ret_str), 5);
            }
        } while(os_iter_next(os));

    // Cleanup
    if(o != NULL) {
        os_object_free(o);
        o=NULL;
    }
    if(os != NULL) {
        os_free(os);
        os=NULL;
    }

    // Never archiving
    log_debug(ZONE, "Getting what to never archive");
    section = nad_append_elem(reply->nad, -1, "never", 3);
    if(storage_get(sess->user->sm->st, tbl_name "_settings", jid_user(sess->jid), "(setting=0)", &os) == st_SUCCESS)
    if(os_iter_first(os))
        do {
            o = os_iter_object(os);
            if((o != NULL) && (os_object_get_str(os, o, "jid", &ret_str)) && (ret_str != NULL)) {
                nad_append_elem(reply->nad, -1, "jid", 4);
                nad_append_cdata(reply->nad, ret_str, strlen(ret_str), 5);
            }
        } while(os_iter_next(os));

    // Cleanup
    if(o != NULL) {
        os_object_free(o);
        o=NULL;
    }
    if(os != NULL) {
        os_free(os);
        os=NULL;
    }

    // Send packet
    pkt_id(pkt, reply);
    pkt_sess(reply, sess);
    pkt_free(pkt);
}