Пример #1
0
int w_has_credentials(sip_msg_t *msg, char* realm, char* s2)
{
	str srealm  = {0, 0};
	hdr_field_t *hdr = NULL;
	int ret;

	if (fixup_get_svalue(msg, (gparam_t*)realm, &srealm) < 0) {
		LM_ERR("failed to get realm value\n");
		return -1;
	}

	ret = find_credentials(msg, &srealm, HDR_PROXYAUTH_T, &hdr);
	if(ret==0) {
		LM_DBG("found www credentials with realm [%.*s]\n", srealm.len, srealm.s);
		return 1;
	}
	ret = find_credentials(msg, &srealm, HDR_AUTHORIZATION_T, &hdr);
	if(ret==0) {
		LM_DBG("found proxy credentials with realm [%.*s]\n", srealm.len, srealm.s);
		return 1;
	}

	LM_DBG("no credentials with realm [%.*s]\n", srealm.len, srealm.s);
	return -1;
}
Пример #2
0
/**
 * Returns the Private Identity extracted from the Authorization header.
 * If none found there takes the SIP URI in To without the "sip:" prefix
 * \todo - remove the fallback case to the To header
 * @param msg - the SIP message
 * @param realm - the realm to match in an Authorization header
 * @returns the str containing the private id, no mem dup
 */
str cscf_get_private_identity(struct sip_msg *msg, str realm) {
	str pi = {0, 0};
	struct hdr_field* h = 0;
	int ret, i, res;

	if ((parse_headers(msg, HDR_AUTHORIZATION_F, 0) != 0) && (parse_headers(msg, HDR_PROXYAUTH_F, 0) != 0)) {
		return pi;
	}

	h = msg->authorization;
	if (!msg->authorization) {
		goto fallback;
	}
		
	if (realm.len && realm.s) {
		ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
		if (ret < 0) {
			ret = find_credentials(msg, &realm, HDR_PROXYAUTH_F, &h);
			if (ret < 0) {
				goto fallback;
			} else {
				if (ret >0) {
					goto fallback;
				}
				h = msg->proxy_auth;
			}
		} else {
			if (ret > 0) {
				goto fallback;
			}
		}
	}
	
	if (!h)
		goto fallback;

	res = parse_credentials(h);
	if (res != 0) {
		LOG(L_ERR, "Error while parsing credentials\n");
		return pi;
	}

	if (h) pi = ((auth_body_t*) h->parsed)->digest.username.whole;

	goto done;

fallback:
	pi = cscf_get_public_identity(msg);
	if (pi.len > 4 && strncasecmp(pi.s, "sip:", 4) == 0) {
		pi.s += 4;
		pi.len -= 4;
	}
	for (i = 0; i < pi.len; i++)
		if (pi.s[i] == ';') {
			pi.len = i;
			break;
		}
done:
	return pi;
}
Пример #3
0
/**
 * Looks for the nonce parameter in the Authorization header and returns its value.
 * @param msg - the SIP message
 * @param realm - realm to match the right Authorization header
 * @returns the nonce or an empty string if none found
 */
str ims_get_nonce(struct sip_msg *msg, str realm)
{
	struct hdr_field* h=0;
	int ret;
	str nonce={0,0};

	if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
		LM_ERR("Error parsing until header Authorization: \n");
		return nonce;
	}

	if (!msg->authorization){
		LM_ERR("Message does not contain Authorization header.\n");
		return nonce;
	}

	ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
	if (ret < 0) {
		LM_ERR("Error while looking for credentials.\n");
		return nonce;
	} else 
		if (ret > 0) {
			LM_ERR("No credentials for this realm found.\n");
			return nonce;
		}
	
	if (h&&h->parsed) {
		nonce = ((auth_body_t*)h->parsed)->digest.nonce;
	}
	
	return nonce;	
}
Пример #4
0
/*
 * Purpose of this function is to find credentials with given realm,
 * do sanity check, validate credential correctness and determine if
 * we should really authenticate (there must be no authentication for
 * ACK and CANCEL
 * @param hdr output param where the Authorize headerfield will be returned.
 * @param check_hdr  pointer to the function checking Authorization header field
 */
