コード例 #1
0
ファイル: auth_mod.c プロジェクト: aphistic/kamailio
static int pv_proxy_authenticate(struct sip_msg *msg, char* realm,
		char *passwd, char *flags)
{
	int vflags = 0;
	str srealm  = {0, 0};
	str spasswd = {0, 0};

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

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

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

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

	if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
		LM_ERR("invalid flags value\n");
		goto error;
	}
	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T,
			&msg->first_line.u.request.method);

error:
	return AUTH_ERROR;
}
コード例 #2
0
ファイル: authorize.c プロジェクト: btriller/kamailio
int autheph_authenticate(struct sip_msg *_m, char *_username, char *_password)
{
	str susername, spassword;

	if (_m == NULL || _username == NULL || _password == NULL)
	{
		LM_ERR("invalid parameters\n");
		return AUTH_ERROR;
	}

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

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

	return ki_autheph_authenticate(_m, &susername, &spassword);
}
コード例 #3
0
ファイル: sl.c プロジェクト: Jared-Prime/kamailio
/**
 * @brief Small wrapper around send_reply
 */
static int w_send_reply(struct sip_msg* msg, char* p1, char* p2)
{
    int code;
    str reason;

    if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) {
		code = default_code;
    }

    if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) {
		reason = default_reason;
    }

	return send_reply(msg, code, &reason);
}
コード例 #4
0
ファイル: sca.c プロジェクト: btriller/kamailio
static int sca_call_info_update_3_f(sip_msg_t* msg,
	char* p1, char* p2, char * p3)
{
	str uri_to = STR_NULL;
	str uri_from = STR_NULL;
	int update_mask = SCA_CALL_INFO_SHARED_BOTH;

	if (get_int_fparam(&update_mask, msg, (fparam_t *) p1) < 0) {
		LM_ERR("sca_call_info_update: argument 1: bad value "
				"(integer expected)\n");
		return (-1);
	}
	if(get_str_fparam(&uri_to, msg, (gparam_p)p2)!=0)
	{
		LM_ERR("unable to get value from param pvar_to\n");
		return -1;
	}
	if(get_str_fparam(&uri_from, msg, (gparam_p)p3)!=0)
	{
		LM_ERR("unable to get value from param pvar_from\n");
		return -1;
	}
	return sca_call_info_update(msg, update_mask, &uri_to, &uri_from);
}
コード例 #5
0
ファイル: tm.c プロジェクト: Gaoithe/openimscore_ims
inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2)
{
	struct cell *t;
	int code, ret = -1;
	str reason;
	char* r;

	if (msg->REQ_METHOD==METHOD_ACK) {
		LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
		return -1;
	}
	if (t_check( msg , 0 )==-1) return -1;
	t=get_t();
	if (!t) {
		LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
			"for which no T-state has been established\n");
		return -1;
	}

	if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) {
	    code = default_code;
	}
	
	if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) {
	    reason = default_reason;
	}
	
	r = as_asciiz(&reason);
	if (r == NULL) r = default_reason.s;
	
	/* if called from reply_route, make sure that unsafe version
	 * is called; we are already in a mutex and another mutex in
	 * the safe version would lead to a deadlock
	 */
	 
	if (rmode==MODE_ONFAILURE) {
		DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");
		ret = t_reply_unsafe(t, msg, code, r);
	} else if (rmode==MODE_REQUEST) {
		ret = t_reply( t, msg, code, r);
	} else {
		LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n");
		ret = -1;
	}

	if (r) pkg_free(r);
	return ret;
}
コード例 #6
0
ファイル: enum.c プロジェクト: TheGrandWazoo/kamailio
/*
 * Call enum_query_2 with given suffix and service.
 */
