/**
 * init a JABBER connection
 */
xj_jcon xj_jcon_init(char *hostname, int port)
{
	xj_jcon jbc = NULL;
	if(hostname==NULL || strlen(hostname)<=0)
		return NULL;
	
	jbc = (xj_jcon)_M_MALLOC(sizeof(struct _xj_jcon));
	if(jbc == NULL)
		return NULL;
	jbc->sock=-1;
    jbc->port = port;
    jbc->juid = -1;
	jbc->seq_nr = 0;
    jbc->hostname = (char*)_M_MALLOC(strlen(hostname)+1);
	if(jbc->hostname == NULL)
	{
		_M_FREE(jbc);
		return NULL;
	}
    strcpy(jbc->hostname, hostname);
	jbc->allowed = jbc->ready = XJ_NET_NUL;
	jbc->jconf = NULL;
	jbc->nrjconf = 0;
	jbc->plist = xj_pres_list_init();
	if(jbc->plist == NULL)
	{
		_M_FREE(jbc->hostname);
		_M_FREE(jbc);
		return NULL;
	}
			
    return jbc;
}
Beispiel #2
0
/**
 * init a jc_pool structure
 * - size : maximum number of the open connection to Jabber
 * - jlen : maximum size of messages queue
 * return : pointer to the structure or NULL on error
 */
xj_jcon_pool xj_jcon_pool_init(int size, int jlen, int ch)
{
	xj_jcon_pool jcp = (xj_jcon_pool)_M_MALLOC(sizeof(t_xj_jcon_pool));
	if(jcp == NULL)
		return NULL;
	jcp->len = size;
	jcp->ojc = (xj_jcon*)_M_MALLOC(size*sizeof(xj_jcon));
	if(jcp->ojc == NULL)
	{
		_M_FREE(jcp);
		return NULL;
	}
	memset( jcp->ojc , 0, size*sizeof(xj_jcon) );
	jcp->jmqueue.len = jlen;
	jcp->jmqueue.size = 0;
	jcp->jmqueue.cache = (ch>0)?ch:90;
	jcp->jmqueue.expire = (int*)_M_MALLOC(jlen*sizeof(int));
	if(jcp->jmqueue.expire == NULL)
	{
		_M_FREE(jcp->ojc);
		_M_FREE(jcp);
		return NULL;
	}
	jcp->jmqueue.jsm=(xj_sipmsg*)_M_MALLOC(jlen*sizeof(xj_sipmsg));
	if(jcp->jmqueue.jsm == NULL)
	{
		_M_FREE(jcp->jmqueue.expire);
		_M_FREE(jcp->ojc);
		_M_FREE(jcp);
		return NULL;
	}
	jcp->jmqueue.ojc = (xj_jcon*)_M_MALLOC(jlen*sizeof(xj_jcon));
	if(jcp->jmqueue.ojc == NULL)
	{
		_M_FREE(jcp->jmqueue.expire);
		_M_FREE(jcp->jmqueue.jsm);
		_M_FREE(jcp->ojc);
		_M_FREE(jcp);
		return NULL;
	}
	memset( jcp->jmqueue.expire , 0, jlen*sizeof(int) );
	memset( jcp->jmqueue.jsm , 0, jlen*sizeof(xj_sipmsg) );
	memset( jcp->jmqueue.ojc , 0, jlen*sizeof(xj_jcon) );
	return jcp;
}
/**
 * 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;
}