auth_result_t pre_auth(struct sip_msg* msg, str* realm, hdr_types_t hftype,
						struct hdr_field**  hdr,
						check_auth_hdr_t check_auth_hdr)
{
	int ret;
	auth_body_t* c;
	check_auth_hdr_t check_hf;
	auth_result_t    auth_rv;

	     /* ACK and CANCEL must be always authenticated, there is
	      * no way how to challenge ACK and CANCEL cannot be
	      * challenged because it must have the same CSeq as
	      * the request to be canceled.
	      * PRACK is also not authenticated
	      */

	if (msg->REQ_METHOD & (METHOD_ACK|METHOD_CANCEL|METHOD_PRACK))
		return AUTHENTICATED;

	     /* Try to find credentials with corresponding realm
	      * in the message, parse them and return pointer to
	      * parsed structure
	      */
	strip_realm(realm);
	ret = find_credentials(msg, realm, hftype, hdr);
	if (ret < 0) {
		LOG(L_ERR, "auth:pre_auth: Error while looking for credentials\n");
		return ERROR;
	} else if (ret > 0) {
		DBG("auth:pre_auth: Credentials with realm '%.*s' not found\n",
				realm->len, ZSW(realm->s));
		return NO_CREDENTIALS;
	}

	     /* Pointer to the parsed credentials */
	c = (auth_body_t*)((*hdr)->parsed);

	    /* digest headers are in c->digest */
	DBG("auth: digest-algo: %.*s parsed value: %d\n",
			c->digest.alg.alg_str.len, c->digest.alg.alg_str.s,
			c->digest.alg.alg_parsed);

	if (mark_authorized_cred(msg, *hdr) < 0) {
		LOG(L_ERR, "auth:pre_auth: Error while marking parsed credentials\n");
		return ERROR;
	}

	    /* check authorization header field's validity */
	if (check_auth_hdr == NULL) {
		check_hf = auth_check_hdr_md5;
	} else {	/* use check function of external authentication module */
		check_hf = check_auth_hdr;
	}
	/* use the right function */
	if (!check_hf(msg, c, &auth_rv)) {
		return auth_rv;
	}
	
	return DO_AUTHENTICATION;
}
Пример #5
0
int get_credentials(struct sip_msg* msg, select_t* s, struct hdr_field** hdr)
{
	int ret;
	str realm;
	hdr_types_t hdr_type;

	*hdr = NULL;

	if (!msg) {
		/* fix-up call check domain for fparam conversion */
		void * ptr;
		char chr;
		ptr=(void *)(s->params[1].v.s.s);
		chr=s->params[1].v.s.s[s->params[1].v.s.len];
		s->params[1].v.s.s[s->params[1].v.s.len]=0;
		ret=fixup_var_str_12(&ptr,0);
		if (ret>=0) {
			s->params[1].v.s.s[s->params[1].v.s.len]=chr;
			s->params[1].v.p=ptr;
			s->params[1].type=SEL_PARAM_PTR;
		}
		return ret;
	}
	

	/* Try to find credentials with corresponding realm
	 * in the message, parse them and return pointer to
	 * parsed structure
	 */
	if (s->params[1].type==SEL_PARAM_PTR) {
		if (get_str_fparam(&realm, msg, s->params[1].v.p)<0)
			return -1;
	} else {
		realm = s->params[1].v.s;
	}

	switch (s->params[0].v.i) {
	case SEL_AUTH_WWW:
		hdr_type = HDR_AUTHORIZATION_T;
		break;

	case SEL_AUTH_PROXY:
		hdr_type = HDR_PROXYAUTH_T;
		break;

	default:
		BUG("Unexpected parameter value \"%d\"\n", s->params[0].v.i);
		return -1;
	}

	ret = find_credentials(msg, &realm, hdr_type, hdr);
	return ret;
}
Пример #6
0
auth_diam_result_t diam_pre_auth(struct sip_msg* _m, str* _realm, int _hftype, 
													struct hdr_field** _h)
{
	int ret;
	struct sip_uri uri;
	str realm;