int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
{
    str suffix, *service;
  
    if (get_str_fparam(&suffix, _msg, (fparam_t*)_suffix) != 0) {
	LM_ERR("unable to get suffix\n");
	return -1;
    }

    service = (str*)_service;
    if ((service == NULL) || (service->len == 0)) {
	LM_ERR("invalid service parameter");
	return -1;
    }

    return enum_query(_msg, &suffix, service);
}
コード例 #7
0
ファイル: authorize.c プロジェクト: 4N7HR4X/kamailio
int autheph_check(struct sip_msg *_m, char *_realm)
{
	str srealm;

	if (eph_auth_api.pre_auth == NULL)
	{
		LM_ERR("autheph_check() cannot be used without the auth "
			"module\n");
		return AUTH_ERROR;
	}

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

	if(_m == NULL || _realm == 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 (_m->REQ_METHOD == METHOD_REGISTER)
	{
		return digest_authenticate(_m, &srealm, HDR_AUTHORIZATION_T,
					&_m->first_line.u.request.method);
	}
	else
	{
		return digest_authenticate(_m, &srealm, HDR_PROXYAUTH_T,
					&_m->first_line.u.request.method);
	}
}
コード例 #8
0
ファイル: authorize.c プロジェクト: btriller/kamailio
int autheph_proxy(struct sip_msg *_m, char *_realm, char *_p2)
{
	str srealm;

	if(_m == NULL || _realm == 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;
	}

	return ki_autheph_proxy(_m, &srealm);
}
コード例 #9
0
ファイル: lookup.c プロジェクト: olegagafonov/kamailio
int lookup_path_to_contact(struct sip_msg* _m, char* contact_uri) {
    ucontact_t* contact;
    str s_contact_uri;
    str path_dst;

    get_act_time();
    if (get_str_fparam(&s_contact_uri, _m, (fparam_t*) contact_uri) < 0) {
        LM_ERR("failed to get RURI\n");
        return -1;
    }
    LM_DBG("Looking up contact [%.*s]\n", s_contact_uri.len, s_contact_uri.s);

    if (ul.get_ucontact(NULL, &s_contact_uri, 0, 0, 0, &contact) == 0) { //get_contact returns with lock

        if (!VALID_CONTACT(contact, act_time)) {
            LM_DBG("Contact is not valid...ignoring\n");
            ul.release_ucontact(contact);
        } else {
            LM_DBG("CONTACT FOUND and path is [%.*s]\n", contact->path.len, contact->path.s);

            if (get_path_dst_uri(&contact->path, &path_dst) < 0) {
                LM_ERR("failed to get dst_uri for Path\n");
                ul.release_ucontact(contact);
                return -1;
            }
            if (set_path_vector(_m, &contact->path) < 0) {
                LM_ERR("failed to set path vector\n");
                ul.release_ucontact(contact);
                return -1;
            }
            if (set_dst_uri(_m, &path_dst) < 0) {
                LM_ERR("failed to set dst_uri of Path\n");
                ul.release_ucontact(contact);
                return -1;
            }

            ul.release_ucontact(contact);
            return 1;
        }
    }
    LM_DBG("no contact found for [%.*s]\n", s_contact_uri.len, s_contact_uri.s);
    return -1;
}
コード例 #10
0
ファイル: sl.c プロジェクト: BackupTheBerlios/openimscore-svn
static int w_sl_send_reply(struct sip_msg* msg, char* p1, char* p2)
{
    int code, ret;
    str reason;
    char* r;

    if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) {
	code = default_code;
    }
    
    if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) {
	reason = default_reason;;
    }

    r = as_asciiz(&reason);
    if (r == NULL) r = default_reason.s;
    ret = sl_send_reply(msg, code, r);
    if (r) pkg_free(r);
    return ret;
}
コード例 #11
0
ファイル: avp.c プロジェクト: 2pac/kamailio
static int append_reply(struct sip_msg* msg, char* p1, char* p2)
{
    avp_ident_t ident, *avp;
    str hf;
    
    if (get_str_fparam(&hf, msg, (fparam_t*)p1) < 0) {
	ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p1)->orig);
	return -1;
    }
    
    if (p2) {
	avp = &((fparam_t*)p2)->v.avp;
    } else {
	ident.name.s = hf;
	ident.flags = AVP_NAME_STR;
	ident.index = 0;
	avp = &ident;
    }
    return (request_hf_helper(msg, &hf, avp, NULL, NULL, 0, 1, 1));
}
コード例 #12
0
ファイル: checks.c プロジェクト: BackupTheBerlios/ser
/*
 * Check if the username matches the username in credentials
 */
int is_user(struct sip_msg* _m, char* _user, char* _str2)
{
	str s;
	struct hdr_field* h;
	auth_body_t* c;

	if (get_str_fparam(&s, _m, (fparam_t *)_user) < 0) {
		ERR("is_user: failed to recover parameter.\n");
		return -1;
	}

	get_authorized_cred(_m->authorization, &h);
	if (!h) {
		get_authorized_cred(_m->proxy_auth, &h);
		if (!h) {
			LOG(L_ERR, "is_user(): No authorized credentials found (error in scripts)\n");
			LOG(L_ERR, "is_user(): Call {www,proxy}_authorize before calling is_user function !\n");
			return -1;
		}
	}

	c = (auth_body_t*)(h->parsed);

	if (!c->digest.username.user.len) {
		DBG("is_user(): Username not found in credentials\n");
		return -1;
	}

	if (s.len != c->digest.username.user.len) {
		DBG("is_user(): Username length does not match\n");
		return -1;
	}

	if (!memcmp(s.s, c->digest.username.user.s, s.len)) {
		DBG("is_user(): Username matches\n");
		return 1;
	} else {
		DBG("is_user(): Username differs\n");
		return -1;
	}
}
コード例 #13
0
ファイル: avp.c プロジェクト: 2pac/kamailio
static int set_sattr(struct sip_msg* msg, char* p1, char* p2)
{
    avp_ident_t avpid;
    int_str value;
    
    if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) {
	return -1;
    }

    if (get_str_fparam(&value.s, msg, (fparam_t*)p2) < 0) {
	ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p2)->orig);
	return -1;
    }
    
    if (add_avp(avpid.flags | AVP_NAME_STR | AVP_VAL_STR, avpid.name, value) != 0) {
	ERR("add_avp failed\n");
	return -1;
    }
    
    return 1;
}
コード例 #14
0
ファイル: sdpops_mod.c プロジェクト: barchandune/kamailio
/**
 * removes all SDP lines that begin with script provided prefix
 * @return -1 - error; 1 - found
 */
static int w_sdp_remove_line_by_prefix(sip_msg_t* msg, char* prefix, char* bar)
{
	str prfx = {NULL, 0};

	if(prefix==0)
	{
		LM_ERR("invalid parameters\n");
		return -1;
	}

	if (get_str_fparam(&prfx, msg, (fparam_t*)prefix))
	{
		LM_ERR("unable to determine prefix\n");
		return -1;
	}
	LM_DBG("Removing SDP lines with prefix: %.*s\n", prfx.len, prfx.s);

	if ( sdp_remove_line_by_prefix(msg, &prfx) < 0)
		return -1;
	return 1;
}
コード例 #15
0
ファイル: lookup.c プロジェクト: kiryu/kamailio
/*
 * Return true if the AOR in the Request-URI is registered,
 * it is similar to lookup but registered neither rewrites
 * the Request-URI nor appends branches
 */
