예제 #1
0
파일: common.c 프로젝트: KISSMonX/opensips
/* 
 * Return parsed To or From, host part of the parsed uri is realm
 */
int get_realm(struct sip_msg* _m, hdr_types_t _hftype, struct sip_uri** _u)
{

	if(_u==NULL)
		return -1;
	if ((REQ_LINE(_m).method.len == 8) 
	    && !memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) 
	    && (_hftype == HDR_AUTHORIZATION_T)
	   ) {
		if (!_m->to && ((parse_headers(_m, HDR_TO_F, 0)==-1) || (!_m->to))) {
			LM_ERR("failed to parse TO headers\n");
			return -1;
		}
		
		/* Body of To header field is parsed automatically */
		if((*_u = parse_to_uri(_m))==NULL)
			return -1;
	} else {
		if (parse_from_header(_m) < 0) {
			LM_ERR("failed to parse FROM headers\n");
			return -2;
		}
		if((*_u = parse_from_uri(_m))==NULL)
			return -1;
	}
	
	return 0;
}
예제 #2
0
static int l_sipwatch_getFlag(lua_State *L)
{
  struct sipapi_object *o;
  struct sip_uri *myuri;

  o = luaL_checkudata(L, 1, "siplua.api");
  myuri = parse_from_uri(o->msg);
  if (myuri)
    {
      if (sipwatch_getFlagFromExtension(myuri->user.s, myuri->user.len))
	{
	  lua_pushboolean(L, 1);
	  return 1;
	}
    }
  myuri = parse_to_uri(o->msg);
  if (myuri)
    {
      if (sipwatch_getFlagFromExtension(myuri->user.s, myuri->user.len))
	{
	  lua_pushboolean(L, 1);
	  return 1;
	}
    }
  lua_pushnil(L);
  return 1;
}
예제 #3
0
/*
 * Check username part in To header field
 */
int check_to(struct sip_msg* _m, char* _s1, char* _s2)
{
	if (!_m->to && ((parse_headers(_m, HDR_TO_F, 0) == -1) || (!_m->to))) {
		LM_ERR("Error while parsing To header field\n");
		return ERR_INTERNAL;
	}
	if(parse_to_uri(_m)==NULL) {
		LM_ERR("Error while parsing To header URI\n");
		return ERR_INTERNAL;
	}

	return check_username(_m, &get_to(_m)->parsed_uri);
}
예제 #4
0
static inline int check_to(struct sip_msg *_m, str *_username)
{
	if (!_m->to && ((parse_headers(_m, HDR_TO_F, 0) == -1) || (!_m->to)))
	{
		LM_ERR("parsing To: header\n");
		return CHECK_ERROR;
	}

	if (parse_to_uri(_m) == NULL)
	{
		LM_ERR("parsing To: URI\n");
		return CHECK_ERROR;
	}

	return check_username(_username, &get_to(_m)->parsed_uri);
}
예제 #5
0
static int l_siplua_getURI_User(lua_State *L)
{
  struct sipapi_object *o;
  struct sip_uri *myuri;

  o = luaL_checkudata(L, 1, "siplua.api");
  myuri = parse_to_uri(o->msg);
  if (!myuri)
    {
/*       siplua_log(L_WARN, "parse_to_uri returned NULL results"); */
      lua_pushnil(L);
    }
  else
    {
/*       siplua_log(L_DBG, "parse_to_uri returned non-empty results"); */
      lua_pushlstring(L, myuri->user.s, myuri->user.len);
    }
  return 1;
}
예제 #6
0
파일: save.c 프로젝트: Jared-Prime/kamailio
/*! \brief
 * This function will process request that
 * contained some contact header fields
 */
static inline int add_contacts(struct sip_msg* _m, udomain_t* _d,
		str* _a, int _mode, int _use_regid)
{
	int res;
	int ret;
	urecord_t* r;
	sip_uri_t *u;

	u = parse_to_uri(_m);
	if(u==NULL)
		return -2;

	ret = 0;
	ul.lock_udomain(_d, _a);
	res = ul.get_urecord(_d, _a, &r);
	if (res < 0) {
		rerrno = R_UL_GET_R;
		LM_ERR("failed to retrieve record from usrloc\n");
		ul.unlock_udomain(_d, _a);
		return -2;
	}

	if (res == 0) { /* Contacts found */
		if ((ret=update_contacts(_m, r, _mode, _use_regid)) < 0) {
			build_contact(_m, r->contacts, &u->host);
			ul.release_urecord(r);
			ul.unlock_udomain(_d, _a);
			return -3;
		}
		build_contact(_m, r->contacts, &u->host);
		ul.release_urecord(r);
	} else {
		if (insert_contacts(_m, _d, _a, _use_regid) < 0) {
			ul.unlock_udomain(_d, _a);
			return -4;
		}
		ret = 1;
	}
	ul.unlock_udomain(_d, _a);
	return ret;
}
예제 #7
0
/*
 * Extract URI depending on the request from To or From header
 */
static inline int get_uri_user(struct sip_msg* _m, str** _uri_user)
{
    struct sip_uri *puri;

    if ((REQ_LINE(_m).method.len == 8) &&
	(memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) == 0)) {
	if ((puri=parse_to_uri(_m))==NULL) {
	    LM_ERR("failed to parse To header\n");
	    return -1;
	}
    } else {
	if ((puri=parse_from_uri(_m))==NULL) {
	    LM_ERR("parsing From header\n");
	    return -1;
	}
    }

    *_uri_user = &(puri->user);

    return 0;
}
예제 #8
0
파일: save.c 프로젝트: halan/kamailio
int unregister(struct sip_msg* _m, udomain_t* _d, str* _uri)
{
	str aor = {0, 0};
	sip_uri_t *u;

	u = parse_to_uri(_m);
	if(u==NULL)
		return -2;


	if (extract_aor(_uri, &aor, NULL) < 0) {
		LM_ERR("failed to extract Address Of Record\n");
		return -1;
	}

	if (star(_m, _d, &aor, &u->host) < 0)
	{
		LM_ERR("error unregistering user [%.*s]\n", aor.len, aor.s);
		return -1;
	}
	return 1;
}
예제 #9
0
파일: group.c 프로젝트: GeorgeShaw/opensips
/*
 * Check from AAA server if a user belongs to a group. User-Name is digest
 * username or digest username@realm, SIP-Group is group, and Service-Type
 * is Group-Check.  SIP-Group is SER specific attribute and Group-Check is
 * SER specific service type value.
 */
