Example #1
0
File: jid.c Project: zipo/zipo
/** do stringprep on the pieces */
static int jid_prep_pieces(char *node, char *domain, char *resource) {
    if(node[0] != '\0')
        if(stringprep_xmpp_nodeprep(node, 1024) != 0)
            return 1;

    if(stringprep_nameprep(domain, 1024) != 0)
        return 1;

    if(resource[0] != '\0')
        if(stringprep_xmpp_resourceprep(resource, 1024) != 0)
            return 1;

    return 0;
}
Example #2
0
char * jid_normalized(const char *jid,int full){
int i,at,slash,ret;
char node[1024],domain[1024],resource[1024];
char *domainbuf;

	if (!jid) return NULL;

	slash=-1;
	at=-1;
	/* split into parts */
	for(i=0;jid[i];i++){
		if (jid[i]=='@' && at<0) at=i;
		if (jid[i]=='/' && slash<0) slash=i;
	}

	if (slash>=0 && slash<at){
		g_warning(N_("slash<at (%i<%i) in %s"),slash,at,jid);
		return NULL;
	}
	if (slash==at+1){
		g_warning(N_("empty domain in %s"),jid);
		return NULL;
	}

	/* node */
	if (at>0){
		if (at>1023){
			g_warning(N_("node too long in %s"),jid);
			return NULL;
		}
		memcpy(node,jid,at);
		node[at]='\000';
	}
	else node[0]='\000';

	/* domain */
	if (slash>0){
		if (slash-at>1024){
			g_warning(N_("domain too long in %s"),jid);
			return NULL;
		}
		memcpy(domain,jid+at+1,slash-at-1);
		domain[slash-at-1]='\000';
	}
	else{
		if (strlen(jid+at+1)>1023){
			g_warning(N_("domain too long in %s"),jid);
			return NULL;
		}
		strcpy(domain,jid+at+1);
	}

	/* resource */
	if (slash>0){
		if (strlen(jid+slash+1)>1023){
			g_warning(N_("resource too long in %s"),jid);
			return NULL;
		}
		strcpy(resource,jid+slash+1);
	}
	else resource[0]='\000';

	if (node[0]){
		ret=stringprep_xmpp_nodeprep(node,1024);
		if (ret!=0){
			g_warning(N_("bad node: %s"),node);
			return NULL;
		}
	}
	if (resource[0]){
		ret=stringprep_xmpp_resourceprep(resource,1024);
		if (ret!=0){
			g_warning(N_("bad node: %s"),resource);
			return NULL;
		}
	}
	ret=idna_to_unicode_8z8z(domain,&domainbuf,IDNA_ALLOW_UNASSIGNED);
	if (ret!=IDNA_SUCCESS){
		g_warning(N_("bad domain: %s"),domain);
		return NULL;
	}
	strcpy(domain,domainbuf);
	g_free(domainbuf);

	if (!full || !resource[0]){
		if (node[0])
			return g_strconcat(node,"@",domain,NULL);
		else
			return g_strdup(domain);
	}
	else{
		if (node[0])
			return g_strconcat(node,"@",domain,"/",resource,NULL);
		else
			return g_strconcat(domain,"/",resource,NULL);
	}
}
Example #3
0
/** auth set handler */
static void _authreg_auth_set(c2s_t c2s, sess_t sess, nad_t nad) {
    int ns, elem, attr, authd = 0;
    char username[1024], resource[1024], str[1024], hash[280];
    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;
    }

    ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL);

    /* sort out the username */
    elem = nad_find_elem(nad, 1, ns, "username", 1);
    if(elem < 0)
    {
        log_debug(ZONE, "auth set 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 set username failed nodeprep, bouncing it");
        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0));
        return;
    }

    /* make sure we have the resource */
    elem = nad_find_elem(nad, 1, ns, "resource", 1);
    if(elem < 0)
    {
        log_debug(ZONE, "auth set with no resource, bouncing it");

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

        return;
    }

    snprintf(resource, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
    if(stringprep_xmpp_resourceprep(resource, 1024) != 0) {
        log_debug(ZONE, "auth set resource failed resourceprep, 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;
    }
    
    /* digest auth */
    if(!authd && ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)
    {
        elem = nad_find_elem(nad, 1, ns, "digest", 1);
        if(elem >= 0)
        {
            if((c2s->ar->get_password)(c2s->ar, username, sess->host->realm, str) == 0)
            {
                snprintf(hash, 280, "%s%s", sess->s->id, str);
                shahash_r(hash, hash);

                if(strlen(hash) == NAD_CDATA_L(nad, elem) && strncmp(hash, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0)
                {
                    log_debug(ZONE, "digest auth succeeded");
                    authd = 1;
                    _authreg_auth_log(c2s, sess, "traditional.digest", username, resource, TRUE);
                }
            }
        }
    }

    /* plaintext auth (compare) */
    if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && c2s->ar->get_password != NULL)
    {
        elem = nad_find_elem(nad, 1, ns, "password", 1);
        if(elem >= 0)
        {
            if((c2s->ar->get_password)(c2s->ar, username, sess->host->realm, str) == 0 && strlen(str) == NAD_CDATA_L(nad, elem) && strncmp(str, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0)
            {
                log_debug(ZONE, "plaintext auth (compare) succeeded");
                authd = 1;
                _authreg_auth_log(c2s, sess, "traditional.plain(compare)", username, resource, TRUE);
            }
        }
    }

    /* plaintext auth (check) */
    if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && c2s->ar->check_password != NULL)
    {
        elem = nad_find_elem(nad, 1, ns, "password", 1);
        if(elem >= 0)
        {
            snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
            if((c2s->ar->check_password)(c2s->ar, username, sess->host->realm, str) == 0)
            {
                log_debug(ZONE, "plaintext auth (check) succeded");
                authd = 1;
                _authreg_auth_log(c2s, sess, "traditional.plain", username, resource, TRUE);
            }
        }
    }

    /* now, are they authenticated? */
    if(authd)
    {
        /* create new bound jid holder */
        if(sess->resources == NULL) {
            sess->resources = (bres_t) calloc(1, sizeof(struct bres_st));
        }

        /* our local id */
        sprintf(sess->resources->c2s_id, "%d", sess->s->tag);

        /* the full user jid for this session */
        sess->resources->jid = jid_new(sess->s->req_to, -1);
        jid_reset_components(sess->resources->jid, username, sess->resources->jid->domain, resource);

        log_write(sess->c2s->log, LOG_NOTICE, "[%d] requesting session: jid=%s", sess->s->tag, jid_full(sess->resources->jid));

        /* build a result packet, we'll send this back to the client after we have a session for them */
        sess->result = nad_new();

        ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);

        nad_append_elem(sess->result, ns, "iq", 0);
        nad_set_attr(sess->result, 0, -1, "type", "result", 6);

        attr = nad_find_attr(nad, 0, -1, "id", NULL);
        if(attr >= 0)
            nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));

        /* start a session with the sm */
        sm_start(sess, sess->resources);

        /* finished with the nad */
        nad_free(nad);

        return;
    }

    _authreg_auth_log(c2s, sess, "traditional", username, resource, FALSE);

    /* auth failed, so error */
    sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0));

    return;
}
Example #4
0
static gboolean jabber_resourceprep(char *str, size_t buflen)
{
	return stringprep_xmpp_resourceprep(str, buflen) == STRINGPREP_OK;
}