/** * 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; }
/** * 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; }