	if ((_m->REQ_METHOD == METHOD_ACK) ||  (_m->REQ_METHOD == METHOD_CANCEL))
		return AUTHORIZED;

	/* if no realm supplied, find out now */
	if (_realm==0 || _realm->len == 0) 
	{
		if (get_realm(_m, _hftype, &uri) < 0) 
		{
			LM_ERR("failed to extract realm\n");
			if (send_resp(_m, 400, &dia_400_err, 0, 0) == -1) 
			{
				LM_ERR("failed to send 400 reply\n");
			}
			return ERROR;
		}
		realm = uri.host;
	} else {
		realm = *_realm;
	}

	ret = find_credentials(_m, &realm, _hftype, _h);
	if (ret < 0) 
	{
		LM_ERR("credentials not found\n");
		if (send_resp(_m, (ret == -2) ? 500 : 400, 
			      (ret == -2) ? &dia_500_err : &dia_400_err, 0, 0) == -1) 
		{
			LM_ERR("failed to send 400 reply\n");
		}
		return ERROR;
	} 
	else 
		if (ret > 0) 
		{
			LM_ERR("credentials with given realm not found\n");
			return NO_CREDENTIALS;
		}
	

	return DO_AUTHORIZATION;
}
Пример #7
0
auth_result_t pre_auth(struct sip_msg* _m, str* _realm, int _hftype, struct hdr_field** _h)
{
	int ret;
	struct sip_uri uri;

	if ((_m->REQ_METHOD == METHOD_ACK) ||  (_m->REQ_METHOD == METHOD_CANCEL))
		return AUTHORIZED;

	/* if no realm supplied, find out now */
	if (_realm==0 || _realm->len == 0) 
	{
		if (get_realm(_m, _hftype, &uri) < 0) 
		{
			LOG(L_ERR, M_NAME":pre_auth(): Error while extracting realm\n");
			if (send_resp(_m, 400, MESSAGE_400, 0, 0) == -1) 
			{
				LOG(L_ERR, M_NAME":pre_auth(): Error while sending 400 reply\n");
			}
			return ERROR;
		}
		
		*_realm = uri.host;
	}

	ret = find_credentials(_m, _realm, _hftype, _h);
	if (ret < 0) 
	{
		LOG(L_ERR, M_NAME":pre_auth(): Error while looking for credentials\n");
		if (send_resp(_m, (ret == -2) ? 500 : 400, 
			      (ret == -2) ? MESSAGE_500 : MESSAGE_400, 0, 0) == -1) 
		{
			LOG(L_ERR, M_NAME":pre_auth(): Error while sending 400 reply\n");
		}
		return ERROR;
	} 
	else 
		if (ret > 0) 
		{
			LOG(L_ERR, M_NAME":pre_auth(): Credentials with given realm not "
				"found\n");
			return NO_CREDENTIALS;
		}
	

	return DO_AUTHORIZATION;
}
Пример #8
0
/**
 * Looks for the auts parameter in the Authorization header and returns its value.
 * @param msg - the SIP message
 * @param realm - realm to match the right Authorization header
 * @returns the auts value or an empty string if not found
 */
str ims_get_auts(struct sip_msg *msg, str realm, int is_proxy_auth)
{
	str name={"auts=\"",6};
	struct hdr_field* h=0;
	int i,ret;
	str auts={0,0};

	if (parse_headers(msg, is_proxy_auth ? HDR_PROXYAUTH_F : HDR_AUTHORIZATION_F,0)!=0) {
		LM_ERR("Error parsing until header Authorization: \n");
		return auts;
	}

	if ((!is_proxy_auth && !msg->authorization)
			|| (is_proxy_auth && !msg->proxy_auth)){
		LM_ERR("Message does not contain Authorization nor Proxy-Authorization header.\n");
		return auts;
	}

	ret = find_credentials(msg, &realm, is_proxy_auth ? HDR_PROXYAUTH_F : HDR_AUTHORIZATION_F, &h);
	if (ret < 0) {
		LM_ERR("Error while looking for credentials.\n");
		return auts;
	} else 
		if (ret > 0) {
			LM_ERR("No credentials for this realm found.\n");
			return auts;
		}
	
	if (h) {
		for(i=0;i<h->body.len-name.len;i++)
			if (strncasecmp(h->body.s+i,name.s,name.len)==0){
				auts.s = h->body.s+i+name.len;
				while(i+auts.len<h->body.len && auts.s[auts.len]!='\"')
					auts.len++;
			}
	}
	
	return auts;	
}
Пример #9
0
/**
 * Returns the Private Identity extracted from the Authorization header.
 * If none found there takes the SIP URI in To without the "sip:" prefix
 * \todo - remove the fallback case to the To header
 * @param msg - the SIP message
 * @param realm - the realm to match in an Authorization header
 * @param is_proxy_auth 0 if the header is Authorization, anything else for Proxy-Authorization
 * @returns the str containing the private id, no mem dup
 */