int aaa_is_user_in(struct sip_msg* _m, char* _hf, char* _group)
{
	str *grp, user_name, user, domain;
	dig_cred_t* cred = 0;
	int hf_type;
	uint32_t service;

	aaa_message *send = NULL, *received = NULL;

	struct hdr_field* h;
	struct sip_uri *turi;

	grp = (str*)_group; /* via fixup */

	hf_type = (int)(long)_hf;

	turi = 0;

	switch(hf_type) {
		case 1: /* Request-URI */
			if(parse_sip_msg_uri(_m)<0) {
				LM_ERR("failed to get Request-URI\n");
				return -1;
			}
			turi = &_m->parsed_uri;
			break;

		case 2: /* To */
			if((turi=parse_to_uri(_m))==NULL) {
				LM_ERR("failed to get To URI\n");
				return -1;
			}
			break;

		case 3: /* From */
			if((turi=parse_from_uri(_m))==NULL) {
				LM_ERR("failed to get From URI\n");
				return -1;
			}
			break;

		case 4: /* Credentials */
			get_authorized_cred(_m->authorization, &h);
			if (!h) {
				get_authorized_cred(_m->proxy_auth, &h);
				if (!h) {
				LM_ERR("no authorized"
							" credentials found (error in scripts)\n");
					return -4;
				}
			}
			cred = &((auth_body_t*)(h->parsed))->digest;
			break;
	}

	if (hf_type != 4) {
		user = turi->user;
		domain = turi->host;
	} else {
		user = cred->username.user;
		domain = *GET_REALM(cred);
	}

	if (user.s == NULL || user.len == 0) {
		LM_DBG("no username part\n");
		return -1;
	}

	if (use_domain) {
		user_name.len = user.len + domain.len + 1;
		user_name.s = (char*)pkg_malloc(user_name.len);
		if (!user_name.s) {
			LM_ERR("no pkg memory left\n");
			return -6;
		}

		memcpy(user_name.s, user.s, user.len);
		user_name.s[user.len] = '@';
		memcpy(user_name.s + user.len + 1, domain.s, domain.len);
	} else {
		user_name = user;
	}

	if ((send = proto.create_aaa_message(conn, AAA_AUTH)) == NULL) {
		LM_ERR("failed to create new aaa message for auth \n");
		return -1;
	}

	if (proto.avp_add(conn, send, &attrs[A_USER_NAME], user_name.s, user_name.len, 0)) {
		proto.destroy_aaa_message(conn, send);
		if (use_domain) pkg_free(user_name.s);
		return -7;
	}

	if (use_domain) pkg_free(user_name.s);


	if (proto.avp_add(conn, send, &attrs[A_SIP_GROUP], grp->s, grp->len, 0)) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("failed to add Sip-Group attribute\n");
		return -8;
	}

	service = vals[V_GROUP_CHECK].value;

	if (proto.avp_add(conn, send, &attrs[A_SERVICE_TYPE], &service, -1, 0)) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("failed to add Service-Type attribute\n");
		return -8;
	}

	/* Add CALL-ID in Acct-Session-Id Attribute */
	if ((parse_headers(_m, HDR_CALLID_F, 0) == -1 || _m->callid == NULL) &&
		 _m->callid == NULL) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("msg parsing failed or callid not present");
		return -10;
	}

	if (proto.avp_add(conn, send, &attrs[A_ACCT_SESSION_ID], _m->callid->body.s,
	_m->callid->body.len, 0)) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("unable to add CALL-ID attribute\n");
		return -11;
	}

	if (!proto.send_aaa_request(conn, send, &received)) {
		LM_DBG("Success\n");
		proto.destroy_aaa_message(conn, send);
		proto.destroy_aaa_message(conn, received);
		return 1;
	} else {
		LM_DBG("Failure\n");
		proto.destroy_aaa_message(conn, send);
		proto.destroy_aaa_message(conn, received);
		return -12;
	}
}
예제 #10
0
static int pv_auth_check(sip_msg_t *msg, char *realm,
		char *passwd, char *flags, char *checks)
{
	int vflags = 0;
	int vchecks = 0;
	str srealm  = {0, 0};
	str spasswd = {0, 0};
	int ret;
	hdr_field_t *hdr;
	sip_uri_t *uri = NULL;
	sip_uri_t *turi = NULL;
	sip_uri_t *furi = NULL;

	if(msg==NULL) {
		LM_ERR("invalid msg parameter\n");
		return AUTH_ERROR;
	}

	if ((msg->REQ_METHOD == METHOD_ACK) || (msg->REQ_METHOD == METHOD_CANCEL)) {
		return AUTH_OK;
	}

	if(realm==NULL || passwd==NULL || flags==NULL || checks==NULL) {
		LM_ERR("invalid parameters\n");
		return AUTH_ERROR;
	}

	if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) {
		LM_ERR("failed to get realm value\n");
		return AUTH_ERROR;
	}

	if(srealm.len==0) {
		LM_ERR("invalid realm value - empty content\n");
		return AUTH_ERROR;
	}

	if (get_str_fparam(&spasswd, msg, (fparam_t*)passwd) < 0) {
		LM_ERR("failed to get passwd value\n");
		return AUTH_ERROR;
	}

	if(spasswd.len==0) {
		LM_ERR("invalid password value - empty content\n");
		return AUTH_ERROR;
	}

	if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
		LM_ERR("invalid flags value\n");
		return AUTH_ERROR;
	}

	if (get_int_fparam(&vchecks, msg, (fparam_t*)checks) < 0) {
		LM_ERR("invalid checks value\n");
		return AUTH_ERROR;
	}
	LM_DBG("realm [%.*s] flags [%d] checks [%d]\n", srealm.len, srealm.s,
			vflags, vchecks);

	if(msg->REQ_METHOD==METHOD_REGISTER)
		ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T,
				&msg->first_line.u.request.method);
	else
		ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T,
				&msg->first_line.u.request.method);

	if(ret==AUTH_OK && (vchecks&AUTH_CHECK_ID_F)) {
		hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;
		srealm = ((auth_body_t*)(hdr->parsed))->digest.username.user;

		if((furi=parse_from_uri(msg))==NULL)
			return AUTH_ERROR;

		if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
			if((turi=parse_to_uri(msg))==NULL)
				return AUTH_ERROR;
			uri = turi;
		} else {
			uri = furi;
		}
		if(srealm.len!=uri->user.len
				|| strncmp(srealm.s, uri->user.s, srealm.len)!=0)
			return AUTH_USER_MISMATCH;

		if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
			/* check from==to */
			if(furi->user.len!=turi->user.len
					|| strncmp(furi->user.s, turi->user.s, furi->user.len)!=0)
				return AUTH_USER_MISMATCH;
			if(auth_use_domain!=0 && (furi->host.len!=turi->host.len
						|| strncmp(furi->host.s, turi->host.s, furi->host.len)!=0))
				return AUTH_USER_MISMATCH;
			/* check r-uri==from for publish */
			if(msg->REQ_METHOD==METHOD_PUBLISH) {
				if(parse_sip_msg_uri(msg)<0)
					return AUTH_ERROR;
				uri = &msg->parsed_uri;
				if(furi->user.len!=uri->user.len
						|| strncmp(furi->user.s, uri->user.s, furi->user.len)!=0)
					return AUTH_USER_MISMATCH;
				if(auth_use_domain!=0 && (furi->host.len!=uri->host.len
							|| strncmp(furi->host.s, uri->host.s, furi->host.len)!=0))
					return AUTH_USER_MISMATCH;
			}
		}
		return AUTH_OK;
	}

	return ret;
}
예제 #11
0
파일: save.c 프로젝트: Jared-Prime/kamailio
int save(struct sip_msg* _m, udomain_t* _d, int _cflags, str *_uri)
{
	contact_t* c;
	int st, mode;
	str aor;
	int ret;
	sip_uri_t *u;
	rr_t *route;
	struct sip_uri puri;
	param_hooks_t hooks;
	param_t *params;
	contact_t *contact;
	int use_ob = 1, use_regid = 1;

	u = parse_to_uri(_m);
	if(u==NULL)
		goto error;

	rerrno = R_FINE;
	ret = 1;

	if (parse_message(_m) < 0) {
		goto error;
	}

	if (check_contacts(_m, &st) > 0) {
		goto error;
	}

	if (parse_supported(_m) == 0) {
		if (!(get_supported(_m)	& F_OPTION_TAG_OUTBOUND)
				&& reg_outbound_mode == REG_OUTBOUND_REQUIRE) {
			LM_WARN("Outbound required by server and not supported by UAC\n");
			rerrno = R_OB_UNSUP;
			goto error;
		}
	}

	if (parse_require(_m) == 0) {
		if ((get_require(_m) & F_OPTION_TAG_OUTBOUND)
				&& reg_outbound_mode == REG_OUTBOUND_NONE) {
			LM_WARN("Outbound required by UAC and not supported by server\n");
			rerrno = R_OB_REQD;
			goto error;
		}
	}

	if (reg_outbound_mode != REG_OUTBOUND_NONE
			&& _m->contact && _m->contact->parsed
			&& !(parse_headers(_m, HDR_VIA2_F, 0) == -1 || _m->via2 == 0
				|| _m->via2->error != PARSE_OK)) {
		/* Outbound supported on server, and more than one Via: - not the first hop */

		if (!(parse_headers(_m, HDR_PATH_F, 0) == -1 || _m->path == 0)) {
			route = (rr_t *)0;
			if (parse_rr_body(_m->path->body.s, _m->path->body.len, &route) < 0) {
				LM_ERR("Failed to parse Path: header body\n");
				goto error;
			}
			if (parse_uri(route->nameaddr.uri.s, route->nameaddr.uri.len, &puri) < 0) {
				LM_ERR("Failed to parse Path: URI\n");
				goto error;
			}
			if (parse_params(&puri.params, CLASS_URI, &hooks, &params) != 0) {
				LM_ERR("Failed to parse Path: URI parameters\n");
				goto error;
			}
			if (!hooks.uri.ob) {
				/* No ;ob parameter to top Path: URI - no outbound */
				use_ob = 0;
			}

		} else {
			/* No Path: header - no outbound */
			use_ob = 0;

		}

		contact = ((contact_body_t *) _m->contact->parsed)->contacts;
		if (!contact) {
			LM_ERR("empty Contact:\n");
			goto error;
		}

		if ((use_ob == 0) && (reg_regid_mode == REG_REGID_OUTBOUND)) {
			if ((get_supported(_m) & F_OPTION_TAG_OUTBOUND)
					&& contact->reg_id) {
				LM_WARN("Outbound used by UAC but not supported by edge proxy\n");
				rerrno = R_OB_UNSUP_EDGE;
				goto error;
			} else {
				/* ignore ;reg-id parameter */
				use_regid = 0;
			}
		}
	}

	get_act_time();
	c = get_first_contact(_m);

	if (extract_aor((_uri)?_uri:&get_to(_m)->uri, &aor, NULL) < 0) {
		LM_ERR("failed to extract Address Of Record\n");
		goto error;
	}

	mem_only = is_cflag_set(REG_SAVE_MEM_FL)?FL_MEM:FL_NONE;

	if (c == 0) {
		if (st) {
			if (star(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error;
			else ret=3;
		} else {
			if (no_contacts(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error;
			else ret=4;
		}
	} else {
		mode = is_cflag_set(REG_SAVE_REPL_FL)?1:0;
		if ((ret=add_contacts(_m, (udomain_t*)_d, &aor, mode, use_regid)) < 0)
			goto error;
		ret = (ret==0)?1:ret;
	}

	update_stat(accepted_registrations, 1);

	/* Only send reply upon request, not upon reply */
	if ((is_route_type(REQUEST_ROUTE) || is_route_type(FAILURE_ROUTE))
			&& !is_cflag_set(REG_SAVE_NORPL_FL) && (reg_send_reply(_m) < 0))
		return -1;

	return ret;
error:
	update_stat(rejected_registrations, 1);
	if (is_route_type(REQUEST_ROUTE) && !is_cflag_set(REG_SAVE_NORPL_FL) )
		reg_send_reply(_m);

	return 0;
}
예제 #12
0
파일: save.c 프로젝트: halan/kamailio
int save(struct sip_msg* _m, udomain_t* _d, int _cflags, str *_uri)
{
	contact_t* c;
	int st, mode;
	str aor;
	int ret;
	sip_uri_t *u;

	u = parse_to_uri(_m);
	if(u==NULL)
		goto error;

	rerrno = R_FINE;
	ret = 1;

	if (parse_message(_m) < 0) {
		goto error;
	}

	if (check_contacts(_m, &st) > 0) {
		goto error;
	}

	if (parse_supported(_m) == 0) {
		if (!(((struct supported_body *)_m->supported->parsed)->supported_all
				& F_SUPPORTED_OUTBOUND) && reg_outbound_mode == REG_OUTBOUND_REQUIRE) {
			LM_WARN("Outbound required by server and not supported by UAC\n");
			rerrno = R_OB_UNSUP;
			goto error;
		}
	}
	
	get_act_time();
	c = get_first_contact(_m);

	if (extract_aor((_uri)?_uri:&get_to(_m)->uri, &aor, NULL) < 0) {
		LM_ERR("failed to extract Address Of Record\n");
		goto error;
	}

	mem_only = is_cflag_set(REG_SAVE_MEM_FL)?FL_MEM:FL_NONE;

	if (c == 0) {
		if (st) {
			if (star(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error;
			else ret=3;
		} else {
			if (no_contacts(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error;
			else ret=4;
		}
	} else {
		mode = is_cflag_set(REG_SAVE_REPL_FL)?1:0;
		if ((ret=add_contacts(_m, (udomain_t*)_d, &aor, mode)) < 0)
			goto error;
		ret = (ret==0)?1:ret;
	}

	update_stat(accepted_registrations, 1);

	/* Only send reply upon request, not upon reply */
	if ((is_route_type(REQUEST_ROUTE)) && !is_cflag_set(REG_SAVE_NORPL_FL) && (reg_send_reply(_m) < 0))
		return -1;

	return ret;
error:
	update_stat(rejected_registrations, 1);
	if (is_route_type(REQUEST_ROUTE) && !is_cflag_set(REG_SAVE_NORPL_FL) )
		reg_send_reply(_m);

	return 0;
}
예제 #13
0
파일: save.c 프로젝트: Jared-Prime/kamailio
/*! \brief
 * Message contained some contacts, but record with same address
 * of record was not found so we have to create a new record
 * and insert all contacts from the message that have expires
 * > 0
 */
static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a, int _use_regid)
{
	ucontact_info_t* ci;
	urecord_t* r = NULL;
	ucontact_t* c;
	contact_t* _c;
	unsigned int flags;
	int num, expires;
	int maxc;
#ifdef USE_TCP
	int e_max, tcp_check;
	struct sip_uri uri;
#endif
	sip_uri_t *u;

	u = parse_to_uri(_m);
	if(u==NULL)
		goto error;

	flags = mem_only;
#ifdef USE_TCP
	if ( (_m->flags&tcp_persistent_flag)
			&& (_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS
				||_m->rcv.proto==PROTO_WS||_m->rcv.proto==PROTO_WSS)) {
		e_max = 0;
		tcp_check = 1;
	} else {
		e_max = tcp_check = 0;
	}
#endif
	_c = get_first_contact(_m);
	maxc = reg_get_crt_max_contacts();
	for( num=0,r=0,ci=0 ; _c ; _c = get_next_contact(_c) ) {
		/* calculate expires */
		calc_contact_expires(_m, _c->expires, &expires);
		/* Skip contacts with zero expires */
		if (expires == 0)
			continue;


		if (maxc > 0 && num >= maxc) {
			LM_INFO("too many contacts (%d) for AOR <%.*s>\n", 
					num, _a->len, _a->s);
			rerrno = R_TOO_MANY;
			goto error;
		}
		num++;

		if (r==0) {
			if (ul.insert_urecord(_d, _a, &r) < 0) {
				rerrno = R_UL_NEW_R;
				LM_ERR("failed to insert new record structure\n");
				goto error;
			}
		}

		/* pack the contact_info */
		if ( (ci=pack_ci( (ci==0)?_m:0, _c, expires, flags, _use_regid))==0 ) {
			LM_ERR("failed to extract contact info\n");
			goto error;
		}

		/* hack to work with buggy clients having many contacts with same
		 * address in one REGISTER - increase CSeq to detect if there was
		 * one already added, then update */
		ci->cseq++;
		if ( r->contacts==0
				|| ul.get_ucontact_by_instance(r, &_c->uri, ci, &c) != 0) {
			ci->cseq--;
			if (ul.insert_ucontact( r, &_c->uri, ci, &c) < 0) {
				rerrno = R_UL_INS_C;
				LM_ERR("failed to insert contact\n");
				goto error;
			}
		} else {
			ci->cseq--;
			if (ul.update_ucontact( r, c, ci) < 0) {
				rerrno = R_UL_UPD_C;
				LM_ERR("failed to update contact\n");
				goto error;
			}
		}
#ifdef USE_TCP
		if (tcp_check) {
			/* parse contact uri to see if transport is TCP */
			if (parse_uri( _c->uri.s, _c->uri.len, &uri)<0) {
				LM_ERR("failed to parse contact <%.*s>\n", 
						_c->uri.len, _c->uri.s);
			} else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS || uri.proto==PROTO_WS || uri.proto==PROTO_WSS) {
				if (e_max) {
					LM_WARN("multiple TCP contacts on single REGISTER\n");
					if (expires>e_max) e_max = expires;
				} else {
					e_max = expires;
				}
			}
		}
#endif
	}

	if (r) {
		if (r->contacts)
			build_contact(_m, r->contacts, &u->host);
		ul.release_urecord(r);
	} else { /* No contacts found */
		build_contact(_m, NULL, &u->host);
	}

#ifdef USE_TCP
	if ( tcp_check && e_max>0 ) {
		e_max -= act_time;
		/*FIXME: Do we want this in the sr core?*/
		/*force_tcp_conn_lifetime( &_m->rcv , e_max + 10 );*/
	}
#endif

	return 0;
error:
	if (r)
		ul.delete_urecord(_d, _a, r);
	return -1;
}
예제 #14
0
파일: save.c 프로젝트: Jared-Prime/kamailio
int unregister(struct sip_msg* _m, udomain_t* _d, str* _uri, str *_ruid)
{
	str aor = {0, 0};
	sip_uri_t *u;
	urecord_t *r;
	ucontact_t *c;
	int res;

	if (_ruid == NULL) {
		/* No ruid provided - remove all contacts for aor */

		if (extract_aor(_uri, &aor, NULL) < 0) {
			LM_ERR("failed to extract Address Of Record\n");
			return -1;
		}

		u = parse_to_uri(_m);
		if(u==NULL)
			return -2;

		if (star(_m, _d, &aor, &u->host) < 0)
		{
			LM_ERR("error unregistering user [%.*s]\n", aor.len, aor.s);
			return -1;
		}
	} else {
		/* ruid provided - remove a specific contact */

		if (_uri->len > 0) {

			if (extract_aor(_uri, &aor, NULL) < 0) {
				LM_ERR("failed to extract Address Of Record\n");
				return -1;
			}

			if (ul.get_urecord_by_ruid(_d, ul.get_aorhash(&aor),
						_ruid, &r, &c) != 0) {
				LM_WARN("AOR/Contact not found\n");
				return -1;
			}
			if (ul.delete_ucontact(r, c) != 0) {
				ul.unlock_udomain(_d, &aor);
				LM_WARN("could not delete contact\n");
				return -1;
			}
			ul.unlock_udomain(_d, &aor);

		} else {

			res = ul.delete_urecord_by_ruid(_d, _ruid);
			switch (res) {
				case -1:
					LM_ERR("could not delete contact\n");
					return -1;
				case -2:
					LM_WARN("contact not found\n");
					return -1;
				default:
					return 1;
			}

		}
	}

	return 1;
}
예제 #15
0
/*
 * Authenticate using WWW/Proxy-Authorize header field
 */
int auth_check(struct sip_msg* _m, char* _realm, char* _table, char *_flags)
{
	str srealm;
	str stable;
	int iflags;
	int ret;
	hdr_field_t *hdr;
	sip_uri_t *uri = NULL;
	sip_uri_t *turi = NULL;
	sip_uri_t *furi = NULL;

	if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) {
		return AUTH_OK;
	}

	if(_m==NULL || _realm==NULL || _table==NULL || _flags==NULL) {
		LM_ERR("invalid parameters\n");
		return AUTH_ERROR;
	}

	if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0) {
		LM_ERR("failed to get realm value\n");
		return AUTH_ERROR;
	}

	if (srealm.len==0) {
		LM_ERR("invalid realm parameter - empty value\n");
		return AUTH_ERROR;
	}

	if (get_str_fparam(&stable, _m, (fparam_t*)_table) < 0) {
		LM_ERR("failed to get realm value\n");
		return AUTH_ERROR;
	}

	if (stable.len==0) {
		LM_ERR("invalid table parameter - empty value\n");
		return AUTH_ERROR;
	}

	if(fixup_get_ivalue(_m, (gparam_p)_flags, &iflags)!=0)
	{
		LM_ERR("invalid flags parameter\n");
		return -1;
	}

	LM_DBG("realm [%.*s] table [%.*s] flags [%d]\n", srealm.len, srealm.s,
			stable.len,  stable.s, iflags);

	hdr = NULL;
	if(_m->REQ_METHOD==METHOD_REGISTER)
		ret = digest_authenticate_hdr(_m, &srealm, &stable, HDR_AUTHORIZATION_T,
						&_m->first_line.u.request.method, &hdr);
	else
		ret = digest_authenticate_hdr(_m, &srealm, &stable, HDR_PROXYAUTH_T,
						&_m->first_line.u.request.method, &hdr);

	if(ret==AUTH_OK && hdr!=NULL && (iflags&AUTH_CHECK_ID_F)) {
		srealm = ((auth_body_t*)(hdr->parsed))->digest.username.user;
			
		if((furi=parse_from_uri(_m))==NULL)
			return AUTH_ERROR;
		
		if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) {
			if((turi=parse_to_uri(_m))==NULL)
				return AUTH_ERROR;
			uri = turi;
		} else {
			uri = furi;
		}
		if(srealm.len!=uri->user.len
					|| strncmp(srealm.s, uri->user.s, srealm.len)!=0)
			return AUTH_USER_MISMATCH;

		if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) {
			/* check from==to */
			if(furi->user.len!=turi->user.len
					|| strncmp(furi->user.s, turi->user.s, furi->user.len)!=0)
				return AUTH_USER_MISMATCH;
			if(use_domain!=0 && (furi->host.len!=turi->host.len
					|| strncmp(furi->host.s, turi->host.s, furi->host.len)!=0))
				return AUTH_USER_MISMATCH;
			/* check r-uri==from for publish */
			if(_m->REQ_METHOD==METHOD_PUBLISH) {
				if(parse_sip_msg_uri(_m)<0)
					return AUTH_ERROR;
				uri = &_m->parsed_uri;
				if(furi->user.len!=uri->user.len
						|| strncmp(furi->user.s, uri->user.s, furi->user.len)!=0)
					return AUTH_USER_MISMATCH;
				if(use_domain!=0 && (furi->host.len!=uri->host.len
						|| strncmp(furi->host.s, uri->host.s, furi->host.len)!=0))
					return AUTH_USER_MISMATCH;
				}
		}
		return AUTH_OK;
	}

	return ret;
}
예제 #16
0
int rls_handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_domain)
{
	subs_t subs;
	pres_ev_t* event = NULL;
	int err_ret = -1;
	int ret = to_presence_code;
	str* contact = NULL;
	xmlDocPtr doc = NULL;
	xmlNodePtr service_node = NULL;
	unsigned int hash_code=0;
	int to_tag_gen = 0;
	event_t* parsed_event;
	param_t* ev_param = NULL;
	str reason;
	int rt;
	str rlsubs_did = {0, 0};

	memset(&subs, 0, sizeof(subs_t));

	/** sanity checks - parse all headers */
	if (parse_headers(msg, HDR_EOH_F, 0)<-1)
	{
		LM_ERR("failed parsing all headers\n");
		if (slb.freply(msg, 400, &pu_400_rpl) < 0)
		{
			LM_ERR("while sending 400 reply\n");
			return -1;
		}
		return 0;
	}
	/* check for To and From headesr */
	if(parse_to_uri(msg)<0 || parse_from_uri(msg)<0)
	{
		LM_ERR("failed to find To or From headers\n");
		if (slb.freply(msg, 400, &pu_400_rpl) < 0)
		{
			LM_ERR("while sending 400 reply\n");
			return -1;
		}
		return 0;
	}
	if(get_from(msg)->tag_value.s ==NULL || get_from(msg)->tag_value.len==0)
	{
		LM_ERR("no from tag value present\n");
		return -1;
	}
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find callid header\n");
		return -1;
	}
	if(parse_sip_msg_uri(msg)<0)
	{
		LM_ERR("failed parsing Request URI\n");
		return -1;
	}

	/* check for header 'Support: eventlist' */
	if(msg->supported==NULL)
	{
		LM_DBG("supported header not found - not for rls\n");
		goto forpresence;
	}

	if(parse_supported(msg)<0)
	{
		LM_ERR("failed to parse supported headers\n");
		return -1;
	}

	if(!(get_supported(msg) & F_SUPPORTED_EVENTLIST))
	{
		LM_DBG("No support for 'eventlist' - not for rls\n");
		goto forpresence;
	}

	/* inspecting the Event header field */
	if(msg->event && msg->event->body.len > 0)
	{
		if (!msg->event->parsed && (parse_event(msg->event) < 0))
		{
			LM_ERR("cannot parse Event header\n");
			goto error;
		}
		if(! ( ((event_t*)msg->event->parsed)->type & rls_events) )
		{	
			goto forpresence;
		}
	} else {
		goto bad_event;
	}

	/* search event in the list */
	parsed_event = (event_t*)msg->event->parsed;
	event = pres_search_event(parsed_event);
	if(event==NULL)
	{
		goto bad_event;
	}
	subs.event= event;

	/* extract the id if any*/
	ev_param= parsed_event->params.list;
	while(ev_param)
	{
		if(ev_param->name.len==2 && strncmp(ev_param->name.s, "id", 2)==0)
		{
			subs.event_id = ev_param->body;
			break;
		}
		ev_param= ev_param->next;
	}

	/* extract dialog information from message headers */
	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
				&to_tag_gen, rls_server_address,
				watcher_user, watcher_domain)<0)
	{
		LM_ERR("bad subscribe request\n");
		goto error;
	}

	hash_code = core_hash(&subs.callid, &subs.to_tag, hash_size);
	if (CONSTR_RLSUBS_DID(&subs, &rlsubs_did) < 0)
	{
		LM_ERR("cannot build rls subs did\n");
		goto error;
	}
	subs.updated = core_hash(&rlsubs_did, NULL, 0) %
		(waitn_time * rls_notifier_poll_rate * rls_notifier_processes);
	
	if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
	{ /* initial Subscribe */
		/*verify if Request URI represents a list by asking xcap server*/	
		if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host,
					&subs.pres_uri)<0)
		{
			LM_ERR("while constructing uri from user and domain\n");
			goto error;
		}
		if(rls_get_service_list(&subs.pres_uri, &subs.watcher_user,
					&subs.watcher_domain, &service_node, &doc)<0)
		{
			LM_ERR("while attepmting to get a resource list\n");
			goto error;
		}
		if(doc==NULL)
		{
			/* if not for RLS, pass it to presence serivce */
			LM_DBG("list not found - searched for uri <%.*s>\n",
					subs.pres_uri.len, subs.pres_uri.s);
			goto forpresence;
		}

		/* if correct reply with 200 OK */
		if(reply_200(msg, &subs.local_contact, subs.expires)<0)
			goto error;

		subs.local_cseq = 0;

		if(subs.expires != 0)
		{
			subs.version = 1;
			if (dbmode==RLS_DB_ONLY)
			{
				rt=insert_rlsdb( &subs );
			}
			else
			{
				rt=pres_insert_shtable(rls_table, hash_code, &subs);
			}
			if (rt<0)
			{
				LM_ERR("while adding new subscription\n");
				goto error;
			}
		}
	} else {
		/* search if a stored dialog */
		if ( dbmode == RLS_DB_ONLY )
		{
			if (rls_dbf.start_transaction)
			{
				if (rls_dbf.start_transaction(rls_db, DB_LOCKING_WRITE) < 0)
				{
					LM_ERR("in start_transaction\n");
					goto error;
				}
			}

			rt = get_dialog_subscribe_rlsdb(&subs);

			if (rt <= 0)
			{
				LM_DBG("subscription dialog not found for <%.*s@%.*s>\n",
						subs.watcher_user.len, subs.watcher_user.s,
						subs.watcher_domain.len, subs.watcher_domain.s);

				if (rls_dbf.end_transaction)
				{
					if (rls_dbf.end_transaction(rls_db) < 0)
					{
						LM_ERR("in end_transaction\n");
						goto error;
					}
				}

				goto forpresence;
			}
			else if(rt>=400)
			{
				reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
		
				if (slb.freply(msg, 400, &reason) < 0)
				{
					LM_ERR("while sending reply\n");
					goto error;
				}

				if (rls_dbf.end_transaction)
				{
					if (rls_dbf.end_transaction(rls_db) < 0)
					{
						LM_ERR("in end_transaction\n");
						goto error;
					}
				}

				ret = 0;
				goto stop;
			}

			/* if correct reply with 200 OK */
			if(reply_200(msg, &subs.local_contact, subs.expires)<0)
				goto error;

			if (update_dialog_subscribe_rlsdb(&subs) < 0)
			{
				LM_ERR("while updating resource list subscription\n");
				goto error;
			}

			if (rls_dbf.end_transaction)
			{
				if (rls_dbf.end_transaction(rls_db) < 0)
				{
					LM_ERR("in end_transaction\n");
					goto error;
				}
			}
		}
		else
		{
			lock_get(&rls_table[hash_code].lock);
			if(pres_search_shtable(rls_table, subs.callid,
					subs.to_tag, subs.from_tag, hash_code)==NULL)
			{
				lock_release(&rls_table[hash_code].lock);
				LM_DBG("subscription dialog not found for <%.*s@%.*s>\n",
						subs.watcher_user.len, subs.watcher_user.s,
						subs.watcher_domain.len, subs.watcher_domain.s);
				goto forpresence;
			}
			lock_release(&rls_table[hash_code].lock);

			/* if correct reply with 200 OK */
			if(reply_200(msg, &subs.local_contact, subs.expires)<0)
				goto error;

			rt = update_rlsubs(&subs, hash_code);

			if(rt<0)
			{
				LM_ERR("while updating resource list subscription\n");
				goto error;
			}
	
			if(rt>=400)
			{
				reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
		
				if (slb.freply(msg, 400, &reason) < 0)
				{
					LM_ERR("while sending reply\n");
					goto error;
				}
				ret = 0;
				goto stop;
			}
		}	
		if(rls_get_service_list(&subs.pres_uri, &subs.watcher_user,
					&subs.watcher_domain, &service_node, &doc)<0)
		{
			LM_ERR("failed getting resource list\n");
			goto error;
		}
		if(doc==NULL)
		{
			/* warning: no document returned?!?! */
			LM_WARN("no document returned for uri <%.*s>\n",
					subs.pres_uri.len, subs.pres_uri.s);
			goto done;
		}
	}

	if (dbmode != RLS_DB_ONLY)
	{
		/* sending notify with full state */
		if(send_full_notify(&subs, service_node, &subs.pres_uri, hash_code)<0)
		{
			LM_ERR("failed sending full state notify\n");
			goto error;
		}
	}

	/* send subscribe requests for all in the list */
	if(resource_subscriptions(&subs, service_node)< 0)
	{
		LM_ERR("failed sending subscribe requests to resources in list\n");
		goto error;
	}

	if (dbmode !=RLS_DB_ONLY)
		remove_expired_rlsubs(&subs, hash_code);

