Пример #1
0
static void stream_node_callback(int type, xode node, void *arg)
{
    struct xmpp_private_data *priv = (struct xmpp_private_data *) arg;
    char *id, *hash, *tag;
    char buf[4096];
    xode x;

    LM_DBG("stream callback: %d: %s\n", type, node ? xode_get_name(node) : "n/a");
    switch (type) {
    case XODE_STREAM_ROOT:
        id = xode_get_attrib(node, "id");
        snprintf(buf, sizeof(buf), "%s%s", id, xmpp_password);
        hash = shahash(buf);

        x = xode_new_tag("handshake");
        xode_insert_cdata(x, hash, -1);
        xode_send(priv->fd, x);
        xode_free(x);
        break;
    case XODE_STREAM_NODE:
        tag = xode_get_name(node);
        if (!strcmp(tag, "handshake")) {
            LM_DBG("handshake succeeded\n");
        } else if (!strcmp(tag, "message")) {
            LM_DBG("XMPP IM received\n");
            char *from = xode_get_attrib(node, "from");
            char *to = xode_get_attrib(node, "to");
            char *type = xode_get_attrib(node, "type");
            xode body = xode_get_tag(node, "body");
            char *msg;

            if (!type)
                type = "chat";
            if (!strcmp(type, "error")) {
                LM_DBG("received message error stanza\n");
                goto out;
            }

            if (!from || !to || !body) {
                LM_DBG("invalid <message/> attributes\n");
                goto out;
            }

            if (!(msg = xode_get_data(body)))
                msg = "";
            xmpp_send_sip_msg(
                encode_uri_xmpp_sip(from),
                decode_uri_xmpp_sip(to),
                msg);
        } else if (!strcmp(tag, "presence")) {
            /* call presence callbacks */
            LM_DBG("XMPP Presence received\n");
            run_xmpp_callbacks(XMPP_RCV_PRESENCE, xode_to_str(node));
        } else if (!strcmp(tag, "iq")) {
            /* call presence callbacks */
            LM_DBG("XMPP IQ received\n");
            run_xmpp_callbacks(XMPP_RCV_IQ, xode_to_str(node));
        }
        break;
    case XODE_STREAM_ERROR:
        LM_ERR("stream error\n");
    /* fall-through */
    case XODE_STREAM_CLOSE:
        priv->running = 0;
        break;
    }
out:
    xode_free(node);
}
Пример #2
0
/**
 * authentication to the JABBER server
 */
int xj_jcon_user_auth(xj_jcon jbc, char *username, char *passwd,
				char *resource)
{
	char msg_buff[4096];
	int n, i, err;
	char *p0, *p1;
	xode x, y, z;

	/*** send open stream tag **/
	sprintf(msg_buff, JB_CLIENT_OPEN_STREAM, jbc->hostname);
	if(send(jbc->sock, msg_buff, strlen(msg_buff), 0) != strlen(msg_buff))
		goto error;
	
	n = recv(jbc->sock, msg_buff, 4096, 0);
	msg_buff[n] = 0;
	if(strncasecmp(msg_buff, JB_START_STREAM, JB_START_STREAM_LEN))
		goto error;
	
	p0 = strstr(msg_buff + JB_START_STREAM_LEN, "id='");
	if(p0 == NULL)
		goto error;

	p0 += 4;
	p1 = strchr(p0, '\'');
	if(p1 == NULL)
		goto error;

	jbc->stream_id = (char*)_M_MALLOC(p1-p0+1);
	strncpy(jbc->stream_id, p0, p1-p0);
    jbc->stream_id[p1-p0] = 0;

	sprintf(msg_buff, "%08X", jbc->seq_nr);
	
	x = xode_new_tag("iq");
	if(!x)
		return -1;

	xode_put_attrib(x, "id", msg_buff);
	xode_put_attrib(x, "type", "get");
	y = xode_insert_tag(x, "query");
	xode_put_attrib(y, "xmlns", "jabber:iq:auth");
	z = xode_insert_tag(y, "username");
	xode_insert_cdata(z, username, -1);
	p0 = xode_to_str(x);
	n = strlen(p0);

	i = send(jbc->sock, p0, n, 0);
	if(i != n)
		goto errorx;
	
	xode_free(x);
	
	// receive  response
	// try 10 times
	i = 10;
	while(i)
	{
		if((n = recv(jbc->sock, msg_buff, 4096, 0)) > 0)
		{
			msg_buff[n] = 0;
			break;
		}
		usleep(1000);
		i--;
	}
	if(!i)
		goto error;

	x = xode_from_strx(msg_buff, n, &err, &i);
	p0 = msg_buff;
	if(err)
		p0 += i; 
	
	if(strncasecmp(xode_get_name(x), "iq", 2))
		goto errorx;
	
	if((x = xode_get_tag(x, "query?xmlns=jabber:iq:auth")) == NULL)
		goto errorx;
			
	y = xode_new_tag("query");
	xode_put_attrib(y, "xmlns", "jabber:iq:auth");
	z = xode_insert_tag(y, "username");
	xode_insert_cdata(z, username, -1);
	z = xode_insert_tag(y, "resource");
	xode_insert_cdata(z, resource, -1);
	
	if(xode_get_tag(x, "digest") != NULL)
	{ // digest authentication
			
		//sprintf(msg_buff, "%s%s", jbc->stream_id, passwd);
		strcpy(msg_buff, jbc->stream_id);
		strcat(msg_buff, passwd);
		//DBG("XJAB:xj_jcon_user_auth: [%s:%s]\n", jbc->stream_id, passwd);
		p1 = shahash(msg_buff);

		z = xode_insert_tag(y, "digest");
		xode_insert_cdata(z, p1, -1);
	}
	else
	{ // plaint text authentication
		z = xode_insert_tag(y, "password");
		xode_insert_cdata(z, passwd, -1);
	}

	y = xode_wrap(y, "iq");
	
	jbc->seq_nr++;
	sprintf(msg_buff, "%08X", jbc->seq_nr);
	
	xode_put_attrib(y, "id", msg_buff);
	xode_put_attrib(y, "type", "set");
	
	p1 = xode_to_str(y);
	n = strlen(p1);
	
	i = send(jbc->sock, p1, n, 0);
	if(i != n)
	{
		xode_free(y);
		goto errorx;
	}
	xode_free(x);
	xode_free(y);
	
	// receive  response
	// try 10 times
	i = 10;
	while(i)
	{
		if((n = recv(jbc->sock, msg_buff, 4096, 0)) > 0)
		{
			msg_buff[n] = 0;
			break;
		}
		usleep(1000);
		i--;
	}
	if(!i)
		goto error;

	x = xode_from_strx(msg_buff, n, &err, &i);
	p0 = msg_buff;
	if(err)
		p0 += i; 
	
	if(strncasecmp(xode_get_name(x), "iq", 2) || 
			strncasecmp(xode_get_attrib(x, "type"), "result", 6))
		goto errorx;
	
	jbc->resource = (char*)_M_MALLOC(strlen(resource)+1);
	strcpy(jbc->resource, resource);

	jbc->allowed = XJ_NET_ALL;
	jbc->ready = XJ_NET_JAB;	
	return 0;
	
errorx:
	xode_free(x);
error:
	return -1;
}