str get_private_identity(struct sip_msg *msg, str realm, int is_proxy_auth)
{
	str pi={0,0};
	struct hdr_field* h=0;
	int ret,i;

	if (parse_headers(msg, is_proxy_auth ? HDR_PROXYAUTH_F : HDR_AUTHORIZATION_F,0)!=0) {
		return pi;
	}

	if (!(is_proxy_auth ? msg->proxy_auth : msg->authorization)){
		goto fallback;
	}

	ret = find_credentials(msg, &realm, is_proxy_auth ? HDR_PROXYAUTH_F : HDR_AUTHORIZATION_F, &h);
	if (ret < 0) {
		goto fallback;
	} else 
		if (ret > 0) {
			goto fallback;
		}
	
	if (h) pi=((auth_body_t*)h->parsed)->digest.username.whole;

	goto done;
		
fallback:
	pi = get_public_identity(msg);
	if (pi.len>4&&strncasecmp(pi.s,"sip:",4)==0) {pi.s+=4;pi.len-=4;}
	for(i=0;i<pi.len;i++)
		if (pi.s[i]==';') {
			pi.len=i;
			break;
		}
done:	
	return pi;	
}
Пример #10
0
static struct hdr_field* get_credentials(struct sip_msg* msg, select_t* s)
{
	int ret;
	struct hdr_field* hdr;
	str realm;
	hdr_types_t hdr_type;

	     /* Try to find credentials with corresponding realm
	      * in the message, parse them and return pointer to
	      * parsed structure
	      */
	realm = s->params[1].v.s;

	switch (s->params[0].v.i) {
	case SEL_AUTH_WWW:
		hdr_type = HDR_AUTHORIZATION_T;
		break;

	case SEL_AUTH_PROXY:
		hdr_type = HDR_PROXYAUTH_T;
		break;

	default:
		BUG("Unexpected parameter value \"%d\"\n", s->params[0].v.i);
		return 0;
	}

	ret = find_credentials(msg, &realm, hdr_type, &hdr);
	if (ret < 0) {
		ERR("Error while looking for credentials\n");
		return 0;
	} else if (ret > 0) {
		return 0;
	}

	return hdr;
}
Пример #11
0
/*
 * Purpose of this function is to find credentials with given realm,
 * do sanity check, validate credential correctness and determine if
 * we should really authenticate (there must be no authentication for
 * ACK and CANCEL
 */