done:
	ret = 1;
stop:
forpresence:
	if(contact!=NULL)
	{	
		if(contact->s!=NULL)
			pkg_free(contact->s);
		pkg_free(contact);
	}

	if(subs.pres_uri.s!=NULL)
		pkg_free(subs.pres_uri.s);
	if(subs.record_route.s!=NULL)
		pkg_free(subs.record_route.s);
	if(doc!=NULL)
		xmlFreeDoc(doc);
	if (rlsubs_did.s != NULL)
		pkg_free(rlsubs_did.s);
	return ret;

bad_event:
	err_ret = 0;
	if(reply_489(msg)<0)
	{
		LM_ERR("failed sending 489 reply\n");
		err_ret = -1;
	}

error:
	LM_ERR("occured in rls_handle_subscribe\n");

	if(contact!=NULL)
	{	
		if(contact->s!=NULL)
			pkg_free(contact->s);
		pkg_free(contact);
	}
	if(subs.pres_uri.s!=NULL)
		pkg_free(subs.pres_uri.s);

	if(subs.record_route.s!=NULL)
		pkg_free(subs.record_route.s);

	if(doc!=NULL)
		xmlFreeDoc(doc);

	if (rlsubs_did.s != NULL)
		pkg_free(rlsubs_did.s);

	if (rls_dbf.abort_transaction)
	{
		if (rls_dbf.abort_transaction(rls_db) < 0)
			LM_ERR("in abort_transaction\n");
	}
	
	return err_ret;
}
예제 #17
0
static int pv_auth_check(sip_msg_t *msg, str *srealm, str *spasswd, int vflags,
		int vchecks)
{
	int ret;
	hdr_field_t *hdr;
	sip_uri_t *uri = NULL;
	sip_uri_t *turi = NULL;
	sip_uri_t *furi = NULL;
	str suser;

	if(msg->REQ_METHOD==METHOD_REGISTER)
		ret = pv_authenticate(msg, srealm, spasswd, vflags, HDR_AUTHORIZATION_T,
				&msg->first_line.u.request.method);
	else
		ret = pv_authenticate(msg, srealm, spasswd, vflags, HDR_PROXYAUTH_T,
				&msg->first_line.u.request.method);

	if(ret==AUTH_OK && (vchecks&AUTH_CHECK_ID_F)) {
		hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;
		suser = ((auth_body_t*)(hdr->parsed))->digest.username.user;

		if((furi=parse_from_uri(msg))==NULL)
			return AUTH_ERROR;

		if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
			if((turi=parse_to_uri(msg))==NULL)
				return AUTH_ERROR;
			uri = turi;
		} else {
			uri = furi;
		}
		if(suser.len!=uri->user.len
				|| strncmp(suser.s, uri->user.s, suser.len)!=0)
			return AUTH_USER_MISMATCH;

		if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
			/* check from==to */
			if(furi->user.len!=turi->user.len
					|| strncmp(furi->user.s, turi->user.s, furi->user.len)!=0)
				return AUTH_USER_MISMATCH;
			if(auth_use_domain!=0 && (furi->host.len!=turi->host.len
						|| strncmp(furi->host.s, turi->host.s, furi->host.len)!=0))
				return AUTH_USER_MISMATCH;
			/* check r-uri==from for publish */
			if(msg->REQ_METHOD==METHOD_PUBLISH) {
				if(parse_sip_msg_uri(msg)<0)
					return AUTH_ERROR;
				uri = &msg->parsed_uri;
				if(furi->user.len!=uri->user.len
						|| strncmp(furi->user.s, uri->user.s, furi->user.len)!=0)
					return AUTH_USER_MISMATCH;
				if(auth_use_domain!=0 && (furi->host.len!=uri->host.len
							|| strncmp(furi->host.s, uri->host.s, furi->host.len)!=0))
					return AUTH_USER_MISMATCH;
			}
		}
		return AUTH_OK;
	}

	return ret;
}
예제 #18
0
int auth_check(sip_msg_t *_m, str *srealm, str *stable, int iflags)
{
	int ret;
	hdr_field_t *hdr;
	sip_uri_t *uri = NULL;
	sip_uri_t *turi = NULL;
	sip_uri_t *furi = NULL;
	str suser;

	if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) {
		return AUTH_OK;
	}

	if (srealm->len<=0) {
		LM_ERR("invalid realm parameter - empty value\n");
		return AUTH_ERROR;
	}

	if (stable->len==0) {
		LM_ERR("invalid table parameter - empty value\n");
		return AUTH_ERROR;
	}

	LM_DBG("realm [%.*s] table [%.*s] flags [%d]\n", srealm->len, srealm->s,
			stable->len,  stable->s, iflags);

	hdr = NULL;
	if(_m->REQ_METHOD==METHOD_REGISTER)
		ret = digest_authenticate_hdr(_m, srealm, stable, HDR_AUTHORIZATION_T,
						&_m->first_line.u.request.method, &hdr);
	else
		ret = digest_authenticate_hdr(_m, srealm, stable, HDR_PROXYAUTH_T,
						&_m->first_line.u.request.method, &hdr);

	if(ret==AUTH_OK && hdr!=NULL && (iflags&AUTH_CHECK_ID_F)) {
		suser = ((auth_body_t*)(hdr->parsed))->digest.username.user;

		if((furi=parse_from_uri(_m))==NULL)
			return AUTH_ERROR;

		if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) {
			if((turi=parse_to_uri(_m))==NULL)
				return AUTH_ERROR;
			uri = turi;
		} else {
			uri = furi;
		}
		if(!((iflags&AUTH_CHECK_SKIPFWD_F)
				&& (_m->REQ_METHOD==METHOD_INVITE || _m->REQ_METHOD==METHOD_BYE
					|| _m->REQ_METHOD==METHOD_PRACK || _m->REQ_METHOD==METHOD_UPDATE
					|| _m->REQ_METHOD==METHOD_MESSAGE))) {
			if(suser.len!=uri->user.len
						|| strncmp(suser.s, uri->user.s, suser.len)!=0) {
				LM_DBG("authentication username mismatch with from/to username\n");
				return AUTH_USER_MISMATCH;
			}
		}

		if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) {
			/* check from==to */
			if(furi->user.len!=turi->user.len
					|| strncmp(furi->user.s, turi->user.s, furi->user.len)!=0) {
				LM_DBG("from username mismatch with to username\n");
				return AUTH_USER_MISMATCH;
			}
			if(use_domain!=0 && (furi->host.len!=turi->host.len
					|| strncmp(furi->host.s, turi->host.s, furi->host.len)!=0)) {
				LM_DBG("from domain mismatch with to domain\n");
				return AUTH_USER_MISMATCH;
			}
			/* check r-uri==from for publish */
			if(_m->REQ_METHOD==METHOD_PUBLISH) {
				if(parse_sip_msg_uri(_m)<0)
					return AUTH_ERROR;
				uri = &_m->parsed_uri;
				if(furi->user.len!=uri->user.len
						|| strncmp(furi->user.s, uri->user.s, furi->user.len)!=0) {
					LM_DBG("from username mismatch with r-uri username\n");
					return AUTH_USER_MISMATCH;
				}
				if(use_domain!=0 && (furi->host.len!=uri->host.len
						|| strncmp(furi->host.s, uri->host.s, furi->host.len)!=0)) {
					LM_DBG("from domain mismatch with r-uri domain\n");
					return AUTH_USER_MISMATCH;
				}
			}
		}
		return AUTH_OK;
	}

	return ret;
}
예제 #19
0
/*!
 * \brief Extract the username and domain from the SIP message
 *
 * Set the username and domain depending on the value of the SIP
 * message and the group check structure.
 * \param msg SIP message
 * \param gcp group check structure
 * \param username stored username
 * \param domain stored domain
 * \return 0 on success, -1 on failure
 */