int registered2(struct sip_msg* _m, char* _t, char* p2)
{
	str uid, aor;
	urecord_t* r;
        ucontact_t* ptr;
	int res;

	if (get_str_fparam(&aor, _m, (fparam_t*)p2) != 0) {
	    ERR("Unable to get the AOR value\n");
	    return -1;
	}

	if (get_to_uid(&uid, _m) < 0) return -1;

	ul.lock_udomain((udomain_t*)_t);
	res = ul.get_urecord((udomain_t*)_t, &uid, &r);

	if (res < 0) {
		ul.unlock_udomain((udomain_t*)_t);
		LOG(L_ERR, "registered(): Error while querying usrloc\n");
		return -1;
	}

	if (res == 0) {
		ptr = r->contacts;
		while (ptr && (!VALID_CONTACT(ptr, act_time) || !VALID_AOR(ptr, aor))) {
			ptr = ptr->next;
		}

		if (ptr) {
			ul.unlock_udomain((udomain_t*)_t);
			DBG("registered(): '%.*s' found in usrloc\n", uid.len, ZSW(uid.s));
			return 1;
		}
	}

	ul.unlock_udomain((udomain_t*)_t);
	DBG("registered(): '%.*s' not found in usrloc\n", uid.len, ZSW(uid.s));
	return -1;
}
コード例 #16
0
ファイル: diversion.c プロジェクト: Gaoithe/openimscore_ims
int add_diversion(struct sip_msg* msg, char* r, char* s)
{
	str div_hf;
	char *at;
	str* uri;
	str reason;

	if (get_str_fparam(&reason, msg, (fparam_t*)r) < 0) return -1;

	uri = &msg->first_line.u.request.uri;

	div_hf.len = DIVERSION_PREFIX_LEN + uri->len + DIVERSION_SUFFIX_LEN + reason.len + CRLF_LEN;
	div_hf.s = pkg_malloc(div_hf.len);
	if (!div_hf.s) {
		LOG(L_ERR, "add_diversion: No memory left\n");
		return -1;
	}

	at = div_hf.s;
	memcpy(at, DIVERSION_PREFIX, DIVERSION_PREFIX_LEN);
	at += DIVERSION_PREFIX_LEN;

	memcpy(at, uri->s, uri->len);
	at += uri->len;

	memcpy(at, DIVERSION_SUFFIX, DIVERSION_SUFFIX_LEN);
	at += DIVERSION_SUFFIX_LEN;

	memcpy(at, reason.s, reason.len);
	at += reason.len;

	memcpy(at, CRLF, CRLF_LEN);

	if (add_diversion_helper(msg, &div_hf) < 0) {
		pkg_free(div_hf.s);
		return -1;
	}

	return 1;
}
コード例 #17
0
static int lookup_domain(struct sip_msg* msg, char* flags, char* fp)
{
    str domain, tmp;
    domain_t* d;
    unsigned int track;
    int ret = -1;
    
    track = 0;
    
    if (get_str_fparam(&domain, msg, (fparam_t*)fp) != 0) {
	ERR("Cannot get domain name to lookup\n");
	return -1;
    }
    
    tmp.s = pkg_malloc(domain.len);
    if (!tmp.s) {
	ERR("No memory left\n");
	return -1;
    }
    memcpy(tmp.s, domain.s, domain.len);
    tmp.len = domain.len;
    strlower(&tmp);

    if (db_mode) {
	if (hash_lookup(&d, *active_hash, &tmp) == 1) {
	    set_avp_list((unsigned long)flags, &d->attrs);
	    ret = 1;
	}
    } else {
	if (db_load_domain(&d, (unsigned long)flags, &tmp) == 0) {
	    set_avp_list((unsigned long)flags, &d->attrs);
	    ret = 1;
	}
    }

    pkg_free(tmp.s);
    return ret;
}
コード例 #18
0
ファイル: http_client.c プロジェクト: albertollamaso/kamailio
/*!
 * Wrapper for HTTP-Query (GET)
 */
static int w_http_query(struct sip_msg* _m, char* _url, char* _result) {
	int ret = 0;
	str url = {NULL, 0};
	str result = {NULL, 0};
	pv_spec_t *dst;
	pv_value_t val;

	if (get_str_fparam(&url, _m, (gparam_p)_url) != 0) {
		LM_ERR("URL undefined\n");
		return -1;
	}

	ret = http_query(_m, url.s, &result, NULL);

	val.rs = result;
	val.flags = PV_VAL_STR;
	dst = (pv_spec_t *)_result;
	dst->setf(_m, &dst->pvp, (int)EQ_T, &val);

	if (result.s != NULL)
		pkg_free(result.s);
	return (ret==0)?-1:ret;
}
コード例 #19
0
ファイル: avp.c プロジェクト: 2pac/kamailio
/*
 *  returns 1 if msg contains an AVP with the given name and value,
 *  returns -1 otherwise
 */
