Exemple #1
0
/*
 * Check from Radius if URI user given as argument belongs to a local user.
 * If so, loads AVPs based on reply items returned from Radius.
 */
int radius_does_uri_user_exist(struct sip_msg* _m, str user)
{
    static char msg[4096];
    VALUE_PAIR *send, *received;
    uint32_t service;
    int res, extra_cnt, offset, i;
    
    send = received = 0;
    
    if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v,
		       user.s, user.len, 0)) {
	LM_ERR("in adding SA_USER_NAME\n");
	return -1;
    }
    
    service = uri_vals[UV_CALL_CHECK].v;
    if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(uri_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of group extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	rc_avpair_free(send);
	generate_avps(uri_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    return -1;
}
Exemple #2
0
/*
 * Check from Radius if URI, whose user and host parts are given as
 * arguments, exists.  If so, loads AVPs based on reply items returned
 * from Radius.  If use_sip_uri_host module parameter has non-zero value,
 * user is send in SA_USER_NAME attribute and host in SA_SIP_URI_HOST
 * attribute.  If is has zero value, user@host is send in SA_USER_NAME
 * attribute.
 */
int radius_does_uri_user_host_exist(struct sip_msg* _m, str user, str host)
{
    char* at, *user_host;
    VALUE_PAIR *send, *received;
    uint32_t service;
    static char msg[4096];
    int extra_cnt, offset, i, res;

    send = received = 0;
    user_host = 0;

    if (!use_sip_uri_host) {

	/* Send user@host in SA_USER_NAME attr */
	user_host = (char*)pkg_malloc(user.len + host.len + 2);
	if (!user_host) {
	    LM_ERR("no more pkg memory\n");
	    return -1;
	}
	at = user_host;
	memcpy(at, user.s, user.len);
	at += user.len;
	*at = '@';
	at++;
	memcpy(at , host.s, host.len);
	at += host.len;
	*at = '\0';
	if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v, user_host,
			   -1, 0)) {
	    LM_ERR("in adding SA_USER_NAME\n");
	    pkg_free(user_host);
	    return -1;
	}

    } else {

	/* Send user in SA_USER_NAME attribute and host in SA_SIP_URI_HOST
          attribute */
	if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v,
			   user.s, user.len, 0)) {
	    LM_ERR("adding User-Name failed\n");
	    return -1;
	}
	if (!rc_avpair_add(rh, &send, uri_attrs[SA_SIP_URI_HOST].v,
			   host.s, host.len, 0)) {
	    LM_ERR("adding SIP-URI-Host failed\n");
	    goto error;
	}
    }

    service = uri_vals[UV_CALL_CHECK].v;
    if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(uri_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of group extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	if (user_host) pkg_free(user_host);
	rc_avpair_free(send);
	generate_avps(uri_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	if (user_host) pkg_free(user_host);
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    if (user_host) pkg_free(user_host);
    return -1;
}
Exemple #3
0
/*
 * Loads from Radius callee's AVPs based on pvar argument.
 * Returns 1 if Radius request succeeded and -1 otherwise.
 */
int radius_load_callee_avps(struct sip_msg* _m, char* _callee, char* _s2)
{
    str user;
    VALUE_PAIR *send, *received;
    uint32_t service;
    static char msg[4096];
    int extra_cnt, offset, i, res;

    send = received = 0;

    if ((_callee == NULL) ||
	(fixup_get_svalue(_m, (gparam_p)_callee, &user) != 0)) {
	LM_ERR("invalid callee parameter");
	return -1;
    }

    if (!rc_avpair_add(rh, &send, callee_attrs[SA_USER_NAME].v,
		       user.s, user.len, 0)) {
	LM_ERR("in adding SA_USER_NAME\n");
	return -1;
    }

    service = callee_vals[EV_SIP_CALLEE_AVPS].v;
    if (!rc_avpair_add(rh, &send, callee_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(callee_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of callee extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(callee_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(callee_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	rc_avpair_free(send);
	generate_avps(callee_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    return -1;
}
Exemple #4
0
/*
 * Check from Radius if a user belongs to a group. User-Name is given in
 * first string argment that may contain pseudo variables.  SIP-Group is
 * given in second string variable that may not contain pseudo variables.
 * Service-Type is Group-Check.
 */
int radius_is_user_in(struct sip_msg* _m, char* _user, char* _group)
{
    str user, *group;
    VALUE_PAIR *send, *received;
    uint32_t service;
    static char msg[4096];
    int extra_cnt, offset, i, res;

    send = received = 0;

    if ((_user == NULL) ||
	(fixup_get_svalue(_m, (gparam_p)_user, &user) != 0)) {
	LM_ERR("invalid user parameter");
	return -1;
    }

    if (!rc_avpair_add(rh, &send, group_attrs[SA_USER_NAME].v,
		       user.s, user.len, 0)) {
	LM_ERR("in adding SA_USER_NAME\n");
	return -1;
    }

    group = (str*)_group;
    if ((group == NULL) || (group->len == 0)) {
	LM_ERR("invalid group parameter");
	goto error;
    }
    if (!rc_avpair_add(rh, &send, group_attrs[SA_SIP_GROUP].v,
		       group->s, group->len, 0)) {
	LM_ERR("in adding SA_SIP_GROUP\n");
	goto error;
    }

    service = group_vals[GV_GROUP_CHECK].v;
    if (!rc_avpair_add(rh, &send, group_attrs[SA_SERVICE_TYPE].v,
		       &service, -1, 0)) {
	LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
	goto error;
    }

    /* Add extra attributes */
    extra_cnt = extra2strar(group_extra, _m, val_arr);
    if (extra_cnt == -1) {
	LM_ERR("in getting values of group extra attributes\n");
	goto error;
    }
    offset = SA_STATIC_MAX;
    for (i = 0; i < extra_cnt; i++) {
	if (val_arr[i].len == -1) {
	    /* Add integer attribute */
	    ADD_EXTRA_AVPAIR(group_attrs, offset+i,
			     &(val_arr[i].s), val_arr[i].len );
	} else {
	    /* Add string attribute */
	    ADD_EXTRA_AVPAIR(group_attrs, offset+i,
			     val_arr[i].s, val_arr[i].len );
	}
    }

    if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
	LM_DBG("success\n");
	rc_avpair_free(send);
	generate_avps(group_attrs, received);
	rc_avpair_free(received);
	return 1;
    } else {
	rc_avpair_free(send);
	rc_avpair_free(received);
#ifdef REJECT_RC
	if (res == REJECT_RC) {
	    LM_DBG("rejected\n");
	    return -1;
	} else {
	    LM_ERR("failure\n");
	    return -2;
	}
#else
	LM_DBG("failure\n");
	return -1;
#endif
    }

 error:
    rc_avpair_free(send);
    return -1;
}
Exemple #5
0
/*
 * This function creates and submits radius authentication request as per
 * draft-sterman-aaa-sip-00.txt.  In addition, _user parameter is included
 * in the request as value of a SER specific attribute type SIP-URI-User,
 * which can be be used as a check item in the request.  Service type of
 * the request is Authenticate-Only.
 */
int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user) 
{
	static char msg[4096];
	VALUE_PAIR *send, *received;
	uint32_t service;
	str method, user, user_name;
	str *ruri;
	int extra_cnt, offset, i;
		
	send = received = 0;

	if (!(_cred && _method && _user)) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	method = *_method;
	user = *_user;
	
	/*
	 * Add all the user digest parameters according to the qop defined.
	 * Most devices tested only offer support for the simplest digest.
	 */
	if (_cred->username.domain.len || !append_realm_to_username) {
		if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) {
			LM_ERR("unable to add User-Name attribute\n");
			goto err;
		}
	} else {
		user_name.len = _cred->username.user.len + _cred->realm.len + 1;
		user_name.s = pkg_malloc(user_name.len);
		if (!user_name.s) {
			LM_ERR("no pkg memory left\n");
			return -3;
		}
		memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len);
		user_name.s[_cred->username.whole.len] = '@';
		memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s,
			_cred->realm.len);
		if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s,
		user_name.len, 0)) {
			LM_ERR("unable to add User-Name attribute\n");
			pkg_free(user_name.s);
			goto err;
		}
		pkg_free(user_name.s);
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_USER_NAME].v, 
	_cred->username.whole.s, _cred->username.whole.len, 0)) {
		LM_ERR("unable to add Digest-User-Name attribute\n");
		goto err;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s,
	_cred->realm.len, 0)) {
		LM_ERR("unable to add Digest-Realm attribute\n");
		goto err;
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s,
	_cred->nonce.len, 0)) {
		LM_ERR("unable to add Digest-Nonce attribute\n");
		goto err;
	}

	if (use_ruri_flag < 0 || isflagset(_msg, use_ruri_flag) != 1) {
		ruri = &_cred->uri;
	} else {
		ruri = GET_RURI(_msg);
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_URI].v, ruri->s,
	ruri->len, 0)) {
		LM_ERR("unable to add Digest-URI attribute\n");
		goto err;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_METHOD].v, method.s,
	method.len, 0)) {
		LM_ERR("unable to add Digest-Method attribute\n");
		goto err;
	}
	
	/* 
	 * Add the additional authentication fields according to the QOP.
	 */
	if (_cred->qop.qop_parsed == QOP_AUTH) {
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth", 4, 0)) {
			LM_ERR("unable to add Digest-QOP attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, 
		_cred->nc.s, _cred->nc.len, 0)) {
			LM_ERR("unable to add Digest-CNonce-Count attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, 
		_cred->cnonce.s, _cred->cnonce.len, 0)) {
			LM_ERR("unable to add Digest-CNonce attribute\n");
			goto err;
		}
	} else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v,
		"auth-int", 8, 0)) {
			LM_ERR("unable to add Digest-QOP attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v,
		_cred->nc.s, _cred->nc.len, 0)) {
			LM_ERR("unable to add Digest-Nonce-Count attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v,
		_cred->cnonce.s, _cred->cnonce.len, 0)) {
			LM_ERR("unable to add Digest-CNonce attribute\n");
			goto err;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v, 
		_cred->opaque.s, _cred->opaque.len, 0)) {
			LM_ERR("unable to add Digest-Body-Digest attribute\n");
			goto err;
		}
		
	} else  {
		/* send nothing for qop == "" */
	}

	/* Add the response... What to calculate against... */
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_RESPONSE].v, 
	_cred->response.s, _cred->response.len, 0)) {
		LM_ERR("unable to add Digest-Response attribute\n");
		goto err;
	}

	/* Indicate the service type, Authenticate only in our case */
	service = vals[V_SIP_SESSION].v;
	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LM_ERR("unable to add Service-Type attribute\n");
		goto err;
	}

	/* Add SIP URI as a check item */
	if (!rc_avpair_add(rh,&send,attrs[A_SIP_URI_USER].v,user.s,user.len,0)) {
		LM_ERR("unable to add Sip-URI-User attribute\n");
		goto err;
	}

	if (attrs[A_CISCO_AVPAIR].n != NULL) {
		if (add_cisco_vsa(&send, _msg)) {
			goto err;
		}
	}

	/* Add extra attributes */
	extra_cnt = extra2strar(auth_extra, _msg, val_arr);
	if (extra_cnt == -1) {
	    LM_ERR("in getting values of extra attributes\n");
	    goto err;
	}
	offset = A_MAX;
	for (i = 0; i < extra_cnt; i++) {
	    if (val_arr[i].len == -1) {
		/* Add integer attribute */
		ADD_EXTRA_AVPAIR(attrs, offset+i,
				 &(val_arr[i].s), val_arr[i].len );
	    } else {
		/* Add string attribute */
		ADD_EXTRA_AVPAIR(attrs, offset+i,
				 val_arr[i].s, val_arr[i].len );
	    }
	}

	/* Send request */
	if ((i = rc_auth(rh, SIP_PORT, send, &received, msg)) == OK_RC) {
		LM_DBG("Success\n");
		rc_avpair_free(send);
		send = 0;

		generate_avps(received);

		rc_avpair_free(received);
		return 1;
	} else {
#ifdef REJECT_RC
                if (i == REJECT_RC) {
                        LM_DBG("Failure\n");
                        goto err;
                }
#endif 
		LM_ERR("authorization failed. RC auth returned %d\n", i);
	}

 err:
	if (send) rc_avpair_free(send);
	if (received) rc_avpair_free(received);
	return -1;
}