int get_username_domain(struct sip_msg *msg, group_check_p gcp,
											str *username, str *domain)
{
	struct sip_uri puri;
	struct sip_uri *turi;
	struct hdr_field* h;
	struct auth_body* c = 0;
	pv_value_t value;

	turi = NULL;

	switch(gcp->id) {
		case 1: /* Request-URI */
			if(parse_sip_msg_uri(msg)<0) {
				LM_ERR("failed to get Request-URI\n");
				return -1;
			}
			turi = &msg->parsed_uri;
			break;

		case 2: /* To */
			if((turi=parse_to_uri(msg))==NULL) {
				LM_ERR("failed to get To URI\n");
				return -1;
			}
			break;

		case 3: /* From */
			if((turi=parse_from_uri(msg))==NULL) {
				LM_ERR("failed to get From URI\n");
				return -1;
			}
			break;

		case 4: /* Credentials */
			get_authorized_cred( msg->authorization, &h);
			if (!h) {
				get_authorized_cred( msg->proxy_auth, &h);
				if (!h) {
					LM_ERR("no authorized credentials found "
							"(error in scripts)\n");
					return -1;
				}
			}
			c = (auth_body_t*)(h->parsed);
			break;

		case 5: /* AVP spec */
			if(pv_get_spec_value( msg, &gcp->sp, &value)!=0 
				|| value.flags&PV_VAL_NULL || value.rs.len<=0)
			{
				LM_ERR("no AVP found (error in scripts)\n");
				return -1;
			}
			if (parse_uri(value.rs.s, value.rs.len, &puri) < 0) {
				LM_ERR("failed to parse URI <%.*s>\n",value.rs.len, value.rs.s);
				return -1;
			}
			turi = &puri;
			break;
		default: {
			LM_ERR("incorrect check id %d\n", gcp->id);
			return -1;
		}
	}

	if (gcp->id != 4) {
		*username = turi->user;
		*domain = turi->host;
	} else {
		*username = c->digest.username.user;
		*domain = *(GET_REALM(&c->digest));
	}
	return 0;
}
예제 #20
0
파일: group.c 프로젝트: GeorgeShaw/opensips
int get_username_domain(struct sip_msg *msg, str *hf_s,
											str *username, str *domain)
{
	struct sip_uri puri;
	struct sip_uri *turi;
	struct hdr_field* h;
	struct auth_body* c = 0; /* Makes gcc happy */

	turi = NULL;

	switch( hf_type(hf_s) ) {
		case 1: /* Request-URI */
			if(parse_sip_msg_uri(msg)<0) {
				LM_ERR("failed to get Request-URI\n");
				return -1;
			}
			turi = &msg->parsed_uri;
			break;

		case 2: /* To */
			if((turi=parse_to_uri(msg))==NULL) {
				LM_ERR("failed to get To URI\n");
				return -1;
			}
			break;

		case 3: /* From */
			if((turi=parse_from_uri(msg))==NULL) {
				LM_ERR("failed to get From URI\n");
				return -1;
			}
			break;

		case 4: /* Credentials */
			get_authorized_cred( msg->authorization, &h);
			if (!h) {
				get_authorized_cred( msg->proxy_auth, &h);
				if (!h) {
					LM_ERR("no authorized credentials found "
							"(error in scripts)\n");
					return -1;
				}
			}
			c = (auth_body_t*)(h->parsed);
			break;

		default: /* string */
			if (parse_uri(hf_s->s, hf_s->len, &puri) < 0) {
				LM_ERR("failed to parse URI <%.*s>\n",hf_s->len, hf_s->s);
				return -1;
			}
			turi = &puri;
			break;
	}

	if ( c==NULL ) {
		*username = turi->user;
		*domain = turi->host;
	} else {
		*username = c->digest.username.user;
		*domain = *(GET_REALM(&c->digest));
	}
	return 0;
}