static int attr_equals(struct sip_msg* msg, char* p1, char* p2)
{
    avp_ident_t avpid;
    int_str value, avp_value;
    avp_t* avp;
    struct search_state st;

    if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) {
	return -1;
    }

    if (p2 && get_str_fparam(&value.s, msg, (fparam_t*)p2) < 0) {
	ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p2)->orig);
	return -1;
    }

    avp = search_avp(avpid, &avp_value, &st);
    if (avp == 0) return -1;

    if (!p2) return 1;
    
    while (avp != 0) {
	if (avp->flags & AVP_VAL_STR) {
	    if ((avp_value.s.len == value.s.len) &&
		!memcmp(avp_value.s.s, value.s.s, avp_value.s.len)) {
		return 1;
	    }
	} else {
	    if (avp_value.n == str2s(value.s.s, value.s.len, 0)) {
		return 1;
	    }
	}
	avp = search_next_avp(&st, &avp_value);
    }
    
    return -1;
}
コード例 #20
0
ファイル: reg_avps.c プロジェクト: 4N7HR4X/kamailio
int read_reg_avps(struct sip_msg *m, char* _domain, char* fp)
{
	urecord_t* r = NULL;
	struct ucontact *contact = NULL;
	udomain_t *d;
	str uid;
	
	if (!use_reg_avps()) return 1;

	d = (udomain_t*)_domain;
	if (get_str_fparam(&uid, m, (fparam_t*)fp) < 0) {
		ERR("invalid parameter\n");
		return -1;
	}
	
/*	INFO("reading avps for uid=%.*s\n", uid.len, ZSW(uid.s)); */

	lock_udomain(d);
	
	if (get_urecord(d, &uid, &r) != 0) {
		unlock_udomain(d);
		WARN("urecord not found\n");
		return -1;
	}

	if (get_ucontact(r, &m->new_uri, &contact) != 0) {
		unlock_udomain(d);
		WARN("ucontact not found\n");
		return -1;
	}

	load_reg_avps(contact);
	
	unlock_udomain(d);
	
	return 1;
}
コード例 #21
0
ファイル: checks.c プロジェクト: Jared-Prime/kamailio
int autheph_check_to1(struct sip_msg *_m, char *_username)
{
	str susername;

	if (_m == NULL || _username == NULL)
	{
		LM_ERR("invalid parameters\n");
		return CHECK_ERROR;
	}

	if (get_str_fparam(&susername, _m, (fparam_t*)_username) < 0)
	{
		LM_ERR("failed to get username value\n");
		return CHECK_ERROR;
	}

	if (susername.len == 0)
	{
		LM_ERR("invalid username parameter - empty value\n");
		return CHECK_ERROR;
	}

	return check_to(_m, &susername);
}
コード例 #22
0
static int w_auth_challenge(struct sip_msg *msg, char* realm, char *flags)
{
	int vflags = 0;
	str srealm  = {0, 0};

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

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

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

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

	if(msg->REQ_METHOD==METHOD_REGISTER)
		return auth_challenge(msg, &srealm, vflags, HDR_AUTHORIZATION_T);
	else
		return auth_challenge(msg, &srealm, vflags, HDR_PROXYAUTH_T);

error:
	if(!(vflags&4)) {
		if(auth_send_reply(msg, 500, "Internal Server Error", 0, 0) <0 )
			return -4;
	}
	return -1;
}
コード例 #23
0
ファイル: checks.c プロジェクト: AndreyRybkin/kamailio
/*
 * Converts URI, if it is tel URI, to SIP URI.  Returns 1, if
 * conversion succeeded or if no conversion was needed, i.e., URI was not
 * tel URI.  Returns -1, if conversion failed.  Takes SIP URI hostpart from
 * second parameter and (if needed) writes the result to third paramater.
 */