auth_result_t pre_auth(struct sip_msg* _m, str* _realm, int _hftype, struct hdr_field** _h)
{
	int ret;
	auth_body_t* c;
	struct sip_uri uri;

	     /* ACK and CANCEL must be always authorized, there is
	      * no way how to challenge ACK and CANCEL cannot be
	      * challenged because it must have the same CSeq as
	      * the request to be cancelled
	      */

	if ((_m->REQ_METHOD == METHOD_ACK) ||  (_m->REQ_METHOD == METHOD_CANCEL)) return AUTHORIZED;

	if (_realm->len == 0) {
		if (get_realm(_m, _hftype, &uri) < 0) {
			LOG(L_ERR, "pre_auth(): Error while extracting realm\n");
			if (send_resp(_m, 400, MESSAGE_400, 0, 0) == -1) {
				LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n");
			}
			return ERROR;
		}
		
		*_realm = uri.host;
		strip_realm(_realm);
	}

	     /* Try to find credentials with corresponding realm
	      * in the message, parse them and return pointer to
	      * parsed structure
	      */
	ret = find_credentials(_m, _realm, _hftype, _h);
	if (ret < 0) {
		LOG(L_ERR, "pre_auth(): Error while looking for credentials\n");
		if (send_resp(_m, (ret == -2) ? 500 : 400, 
			      (ret == -2) ? MESSAGE_500 : MESSAGE_400, 0, 0) == -1) {
			LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n");
		}
		return ERROR;
	} else if (ret > 0) {
		DBG("pre_auth(): Credentials with given realm not found\n");
		return NOT_AUTHORIZED;
	}

	     /* Pointer to the parsed credentials */
	c = (auth_body_t*)((*_h)->parsed);

	     /* Check credentials correctness here */
	if (check_dig_cred(&(c->digest)) != E_DIG_OK) {
		LOG(L_ERR, "pre_auth(): Credentials received are not filled properly\n");
		if (send_resp(_m, 400, MESSAGE_400, 0, 0) == -1) {
			LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n");
		}
		return ERROR;
	}

	if (check_nonce(&c->digest.nonce, &secret) != 0) {
		DBG("pre_auth(): Invalid nonce value received\n");
		return NOT_AUTHORIZED;
	}

	return DO_AUTHORIZATION;
}
Пример #12
0
/*
 * Purpose of this function is to find credentials with given realm,
 * do sanity check, validate credential correctness and determine if
 * we should really authenticate (there must be no authentication for
 * ACK and CANCEL
 */
auth_result_t pre_auth(struct sip_msg* _m, str* _realm, hdr_types_t _hftype,
													struct hdr_field** _h)
{
	int ret;
	auth_body_t* c;
	struct sip_uri *uri;

	/* ACK and CANCEL must be always authorized, there is
	 * no way how to challenge ACK and CANCEL cannot be
	 * challenged because it must have the same CSeq as
	 * the request to be canceled
	 */

	if ((_m->REQ_METHOD == METHOD_ACK) ||  (_m->REQ_METHOD == METHOD_CANCEL))
		return AUTHORIZED;

	if (_realm->len == 0) {
		if (get_realm(_m, _hftype, &uri) < 0) {
			LM_ERR("failed to extract realm\n");
			if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) {
				LM_ERR("failed to send 400 reply\n");
			}
			return ERROR;
		}
		
		*_realm = uri->host;
		strip_realm(_realm);
	}

	/* Try to find credentials with corresponding realm
	 * in the message, parse them and return pointer to
	 * parsed structure
	 */
	ret = find_credentials(_m, _realm, _hftype, _h);
	if (ret < 0) {
		LM_ERR("failed to find credentials\n");
		if (send_resp(_m, (ret == -2) ? 500 : 400, 
			      (ret == -2) ? &auth_500_err : &auth_400_err, 0, 0) == -1) {
			LM_ERR("failed to send 400 reply\n");
		}
		return ERROR;
	} else if (ret > 0) {
		LM_DBG("credentials with given realm not found\n");
		return NO_CREDENTIALS;
	}

	/* Pointer to the parsed credentials */
	c = (auth_body_t*)((*_h)->parsed);

	/* Check credentials correctness here */
	if (check_dig_cred(&(c->digest)) != E_DIG_OK) {
		LM_DBG("received credentials are not filled properly\n");
		if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) {
			LM_ERR("failed to send 400 reply\n");
		}
		return ERROR;
	}

	if (mark_authorized_cred(_m, *_h) < 0) {
		LM_ERR("failed to mark parsed credentials\n");
		if (send_resp(_m, 500, &auth_400_err, 0, 0) == -1) {
			LM_ERR("failed to send 400 reply\n");
		}
		return ERROR;
	}

	if (is_nonce_stale(&c->digest.nonce)) {
		LM_DBG("stale nonce value received\n");
		c->stale = 1;
		return STALE_NONCE;
	}

	if (check_nonce(&c->digest.nonce, &secret) != 0) {
		LM_DBG("invalid nonce value received\n");
		c->stale = 1;
		return STALE_NONCE;
	}

	return DO_AUTHORIZATION;
}