Ejemplo n.º 1
0
int parse_authenticate_header(struct hdr_field *authenticate)
{
    void **parsed;
    struct authenticate_body *auth_body;

    parsed = &(authenticate->parsed);

    while(*parsed == NULL)
    {
	auth_body = pkg_malloc(sizeof(struct authenticate_body));
	if (auth_body == NULL)
	{
	    LM_ERR("oom\n");
	    return -1;
	}

	if (0 != parse_authenticate_body(&authenticate->body, auth_body))
	    return -1;
	*parsed = auth_body;

	authenticate = authenticate->sibling;
	if (authenticate)
	    parsed = &(authenticate->parsed);
	else
	    break;
    }
    return 0;
}
Ejemplo n.º 2
0
void uac_reg_tm_callback( struct cell *t, int type, struct tmcb_params *ps)
{
	char *uuid;
	str suuid;
	reg_uac_t *ri = NULL;
	contact_t* c;
	int expires;
	struct sip_uri puri;
	struct hdr_field *hdr;
	HASHHEX response;
	str *new_auth_hdr = NULL;
	static struct authenticate_body auth;
	struct uac_credential cred;
	char  b_ruri[MAX_URI_SIZE];
	str   s_ruri;
#ifdef UAC_OLD_AUTH
	char  b_turi[MAX_URI_SIZE];
	str   s_turi;
#endif
	char  b_hdrs[MAX_UACH_SIZE];
	str   s_hdrs;
	uac_req_t uac_r;
	str method = {"REGISTER", 8};
	int ret;
	dlg_t tmdlg;

	if(ps->param==NULL || *ps->param==0)
	{
		LM_DBG("uuid not received\n");
		return;
	}
	uuid = *((char**)ps->param);
	LM_DBG("completed with status %d [uuid: %s]\n",
		ps->code, uuid);
	suuid.s = uuid;
	suuid.len = strlen(suuid.s);
	ri = reg_ht_get_byuuid(&suuid);

	if(ri==NULL)
	{
		LM_DBG("no user with uuid %s\n", uuid);
		goto done;
	}

	if(ps->code == 200)
	{
		if (parse_headers(ps->rpl, HDR_EOH_F, 0) == -1)
		{
			LM_ERR("failed to parse headers\n");
			goto error;
		}
		if (ps->rpl->contact==NULL)
		{
			LM_ERR("no Contact found\n");
			goto error;
		}
		if (parse_contact(ps->rpl->contact) < 0)
		{
			LM_ERR("failed to parse Contact HF\n");
			goto error;
		}
		if (((contact_body_t*)ps->rpl->contact->parsed)->star)
		{
			LM_DBG("* Contact found\n");
			goto done;
		}

		if (contact_iterator(&c, ps->rpl, 0) < 0)
			goto done;
		while(c)
		{
			if(parse_uri(c->uri.s, c->uri.len, &puri)!=0)
			{
				LM_ERR("failed to parse c-uri\n");
				goto error;
			}
			if(suuid.len==puri.user.len
					&& (strncmp(puri.user.s, suuid.s, suuid.len)==0))
			{
				/* calculate expires */
				expires=0;
				if(c->expires==NULL || c->expires->body.len<=0)
				{
					if(ps->rpl->expires!=NULL && ps->rpl->expires->body.len>0)
						expires = atoi(ps->rpl->expires->body.s);
				} else {
					str2int(&c->expires->body, (unsigned int*)(&expires));
				}
				ri->timer_expires = ri->timer_expires + expires;
				ri->flags |= UAC_REG_ONLINE;
				goto done;
			}
			if (contact_iterator(&c, ps->rpl, c) < 0)
			{
				LM_DBG("local contact not found\n");
				goto done;
			}
		}
	}

	if(ps->code == 401 || ps->code == 407)
	{
		if(ri->flags & UAC_REG_AUTHSENT)
		{
			LM_ERR("authentication failed for <%.*s>\n",
					ri->l_uuid.len, ri->l_uuid.s);
			goto error;
		}
		hdr = get_autenticate_hdr(ps->rpl, ps->code);
		if (hdr==0)
		{
			LM_ERR("failed to extract authenticate hdr\n");
			goto error;
		}

		LM_DBG("auth header body [%.*s]\n",
			hdr->body.len, hdr->body.s);

		if (parse_authenticate_body(&hdr->body, &auth)<0)
		{
			LM_ERR("failed to parse auth hdr body\n");
			goto error;
		}
		if (ri->realm.len>0) {
			/* only check if realms match if it is non-empty */
			if(auth.realm.len!=ri->realm.len
					|| strncmp(auth.realm.s, ri->realm.s, ri->realm.len)!=0)
			{
				LM_ERR("realms do not match. requested realm: [%.*s]\n",
					auth.realm.len, auth.realm.s);
				goto error;
			}
		}
		cred.realm = auth.realm;
		cred.user = ri->auth_username; 
		cred.passwd = ri->auth_password;
 		cred.next = NULL;

		snprintf(b_ruri, MAX_URI_SIZE, "sip:%.*s",
				ri->r_domain.len, ri->r_domain.s);
		s_ruri.s = b_ruri; s_ruri.len = strlen(s_ruri.s);

		do_uac_auth(&method, &s_ruri, &cred, &auth, response);
		new_auth_hdr=build_authorization_hdr(ps->code, &s_ruri, &cred,
						&auth, response);
		if (new_auth_hdr==0)
		{
			LM_ERR("failed to build authorization hdr\n");
			goto error;
		}
		
#ifdef UAC_OLD_AUTH
		snprintf(b_turi, MAX_URI_SIZE, "sip:%.*s@%.*s",
				ri->r_username.len, ri->r_username.s,
				ri->r_domain.len, ri->r_domain.s);
		s_turi.s = b_turi; s_turi.len = strlen(s_turi.s);
#endif
		snprintf(b_hdrs, MAX_UACH_SIZE,
				"Contact: <sip:%.*s@%.*s>\r\n"
				"Expires: %d\r\n"
				"%.*s",
				ri->l_uuid.len, ri->l_uuid.s,
				reg_contact_addr.len, reg_contact_addr.s,
				ri->expires,
				new_auth_hdr->len, new_auth_hdr->s);
		s_hdrs.s = b_hdrs; s_hdrs.len = strlen(s_hdrs.s);
		pkg_free(new_auth_hdr->s);

		memset(&uac_r, 0, sizeof(uac_r));
		if(uac_reg_tmdlg(&tmdlg, ps->rpl)<0)
		{
			LM_ERR("failed to build tm dialog\n");
			goto error;
		}
		tmdlg.rem_target = s_ruri;
		if(ri->auth_proxy.len)
			tmdlg.dst_uri = ri->auth_proxy;
		uac_r.method = &method;
		uac_r.headers = &s_hdrs;
		uac_r.dialog = &tmdlg;
		uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
		/* Callback function */
		uac_r.cb  = uac_reg_tm_callback;
		/* Callback parameter */
		uac_r.cbp = (void*)uuid;
#ifdef UAC_OLD_AUTH
		ret = uac_tmb.t_request(&uac_r,  /* UAC Req */
				&s_ruri, /* Request-URI */
				&s_turi, /* To */
				&s_turi, /* From */
				(ri->auth_proxy.len)?&ri->auth_proxy:NULL /* outbound uri */
			);
#endif
		ret = uac_tmb.t_request_within(&uac_r);

		if(ret<0) {
			LM_ERR("failed to send request with authentication for [%.*s]",
			       ri->l_uuid.len, ri->l_uuid.s);
			goto error;
		}

		ri->flags |= UAC_REG_AUTHSENT;
		return;
	} else
	{
		LM_ERR("got sip response %d while registering [%.*s]\n",
		       ps->code, ri->l_uuid.len, ri->l_uuid.s);
		goto error;
	}

error:
	ri->flags &= ~(UAC_REG_ONGOING|UAC_REG_AUTHSENT);
	if(reg_retry_interval) {
		ri->timer_expires = time(NULL) + reg_retry_interval;
	} else {
		ri->flags |= UAC_REG_DISABLED;
		counter_inc(regdisabled);
	}
done:
	if(ri)
		ri->flags &= ~(UAC_REG_ONGOING|UAC_REG_AUTHSENT);
	shm_free(uuid);
	counter_inc(regactive);
}
Ejemplo n.º 3
0
int uac_auth(sip_msg_t *msg)
{
	static struct authenticate_body auth;
	struct uac_credential *crd;
	int code, branch;
	struct sip_msg *rpl;
	struct cell *t;
	struct hdr_field *hdr;
	HASHHEX response;
	str *new_hdr;
	sr_cfgenv_t *cenv = NULL;

	/* get transaction */
	t = uac_tmb.t_gett();
	if (t==T_UNDEFINED || t==T_NULL_CELL)
	{
		LM_CRIT("no current transaction found\n");
		goto error;
	}

	/* get the selected branch */
	branch = uac_tmb.t_get_picked_branch();
	if (branch<0) {
		LM_CRIT("no picked branch (%d)\n",branch);
		goto error;
	}

	rpl = t->uac[branch].reply;
	code = t->uac[branch].last_received;
	LM_DBG("picked reply is %p, code %d\n",rpl,code);

	if (rpl==0)
	{
		LM_CRIT("empty reply on picked branch\n");
		goto error;
	}
	if (rpl==FAKED_REPLY)
	{
		LM_ERR("cannot process a FAKED reply\n");
		goto error;
	}

	hdr = get_autenticate_hdr( rpl, code);
	if (hdr==0)
	{
		LM_ERR("failed to extract authenticate hdr\n");
		goto error;
	}

	LM_DBG("header found; body=<%.*s>\n",
		hdr->body.len, hdr->body.s);

	if (parse_authenticate_body( &hdr->body, &auth)<0)
	{
		LM_ERR("failed to parse auth hdr body\n");
		goto error;
	}

	/* can we authenticate this realm? */
	crd = 0;
	/* first look into AVP, if set */
	if ( auth_realm_spec.type!=PVT_NONE )
		crd = get_avp_credential( msg, &auth.realm );
	/* if not found, look into predefined credentials */
	if (crd==0)
		crd = lookup_realm( &auth.realm );
	/* found? */
	if (crd==0)
	{
		LM_DBG("no credential for realm \"%.*s\"\n",
			auth.realm.len, auth.realm.s);
		goto error;
	}

	/* do authentication */
	do_uac_auth( &msg->first_line.u.request.method,
			&t->uac[branch].uri, crd, &auth, response);

	/* build the authorization header */
	new_hdr = build_authorization_hdr( code, &t->uac[branch].uri,
		crd, &auth, response);
	if (new_hdr==0)
	{
		LM_ERR("failed to build authorization hdr\n");
		goto error;
	}

	/* so far, so good -> add the header and set the proper RURI */
	if ( apply_urihdr_changes( msg, &t->uac[branch].uri, new_hdr)<0 )
	{
		LM_ERR("failed to apply changes\n");
		goto error;
	}

	/* mark request in T with uac auth for increase of cseq via dialog
	 * - this function is executed in failure route, msg_flags will be
	 *   reset afterwards by tm fake env */
	if(t->uas.request) {
		t->uas.request->msg_flags |= FL_UAC_AUTH;
		cenv = sr_cfgenv_get();
		if(cenv->cb_cseq_update != NULL) {
			if(cenv->cb_cseq_update(msg)<0) {
				goto error;
			}
		}
	}

	return 0;
error:
	return -1;
}
Ejemplo n.º 4
0
int uac_auth( struct sip_msg *msg)
{
	static struct authenticate_body auth;
	struct uac_credential *crd;
	int picked_code, picked_br, b;
	struct sip_msg *rpl;
	struct cell *t;
	struct hdr_field *hdr;
	HASHHEX response;
	str *new_hdr;

	/* get transaction */
	t = uac_tmb.t_gett();
	if (t==T_UNDEFINED || t==T_NULL_CELL)
	{
		LOG(LOG_CRIT,"BUG:uac:uac_auth: no current transaction found\n");
		goto error;
	}

	/* pick the selected reply */
	picked_br = -1;
	picked_code = 999;
	for ( b=t->first_branch; b<t->nr_of_outgoings ; b++ )
	{
		/* skip 'empty branches' */
		if (!t->uac[b].request.buffer)
			continue;
		/* there is still an unfinished UAC transaction? */
		if ( t->uac[b].last_received<200 )
		{
			LOG(L_CRIT,"BUG:uac:uac_auth: incomplet transaction in failure "
				"route\n");
			goto error;
		}
		if ( t->uac[b].last_received<picked_code )
		{
			picked_br = b;
			picked_code = t->uac[b].last_received;
		}
	}
	if (picked_br<0)
	{
		LOG(L_CRIT,"BUG:uac:uac_auth: empty transaction in failure "
			"route\n");
		goto error;
	}

	rpl = t->uac[picked_br].reply;
	DBG("DEBUG:uac:uac_auth: picked reply is %p, code %d\n",rpl,picked_code);

	if (rpl==0)
	{
		LOG(L_CRIT,"BUG:uac:uac_auth: empty reply on picked branch\n");
		goto error;
	}
	if (rpl==FAKED_REPLY)
	{
		LOG(L_ERR,"ERROR:uac:uac_auth: cannot process a FAKED reply\n");
		goto error;
	}

	hdr = get_autenticate_hdr( rpl, picked_code);
	if (hdr==0)
	{
		LOG( L_ERR,"ERROR:uac:uac_auth: failed to extract authenticate hdr\n");
		goto error;
	}

	DBG("DEBUG:uac:uac_auth: header found; body=<%.*s>\n",
		hdr->body.len, hdr->body.s);

	if (parse_authenticate_body( &hdr->body, &auth)<0)
	{
		LOG(L_ERR,"ERROR:uac:uac_auth: failed to parse auth hdr body\n");
		goto error;
	}

	/* can we authenticate this realm? */
	crd = lookup_realm( &auth.realm );
	if (crd==0)
	{
		LOG(L_ERR,"ERROR:uac:uac_auth: no credential for realm \"%.*s\"\n",
			auth.realm.len, auth.realm.s);
		goto error;
	}

	/* do authentication */
	do_uac_auth( msg, &t->uac[picked_br].uri, crd, &auth, response);

	/* build the authorization header */
	new_hdr = build_authorization_hdr( picked_code, &t->uac[picked_br].uri,
		crd, &auth, response);
	if (new_hdr==0)
	{
		LOG(L_ERR,"ERROR:uac:uac_auth: failed to build authorization hdr\n");
		goto error;
	}

	/* so far, so good -> add the header and set the proper RURI */
	if ( apply_urihdr_changes( msg, &t->uac[picked_br].uri, new_hdr)<0 )
	{
		LOG(L_ERR,"ERROR:uac:uac_auth: failed to apply changes\n");
		goto error;
	}

	/* increas the Cseq nr */


	return 0;
error:
	return -1;
}
Ejemplo n.º 5
0
/** 
 * TM callback function
 */