int tel2sip(struct sip_msg* _msg, char* _uri, char* _hostpart, char* _res)
{
    str uri, hostpart, tel_uri, sip_uri;
    char *at;
    int i, j, in_tel_parameters = 0;
    pv_spec_t *res;
    pv_value_t res_val;

    /* get parameters */
    if (get_str_fparam(&uri, _msg, (fparam_t*)_uri) < 0) {
	LM_ERR("failed to get uri value\n");
    }
    if (get_str_fparam(&hostpart, _msg, (fparam_t*)_hostpart) < 0) {
	LM_ERR("failed to get hostpart value\n");
    }
    res = (pv_spec_t *)_res;

    /* check if anything needs to be done */
    if (uri.len < 4) return 1;
    if (strncasecmp(uri.s, "tel:", 4) != 0) return 1;
    
    /* reserve memory for clean tel uri */
    tel_uri.s = pkg_malloc(uri.len+1);
    if (tel_uri.s == 0) {
	LM_ERR("no more pkg memory\n");
	return -1;
    }
	
    /* Remove visual separators before converting to SIP URI. Don't remove 
       visual separators in TEL URI parameters (after the first ";") */
    for (i=0, j=0; i < uri.len; i++) {
	if (in_tel_parameters == 0) {
	    if (uri.s[i] == ';')
		in_tel_parameters = 1;
	}
	if (in_tel_parameters == 0) {
	    if ((uri.s[i] != '-') && (uri.s[i] != '.') && 
		(uri.s[i] != '(') && (uri.s[i] != ')'))
		tel_uri.s[j++] = tolower(uri.s[i]);
	} else {
	    tel_uri.s[j++] = tolower(uri.s[i]);
	}
    }
    tel_uri.s[j] = '\0';
    tel_uri.len = strlen(tel_uri.s);

    /* reserve memory for resulting sip uri */
    sip_uri.len = 4 + tel_uri.len - 4 + 1 + hostpart.len + 1 + 10;
    sip_uri.s = pkg_malloc(sip_uri.len);
    if (sip_uri.s == 0) {
	LM_ERR("no more pkg memory\n");
	pkg_free(tel_uri.s);
	return -1;
    }

    /* create resulting sip uri */
    at = sip_uri.s;
    append_str(at, "sip:", 4);
    append_str(at, tel_uri.s + 4, tel_uri.len - 4);
    append_chr(at, '@');
    append_str(at, hostpart.s, hostpart.len);
    append_chr(at, ';');
    append_str(at, "user=phone", 10);

    /* tel_uri is not needed anymore */
    pkg_free(tel_uri.s);

    /* set result pv value and write sip uri to result pv */
    res_val.rs = sip_uri;
    res_val.flags = PV_VAL_STR;
    if (res->setf(_msg, &res->pvp, (int)EQ_T, &res_val) != 0) {
	LM_ERR("failed to set result pvar\n");
	pkg_free(sip_uri.s);
	return -1;
    }

    /* free allocated pkg memory and return */
    pkg_free(sip_uri.s);
    return 1;
}
コード例 #24
0
ファイル: avp_db.c プロジェクト: Gaoithe/openimscore_ims
static int load_user_attrs(struct sip_msg* msg, unsigned long flags, fparam_t* fp)
{
    int_str name, v;
    str avp_name, avp_val;
    int i, type, n;
    db_key_t keys[1], cols[4];
    db_res_t* res;
    db_val_t kv[1], *val;

    keys[0] = uid_column;
    kv[0].type = DB_STR;
    kv[0].nul = 0;
    if (get_str_fparam(&kv[0].val.str_val, msg, (fparam_t*)fp) < 0) {
	ERR("Unable to get UID\n");
	return -1;
    }

    cols[0] = name_column;
    cols[1] = type_column;
    cols[2] = val_column;
    cols[3] = flags_column;
    
    if (db.use_table(con, user_attrs_table) < 0) {
	ERR("Error in use_table\n");
	return -1;
    }
    
    if (db.query(con, keys, 0, kv, cols, 1, 4, 0, &res) < 0) {
	ERR("Error while quering database\n");
	return -1;
    }
    
    n = 0;
    /* AVP names from DB are always strings */
    flags |= AVP_NAME_STR;
    for(i = 0; i < res->n; i++) {
	/* reset val_str as the value could be an integer */
	flags &= ~AVP_VAL_STR;
	val = res->rows[i].values;
	
	if (val[0].nul || val[1].nul || val[3].nul) {
	    ERR("Skipping row containing NULL entries\n");
	    continue;
	}
	
	if ((val[3].val.int_val & DB_LOAD_SER) == 0) continue;
	
	n++;
	     /* Get AVP name */
	avp_name.s = (char*)val[0].val.string_val;
	avp_name.len = strlen(avp_name.s);
	name.s = avp_name;
	
	     /* Get AVP type */
	type = val[1].val.int_val;
	
	     /* Test for NULL value */
	if (val[2].nul) {
	    avp_val.s = 0;
	    avp_val.len = 0;
	} else {
	    avp_val.s = (char*)val[2].val.string_val;
	    avp_val.len = strlen(avp_val.s);
	}

	if (type == AVP_VAL_STR) {
		 /* String AVP */
	    v.s = avp_val;
	    flags |= AVP_VAL_STR;
	} else {
		 /* Integer AVP */
	    str2int(&avp_val, (unsigned*)&v.n);
	}
	
	if (add_avp(flags, name, v) < 0) {
	    ERR("Error while adding user attribute %.*s, skipping\n",
		avp_name.len, ZSW(avp_name.s));
	    continue;
	}
    }
    DBG("avp_db:load_attrs: %d user attributes found, %d loaded\n", res->n, n);
    db.free_result(con, res);
    return 1;
}
コード例 #25
0
ファイル: permissions.c プロジェクト: Jared-Prime/kamailio
static int w_ip_is_trusted(struct sip_msg* msg, char* _ip_set, char* _ip) {
	str ip_set_s, ip_s;
	struct ip_addr *ip, ip_buf;
	struct ip_set new_ip_set, *ip_set;
	struct ip_set_list_item *isli = NULL;
	int kind;
	kind = ((struct ip_set_param*)_ip_set)->kind;
	if (kind == IP_SET_PARAM_KIND_LOCAL) {
		if (get_str_fparam(&ip_set_s, msg, ((struct ip_set_param*)_ip_set)->u.local.fparam) < 0) {
		    ERR(MODULE_NAME": ip_is_trusted: Error while obtaining ip_set parameter value\n");
			return -1;
		}
		if (is_ip_set_name(&ip_set_s)) {
			isli = ip_set_list_find_by_name(ip_set_s);
			if (!isli) {
				ERR(MODULE_NAME": ip_is_trusted: ip set '%.*s' is not declared\n", ip_set_s.len, ip_set_s.s);
				return -1;
			}
			kind = IP_SET_PARAM_KIND_GLOBAL;
			goto force_global;
		}		
		ip_set = &((struct ip_set_param*)_ip_set)->u.local.ip_set;
	}
	else {
		isli = ((struct ip_set_param*)_ip_set)->u.global.ip_set;
	force_global:
		if (!isli->ip_set) return -1; /* empty ip set */
		
		if (unlikely(isli->ip_set != ip_set_list_local[isli->idx])) {   /* global ip set has changed ? */
			if (ip_set_list_local[isli->idx]) {
				if (atomic_dec_and_test(&ip_set_list_local[isli->idx]->refcnt)) {
					ip_set_destroy(&ip_set_list_local[isli->idx]->ip_set);
					shm_free(ip_set_list_local[isli->idx]);
					ip_set_list_local[isli->idx] = NULL;
				}
			}
			lock_get(&isli->read_lock);			
			atomic_inc(&isli->ip_set->refcnt);
			ip_set_list_local[isli->idx] = isli->ip_set;
			lock_release(&isli->read_lock);
		}
		ip_set = &ip_set_list_local[isli->idx]->ip_set;
	}
	
	if (get_str_fparam(&ip_s, msg, (fparam_t*)_ip) < 0) {
	    ERR(MODULE_NAME": ip_is_trusted: Error while obtaining ip parameter value\n");
	    return -1;
	}
	if (!ip_s.len || !ip_set_s.len) return -1;
	switch (ip_s.s[0]) {
		case 's':	/* src */
		case 'S':
			ip = &msg->rcv.src_ip;
			break;
		case 'd':	/* dst */
		case 'D':
			ip = &msg->rcv.dst_ip;
			break;
		case 'r':	/* rcv */
		case 'R':
			ip = &msg->rcv.bind_address->address;
			break;			
		default:
			/* string -> ip */

			if ( ((ip = str2ip(&ip_s))==0)
			                  && ((ip = str2ip6(&ip_s))==0)
							                  ){
				ERR(MODULE_NAME": ip_is_trusted: string to ip conversion error '%.*s'\n", ip_s.len, ip_s.s);
				return -1;
			}
			ip_buf = *ip;
			ip = &ip_buf;  /* value has been in static buffer */			
			break;
	}

	/* test if ip_set string has changed since last call */
	if (kind == IP_SET_PARAM_KIND_LOCAL) {
		if (((struct ip_set_param*)_ip_set)->u.local.s.len != ip_set_s.len || 
			memcmp(((struct ip_set_param*)_ip_set)->u.local.s.s, ip_set_s.s, ip_set_s.len) != 0) {

			ip_set_init(&new_ip_set, 0);
			if (ip_set_add_list(&new_ip_set, ip_set_s) < 0) {
				ip_set_destroy(&new_ip_set);
				return -1;
			};
			if (((struct ip_set_param*)_ip_set)->u.local.sz < ip_set_s.len) {
				void *p;
				p = pkg_realloc(((struct ip_set_param*)_ip_set)->u.local.s.s, ip_set_s.len);
				if (!p) {
					ip_set_destroy(&new_ip_set);
					return E_OUT_OF_MEM;
				}
				((struct ip_set_param*)_ip_set)->u.local.s.s = p;			
				((struct ip_set_param*)_ip_set)->u.local.sz = ip_set_s.len;			
			}
			memcpy(((struct ip_set_param*)_ip_set)->u.local.s.s, ip_set_s.s, ip_set_s.len);
			((struct ip_set_param*)_ip_set)->u.local.s.len = ip_set_s.len;
			ip_set_destroy(&((struct ip_set_param*)_ip_set)->u.local.ip_set);
			((struct ip_set_param*)_ip_set)->u.local.ip_set = new_ip_set;
		}
	}
/* ip_set_print(stderr, &ip_set); */
	switch (ip_set_ip_exists(ip_set, ip)) {
		case IP_TREE_FIND_FOUND:
		case IP_TREE_FIND_FOUND_UPPER_SET:
			return 1;
		default:
			return -1;
	}
}
コード例 #26
0
ファイル: avp_radius.c プロジェクト: asyn/openvims
static int load_uri_attrs(struct sip_msg* msg, unsigned long flags, fparam_t* fp)
{
    static char rad_msg[4096];
    struct sip_uri puri;
    str uri, did, scheme;
    UINT4 service;
    VALUE_PAIR* send, *received;

    send = NULL;
    received = NULL;

    if (get_str_fparam(&uri, msg, (fparam_t*)fp) != 0) {
	ERR("Unable to get URI\n");
	return -1;
    }

    if (parse_uri(uri.s, uri.len, &puri) < 0) {
	ERR("Error while parsing URI '%.*s'\n", uri.len, uri.s);
	return -1;
    }

    if (puri.host.len) {
	/* domain name is present */
	if (dm_get_did(&did, &puri.host) < 0) {
		DBG("Cannot lookup DID for domain %.*s, using default value\n", puri.host.len, ZSW(puri.host.s));
		did.s = DEFAULT_DID;
		did.len = sizeof(DEFAULT_DID) - 1;
	}
    } else {
	/* domain name is missing -- can be caused by tel: URI */
	DBG("There is no domain name, using default value\n");
	did.s = DEFAULT_DID;
	did.len = sizeof(DEFAULT_DID) - 1;
    }

    uri_type_to_str(puri.type, &scheme);
    service = vals[V_GET_URI_ATTRS].v;

    if (scheme.len) {
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_URI_SCHEME].v), 
			   scheme.s, scheme.len,
			   VENDOR(attrs[A_SER_URI_SCHEME].v))) {
	    ERR("Error while adding A_SER_URI_SCHEME\n");
	    goto error;
	}
    }

    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v), 
		       puri.user.s, puri.user.len,
		       VENDOR(attrs[A_USER_NAME].v))) {
	ERR("Error while adding A_USER_NAME\n");
	goto error;
    }

    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_DID].v), 
		       did.s, did.len,
		       VENDOR(attrs[A_SER_DID].v))) {
	ERR("Error while adding A_SER_DID\n");
	goto error;
    }
    
    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_SERVICE_TYPE].v), 
		       &vals[V_GET_URI_ATTRS].v, -1,
		       VENDOR(attrs[A_SER_SERVICE_TYPE].v))) {
	ERR("Error adding A_SERVICE_TYPE\n");
	goto error;
    }

    if (rc_auth(rh, 0, send, &received, rad_msg) != OK_RC) {
	DBG("load_uri_attrs: Failure\n");
	goto error;
    }

    DBG("load_uri_attrs: Success\n");
    rc_avpair_free(send);

    if (generate_avps(flags, received) < 0) {
	rc_avpair_free(received);
	goto error;
    }

    rc_avpair_free(received);
    return 1;

 error:
    if (send) rc_avpair_free(send);
    if (received) rc_avpair_free(send);
    return -1;
}
コード例 #27
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;
}
コード例 #28
0
ファイル: lookup.c プロジェクト: kiryu/kamailio
/*
 * Lookup contact in the database and rewrite Request-URI,
 * and filter them by aor
 */
int lookup2(struct sip_msg* msg, char* table, char* p2)
{
	urecord_t* r;
	str uid;
	ucontact_t* ptr;
	int res;
	unsigned int nat;
	str new_uri, aor;
	fparam_t* fp;

	nat = 0;
	fp = (fparam_t*)p2;
	
	if (get_str_fparam(&aor, msg, (fparam_t*)p2) != 0) {
	    ERR("Unable to get the AOR value\n");
	    return -1;
	}

	if (get_to_uid(&uid, msg) < 0) return -1;
	get_act_time();

	ul.lock_udomain((udomain_t*)table);
	res = ul.get_urecord((udomain_t*)table, &uid, &r);
	if (res < 0) {
		ERR("Error while querying usrloc\n");
		ul.unlock_udomain((udomain_t*)table);
		return -2;
	}
	
	if (res > 0) {
		DBG("'%.*s' Not found in usrloc\n", uid.len, ZSW(uid.s));
		ul.unlock_udomain((udomain_t*)table);
		return -3;
	}

	ptr = r->contacts;
	while (ptr && (!VALID_CONTACT(ptr, act_time) || !VALID_AOR(ptr, aor)))
	    ptr = ptr->next;
	
	if (ptr) {
	       if (ptr->received.s && ptr->received.len) {
			if (received_to_uri){
				if (add_received(&new_uri, &ptr->c, &ptr->received) < 0) {
					ERR("Out of memory\n");
					return -4;
				}
			/* replace the msg uri */
			if (msg->new_uri.s) pkg_free(msg->new_uri.s);
			msg->new_uri = new_uri;
			msg->parsed_uri_ok = 0;
			ruri_mark_new();
			goto skip_rewrite_uri;
			} else if (set_dst_uri(msg, &ptr->received) < 0) {
			        ul.unlock_udomain((udomain_t*)table);
				return -4;
			}
		}
		
		if (rewrite_uri(msg, &ptr->c) < 0) {
			ERR("Unable to rewrite Request-URI\n");
			ul.unlock_udomain((udomain_t*)table);
			return -4;
		}

		if (ptr->sock) {
			set_force_socket(msg, ptr->sock);
		}

skip_rewrite_uri:
		set_ruri_q(ptr->q);

		nat |= ptr->flags & FL_NAT;
		ptr = ptr->next;
	} else {
		     /* All contacts expired */
		ul.unlock_udomain((udomain_t*)table);
		return -5;
	}
	
	     /* Append branches if enabled */
	if (!append_branches) goto skip;

	while(ptr) {
		if (VALID_CONTACT(ptr, act_time) && VALID_AOR(ptr, aor)) {
			if (received_to_uri && ptr->received.s && ptr->received.len) {
				if (add_received(&new_uri, &ptr->c, &ptr->received) < 0) {
					ERR("branch: out of memory\n");
					goto cont; /* try to continue */
				}
				if (append_branch(msg, &new_uri, 0, 0, ptr->q, 0, 0) == -1) {
					ERR("Error while appending a branch\n");
					pkg_free(new_uri.s);
					if (ser_error == E_TOO_MANY_BRANCHES) goto skip;
					else goto cont; /* try to continue, maybe we have an
							                   oversized contact */
				}
				pkg_free(new_uri.s); /* append_branch doesn't free it */
			} else {
				if (append_branch(msg, &ptr->c, &ptr->received, 0 /* path */,
									 ptr->q, 0, ptr->sock) == -1) {
					ERR("Error while appending a branch\n");
					goto skip; /* Return OK here so the function succeeds */
				}
			}
			
			nat |= ptr->flags & FL_NAT; 
		} 
cont:
		ptr = ptr->next; 
	}
	
 skip:
	ul.unlock_udomain((udomain_t*)table);
	if (nat) setflag(msg, load_nat_flag);
	return 1;
}
コード例 #29
0
ファイル: authorize.c プロジェクト: mehulsbhatt/voip-foip
/*
 * Authorize digest credentials
 */