void uac_send_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
{
	int ret;
	struct hdr_field *hdr;
	HASHHEX response;
	str *new_auth_hdr = NULL;
	static struct authenticate_body auth;
	struct uac_credential cred;
	char  b_hdrs[MAX_UACH_SIZE];
	str   s_hdrs;
	uac_req_t uac_r;
	dlg_t tmdlg;
	uac_send_info_t *tp = NULL;

	LM_DBG("tm callback with status %d\n", ps->code);

	if(ps->param==NULL || *ps->param==0)
	{
		LM_DBG("callback param with message id not received\n");
		goto done;
	}
	tp = (uac_send_info_t*)(*ps->param);

	if(tp->evroute!=0) {
		uac_req_run_event_route((ps->rpl==FAKED_REPLY)?NULL:ps->rpl,
				tp, ps->code);
	}

	if((ps->code != 401 && ps->code != 407) || tp->s_apasswd.len<=0)
	{
		LM_DBG("completed with status %d\n", ps->code);
		goto done;
	}

	LM_DBG("completed with status %d\n", ps->code);

	hdr = get_autenticate_hdr(ps->rpl, ps->code);
	if (hdr==0)
	{
		LM_ERR("failed to extract authenticate hdr\n");
		goto error;
	}

	LM_DBG("auth header body [%.*s]\n",
		hdr->body.len, hdr->body.s);

	if (parse_authenticate_body(&hdr->body, &auth)<0)
	{
		LM_ERR("failed to parse auth hdr body\n");
		goto error;
	}

	cred.realm  = auth.realm;
	cred.user   = tp->s_auser;
	cred.passwd = tp->s_apasswd;
	cred.next   = NULL;

	do_uac_auth(&tp->s_method, &tp->s_ruri, &cred, &auth, response);
	new_auth_hdr=build_authorization_hdr(ps->code, &tp->s_ruri, &cred,
						&auth, response);
	if (new_auth_hdr==0)
	{
		LM_ERR("failed to build authorization hdr\n");
		goto error;
	}

	if(tp->s_hdrs.len <= 0) {
		snprintf(b_hdrs, MAX_UACH_SIZE,
				"%.*s",
				new_auth_hdr->len, new_auth_hdr->s);
	} else {
		snprintf(b_hdrs, MAX_UACH_SIZE,
				"%.*s%.*s",
				tp->s_hdrs.len, tp->s_hdrs.s,
				new_auth_hdr->len, new_auth_hdr->s);
	}

	s_hdrs.s = b_hdrs; s_hdrs.len = strlen(s_hdrs.s);
	pkg_free(new_auth_hdr->s);

	memset(&uac_r, 0, sizeof(uac_r));
	if(uac_send_tmdlg(&tmdlg, ps->rpl)<0)
	{
		LM_ERR("failed to build tm dialog\n");
		goto error;
	}
	tmdlg.rem_target = tp->s_ruri;
	if(tp->s_ouri.len>0)
		tmdlg.dst_uri = tp->s_ouri;
	uac_r.method = &tp->s_method;
	uac_r.headers = &s_hdrs;
	uac_r.body = (tp->s_body.len <= 0) ? NULL : &tp->s_body;
	uac_r.ssock = (tp->s_sock.len <= 0) ? NULL : &tp->s_sock;
	uac_r.dialog = &tmdlg;
	uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
	ret = tmb.t_request_within(&uac_r);

	if(ret<0) {
		LM_ERR("failed to send request with authentication\n");
		goto error;
	}

done:
error:
	if(tp!=NULL)
		shm_free(tp);
	return;
}