static inline int digest_authenticate(struct sip_msg* msg, fparam_t* realm,
									char* tname, hdr_types_t hftype)
{
	char ha1[256];
	int res;
	struct hdr_field* h;
	auth_body_t* cred;
	str domain, table;
	db1_res_t* result = NULL;
	int ret;

	cred = 0;
	ret = AUTH_ERROR;

	if(!tname) {
		LM_ERR("invalid table parameter\n");
		return AUTH_ERROR;
	}

	table.s = tname;
	table.len = strlen(tname);

	if (get_str_fparam(&domain, msg, realm) < 0) {
		LM_ERR("failed to get realm value\n");
		goto end;
	}

	if (domain.len==0)
	{
		LM_ERR("invalid realm parameter - empty value\n");
		goto end;
	}
	LM_DBG("realm value [%.*s]\n", domain.len, domain.s);

	ret = auth_api.pre_auth(msg, &domain, hftype, &h, NULL);
	switch(ret) {
		case ERROR:
		case BAD_CREDENTIALS:
			LM_DBG("error or bad credentials\n");
			ret = AUTH_ERROR;
			goto end;
		case CREATE_CHALLENGE:
			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_RESYNCHRONIZATION:
			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case NOT_AUTHENTICATED:
			LM_DBG("not authenticated\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_AUTHENTICATION:
			break;
		case AUTHENTICATED:
			ret = AUTH_OK;
			goto end;
	}

	cred = (auth_body_t*)h->parsed;

	res = get_ha1(&cred->digest.username, &domain, &table, ha1, &result);
	if (res < 0) {
		/* Error while accessing the database */
		ret = AUTH_ERROR;
		goto end;
	}
	if (res > 0) {
		/* Username not found in the database */
		ret = AUTH_USER_UNKNOWN;
		goto end;
	}

	/* Recalculate response, it must be same to authorize successfully */
	ret = auth_api.check_response(&(cred->digest),
				&msg->first_line.u.request.method, ha1);
	if(ret==AUTHENTICATED) {
		ret = AUTH_OK;
		switch(auth_api.post_auth(msg, h)) {
			case AUTHENTICATED:
				generate_avps(result);
				break;
			default:
				ret = AUTH_ERROR;
				break;
		}
	} else {
		if(ret==NOT_AUTHENTICATED)
			ret = AUTH_INVALID_PASSWORD;
		else
			ret = AUTH_ERROR;
	}

end:
	if(result)
		auth_dbf.free_result(auth_db_handle, result);
	return ret;
}
コード例 #30
0
ファイル: auth_mod.c プロジェクト: mehulsbhatt/voip-foip
/**
 * @brief do WWW-Digest authentication with password taken from cfg var
 */
static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
		char *p3, int hftype)
{
    int flags = 0;
    str realm  = {0, 0};
    str passwd = {0, 0};
	struct hdr_field* h;
	auth_body_t* cred;
	int ret;
    str hf = {0, 0};
    avp_value_t val;
	static char ha1[256];
	struct qp *qop = NULL;

	cred = 0;
	ret = AUTH_ERROR;

	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
		LM_ERR("failed to get realm value\n");
		goto error;
	}

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

	if (get_str_fparam(&passwd, msg, (fparam_t*)p2) < 0) {
		LM_ERR("failed to get passwd value\n");
		goto error;
	}

	if(passwd.len==0) {
		LM_ERR("invalid password value - empty content\n");
		goto error;
	}

	if (get_int_fparam(&flags, msg, (fparam_t*)p3) < 0) {
		LM_ERR("invalid flags value\n");
		goto error;
	}

	switch(pre_auth(msg, &realm, hftype, &h, NULL)) {
		case ERROR:
		case BAD_CREDENTIALS:
			LM_DBG("error or bad credentials\n");
			ret = AUTH_ERROR;
			goto end;
		case CREATE_CHALLENGE:
			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_RESYNCHRONIZATION:
			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
			ret = AUTH_ERROR;
			goto end;
		case NOT_AUTHENTICATED:
			LM_DBG("not authenticated\n");
			ret = AUTH_ERROR;
			goto end;
		case DO_AUTHENTICATION:
			break;
		case AUTHENTICATED:
			ret = AUTH_OK;
			goto end;
	}

	cred = (auth_body_t*)h->parsed;

	/* compute HA1 if needed */
	if ((flags&1)==0) {
		/* Plaintext password is stored in PV, calculate HA1 */
		calc_HA1(HA_MD5, &cred->digest.username.whole, &realm,
				&passwd, 0, 0, ha1);
		LM_DBG("HA1 string calculated: %s\n", ha1);
	} else {
		memcpy(ha1, passwd.s, passwd.len);
		ha1[passwd.len] = '\0';
	}

	/* Recalculate response, it must be same to authorize successfully */
	ret = auth_check_response(&(cred->digest),
				&msg->first_line.u.request.method, ha1);
	if(ret==AUTHENTICATED) {
		ret = AUTH_OK;
		switch(post_auth(msg, h)) {
			case AUTHENTICATED:
				break;
			default:
				ret = AUTH_ERROR;
				break;
		}
	} else {
		if(ret==NOT_AUTHENTICATED)
			ret = AUTH_INVALID_PASSWORD;
		else
			ret = AUTH_ERROR;
	}

end:
	if (ret < 0) {
		/* check if required to add challenge header as avp */
		if(!(flags&14))
			return ret;
		if(flags&8) {
			qop = &auth_qauthint;
		} else if(flags&4) {
			qop = &auth_qauth;
		}
		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
				&realm, NULL, NULL, qop, hftype, &hf) < 0) {
			ERR("Error while creating challenge\n");
			ret = AUTH_ERROR;
		} else {
			val.s = hf;
			if(add_avp(challenge_avpid.flags | AVP_VAL_STR,
							challenge_avpid.name, val) < 0) {
				LM_ERR("Error while creating attribute with challenge\n");
				ret = AUTH_ERROR;
			}
			pkg_free(hf.s);
		}
	}

error:
	return ret;

}