Esempio n. 1
0
int rc_acct_proxy(VALUE_PAIR *send)
{
	SEND_DATA       data;
	int		result;
	char		msg[4096];
	int		i;
	SERVER		*acctserver = rc_conf_srv("authserver");
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = send;
	data.receive_pairs = NULL;

	result = ERROR_RC;
	for(i=0; (i<acctserver->max) && (result != OK_RC) && (result != BADRESP_RC)
		; i++)
	{
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i],
			    acctserver->port[i], timeout, retries);

		result = rc_send_server (&data, msg, NULL);
	}

	rc_avpair_free(data.receive_pairs);

	return result;
}
Esempio n. 2
0
int rc_acct_using_server(SERVER *acctserver,
			 UINT4 client_port,
			 VALUE_PAIR *send)
{
	SEND_DATA       data;
	VALUE_PAIR	*adt_vp;
	int		result;
	time_t		start_time, dtime;
	char		msg[4096];
	int		i;
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = send;
	data.receive_pairs = NULL;

	/*
	 * Fill in NAS-IP-Address or NAS-Identifier
	 */

	if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC)
	    return (ERROR_RC);

	/*
	 * Fill in NAS-Port
	 */

	if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL)
		return (ERROR_RC);

	/*
	 * Fill in Acct-Delay-Time
	 */

	dtime = 0;
	if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, VENDOR_NONE)) == NULL)
		return (ERROR_RC);

	start_time = time(NULL);
	result = ERROR_RC;
	for(i=0; (i<acctserver->max) && (result != OK_RC) && (result != BADRESP_RC)
		; i++)
	{
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i],
			    acctserver->port[i], timeout, retries);

		dtime = time(NULL) - start_time;
		rc_avpair_assign(adt_vp, &dtime, 0);

		result = rc_send_server (&data, msg, NULL);
	}

	rc_avpair_free(data.receive_pairs);

	return result;
}
Esempio n. 3
0
int send_acct_func_async(struct sip_msg* msg, async_resume_module **resume_f,
		void **resume_param, str *s)
{
	int i, index = -1, res;
	VALUE_PAIR *send = NULL;
	SEND_CONTEXT *ctx = 0;
	struct rad_ctx *rctx;


	if (!rh) {
		if (init_radius_handle()) {
			LM_ERR("invalid radius handle\n");
			return -1;
		}
	}

	for (i = 0; i < set_size; i++) {
		if (sets[i]->set_name.len == s->len &&
				!strncmp(sets[i]->set_name.s, s->s, s->len))
				index = i;
	}

	if (index == -1) {
		LM_ERR("set not found\n");
		return -1;
	}

	if (make_send_message(msg, index, &send) < 0) {
		LM_ERR("make message failed\n");
		return -1;
	}

	res = rc_acct_async(rh, SIP_PORT, send, &ctx);
	if (res == OK_RC) {
		LM_DBG("radius accounting message sent\n");

		rctx = pkg_malloc(sizeof(struct rad_ctx));
		if (rctx == NULL) {
			LM_ERR("no pkg mem\n");
			if (send) rc_avpair_free(send);
			return -1;
		}

		rctx->send	 = send;
		rctx->ctx	 = ctx;

		*resume_param = rctx;
		*resume_f	  = resume_send_acct;
		async_status  = ctx->sockfd;

		return 1;
	}

	if (send) rc_avpair_free(send);
	return -1;

}
Esempio n. 4
0
static int load_user_attrs(struct sip_msg* msg, unsigned long flags, fparam_t* fp)
{
    static char rad_msg[4096];
    str uid;
    UINT4 service;
    VALUE_PAIR* send, *received;

    send = NULL;
    received = NULL;

    if (get_str_fparam(&uid, msg, (fparam_t*)fp) < 0) {
	ERR("Unable to get UID\n");
	return -1;
    }

    service = vals[V_GET_USER_ATTRS].v;

    if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v), 
		       uid.s, uid.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_SERVICE_TYPE].v), 
		       &vals[V_GET_USER_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_user_attrs: Failure\n");
	goto error;
    }

    DBG("load_user_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;
}
Esempio n. 5
0
void free_radius_auth_value_pair(VALUE_PAIR *send, VALUE_PAIR *received, rc_handle *rh)
{
	if (send)
		rc_avpair_free(send);

	if (received)
		rc_avpair_free(received);
		
	if (rh)
		rc_destroy(rh);
	rh = NULL;
}
Esempio n. 6
0
int process(void *rh, VALUE_PAIR * send, int acct, int nas_port)
{
    VALUE_PAIR *received;
    char msg[PW_MAX_MSG_SIZE];
    char buf[BUF_LEN];
    int i, fd;

    fd = rc_tls_fd(rh);
    if (fd >= 0) {
        dup(fd);
        close(fd);
    }

    received = NULL;
    if (acct == 0) {
        i = rc_auth(rh, nas_port, send, &received, msg);
        if (i != OK_RC) {
            fprintf(stderr, "tls-restart: error sending 1 (ok)\n");
        }

        i = rc_auth(rh, nas_port, send, &received, msg);
        if (i != OK_RC) {
            fprintf(stderr, "tls-restart: error sending 2\n");
            exit(2);
        }
        if (received != NULL) {
            printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN));
            rc_avpair_free(received);
        }
    } else {
        i = rc_acct(rh, nas_port, send);
    }

    return (i == OK_RC) ? 0 : 1;
}
Esempio n. 7
0
static void radius_log(struct ast_event *event)
{
	int result = ERROR_RC;
	VALUE_PAIR *send = NULL;
	struct ast_cel_event_record record = {
		.version = AST_CEL_EVENT_RECORD_VERSION,
	};

	if (ast_cel_fill_record(event, &record)) {
		return;
	}

	if (build_radius_record(&send, &record)) {
		ast_debug(1, "Unable to create RADIUS record. CEL not recorded!\n");
		goto return_cleanup;
	}

	result = rc_acct(rh, 0, send);
	if (result != OK_RC) {
		ast_log(LOG_ERROR, "Failed to record Radius CEL record!\n");
	}

return_cleanup:
	if (send) {
		rc_avpair_free(send);
	}
}
Esempio n. 8
0
int rc_check(char *host, unsigned short port, char *msg)
{
	SEND_DATA       data;
	int		result;
	UINT4		service_type;
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = data.receive_pairs = NULL;

	/*
	 * Fill in NAS-IP-Address or NAS-Identifier,
         * although it isn't neccessary
	 */

	if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC)
	    return (ERROR_RC);

	/*
	 * Fill in Service-Type
	 */

	service_type = PW_ADMINISTRATIVE;
	rc_avpair_add(&(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, VENDOR_NONE);

	rc_buildreq(&data, PW_STATUS_SERVER, host, port, timeout, retries);
	result = rc_send_server (&data, msg, NULL);

	rc_avpair_free(data.receive_pairs);

	return result;
}
Esempio n. 9
0
/** Asks the server hostname on the specified port for a status message
 *
 * @param rh a handle to parsed configuration.
 * @param host the name of the server.
 * @param secret the secret used by the server.
 * @param port the server's port number.
 * @param msg must be an array of PW_MAX_MSG_SIZE or NULL; will contain the concatenation of any
 *	PW_REPLY_MESSAGE received.
 * @return OK_RC (0) on success, negative on failure as return value.
 */
int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg)
{
	SEND_DATA       data;
	int		result;
	uint32_t	service_type;
	int		timeout = rc_conf_int(rh, "radius_timeout");
	int		retries = rc_conf_int(rh, "radius_retries");
	rc_type		type;

	data.send_pairs = data.receive_pairs = NULL;

	if (rh->so_type == RC_SOCKET_TLS || rh->so_type == RC_SOCKET_DTLS)
		type = AUTH;
	else
		type = ACCT;

	/*
	 * Fill in Service-Type
	 */

	service_type = PW_ADMINISTRATIVE;
	rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, 0);

	rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout, retries);
	result = rc_send_server (rh, &data, msg, type);

	rc_avpair_free(data.receive_pairs);

	return result;
}
Esempio n. 10
0
/* TODO
 * when timeout mechanism will be available
 * rc_auth_function shall be called to try another
 * destination if the current one has timed out
 * */
int resume_send_acct(int fd, struct sip_msg *msg, void *param)
{
	int res, retval;
	struct rad_ctx *rctx;

	rctx = (struct rad_ctx *)param;
	if (rctx == NULL) {
		LM_ERR("no context given\n");
		return -1;
	}


	res = rc_acct_resume(&rctx->ctx);
	if (res == OK_RC || res == REJECT_RC) {
		async_status = ASYNC_DONE;
		retval = 1;
	} else if (res == READBLOCK_RC) {
		async_status  = ASYNC_CONTINUE;
		retval = 1;
		goto exit;
	} else {
		LM_ERR("radius authentication message failed with %s\n",
							((res==BADRESP_RC)?"BAD REPLY":"ERROR"));
		retval = -1;
	}

	if (rctx->send) rc_avpair_free(rctx->send);
	pkg_free(rctx);

exit:
	return retval;
}
Esempio n. 11
0
int
process(void *rh, VALUE_PAIR *send, int acct, int nas_port, int send_info)
{
    VALUE_PAIR *received = NULL;
    char buf[BUF_LEN];
    RC_AAA_CTX *ctx = NULL;
    const unsigned char *p;
    int i, j;

    received = NULL;
    if (acct == 0) {
        i = rc_aaa_ctx(rh, &ctx, nas_port, send, &received, NULL, 1, PW_ACCESS_REQUEST);
        if (received != NULL) {
            printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN));
            rc_avpair_free(received);
        }
        if (ctx) {
            if (send_info) {
                printf("Request-Info-Secret = %s\n", rc_aaa_ctx_get_secret(ctx));
                printf("Request-Info-Vector = ");
                p = rc_aaa_ctx_get_vector(ctx);
                for (j=0; j<AUTH_VECTOR_LEN; j++) {
                    printf("%.2x", (unsigned)p[j]);
                }
                printf("\n");
            }
            rc_aaa_ctx_free(ctx);
        }
    } else {
        i = rc_acct(rh, nas_port, send);
    }

    return (i == OK_RC) ? 0 : 1;
}
Esempio n. 12
0
switch_status_t mod_xml_radius_accounting_end(switch_core_session_t *session){
	VALUE_PAIR *send = NULL;
	uint32_t service = PW_STATUS_STOP;
	rc_handle *new_handle = NULL;
	switch_xml_t fields = NULL, conditions = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	
	if (GLOBAL_DEBUG ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting accounting stop\n");
		switch_core_session_execute_application(session, "info", NULL);
	}
	
	/* If there are conditions defined, and none of them pass, then skip this accounting */
	if ((conditions = switch_xml_child(globals.acct_start_configs, "conditions")) != NULL &&
		mod_xml_radius_check_conditions(channel, conditions) != SWITCH_STATUS_SUCCESS ) {
		goto end;
	}
	
	if ( mod_xml_radius_new_handle(&new_handle, globals.acct_end_configs) != SWITCH_STATUS_SUCCESS || new_handle == NULL ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new accounting_end handle for call: %s\n",
						  switch_channel_get_variable(channel, "uuid"));
		goto end;		
	}

	if ((fields = switch_xml_child(globals.acct_end_configs, "fields")) == NULL ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n");		
		goto end;
	}
	
	if ( mod_xml_radius_add_params(session, NULL, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n");		
		goto end;
	}
	
	if (rc_avpair_add(new_handle, &send, PW_ACCT_STATUS_TYPE, &service, -1, 0) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
		goto end;
	}	

	if (rc_acct(new_handle, 0, send) == OK_RC) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "mod_xml_radius:  Accounting Stop success\n");
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius:  Accounting Stop failed\n");
	}

 end:
	if ( send ) {
		rc_avpair_free(send);
		send = NULL;
	}
	if ( new_handle) {
		rc_destroy(new_handle);
		new_handle = NULL;
	}
	
	return SWITCH_STATUS_SUCCESS;
}
Esempio n. 13
0
/* skip leading text and begin with first item's
 * separator ", " which will be overwritten by the
 * leading text later
 *
 */
static int log_request(struct sip_msg* rq, str* ouri, struct hdr_field* to, unsigned int code, time_t req_time)
{
	VALUE_PAIR *send;
	UINT4 av_type;

	send = NULL;
	if (skip_cancel(rq)) return 1;

	if (fmt2rad(log_fmt, rq, ouri, to, code, &send, req_time) < 0) goto error;

	     /* Add Acct-Status-Type attribute */
	av_type = rad_status(rq, code);
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_ACCT_STATUS_TYPE].v), &av_type, -1, 
			   VENDOR(attrs[A_ACCT_STATUS_TYPE].v))) {
		ERR("Add Status-Type\n");
		goto error;
	}

	     /* Add Service-Type attribute */
	av_type = (service_type != -1) ? service_type : vals[V_SIP_SESSION].v;
	if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SERVICE_TYPE].v), &av_type, -1, 
			   VENDOR(attrs[A_SERVICE_TYPE].v))) {
		ERR("add STATUS_TYPE\n");
		goto error;
	}

	     /* Add User-Name attribute */
	if (add_user_name(rq, rh, &send) < 0) goto error;

	     /* Send the request out */
	if (rc_acct(rh, SIP_PORT, send) != OK_RC) {
		ERR("RADIUS accounting request failed\n");
		goto error;
	}

	rc_avpair_free(send);
	return 1;

error:
	rc_avpair_free(send);
	return -1;
}
Esempio n. 14
0
/*
	Radius implementation for the destroy_aaa_message callback
 */
int rad_destroy_message(aaa_conn* rh, aaa_message* message) {

	if (!rh || ! message) {
		LM_ERR("invalid arguments\n");
		return -1;
	}

 	rc_avpair_free((VALUE_PAIR*) message->avpair);
	pkg_free(message);
	return 0;
}
Esempio n. 15
0
/*
 * Check from Radius if request URI belongs to a local user.
 * User-Name is user@host of request Uri and Service-Type is Call-Check.
 */
int radius_does_uri_exist(struct sip_msg* _m, char* _s1, char* _s2)
{
	static char msg[4096];
	VALUE_PAIR *send, *received;
	UINT4 service;
	char* at, *uri;

	send = received = 0;

	if (parse_sip_msg_uri(_m) < 0) {
		LM_ERR("parsing URI failed\n");
		return -1;
	}
	
	uri = (char*)pkg_malloc(_m->parsed_uri.user.len + _m->parsed_uri.host.len + 2);
	if (!uri) {
		LM_ERR("no more pkg memory\n");
		return -2;
	}

	at = uri;
	memcpy(at, _m->parsed_uri.user.s, _m->parsed_uri.user.len);
	at += _m->parsed_uri.user.len;
	*at = '@';
	at++;
	memcpy(at , _m->parsed_uri.host.s, _m->parsed_uri.host.len);
	at += _m->parsed_uri.host.len;
	*at = '\0';

	if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, uri, -1, 0)) {
		LM_ERR("adding User-Name failed\n");
		rc_avpair_free(send);
		pkg_free(uri);
	 	return -3;
	}

	service = vals[V_CALL_CHECK].v;
	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LM_ERR("adding service type failed\n");
		rc_avpair_free(send);
		pkg_free(uri);
	 	return -4;  	
	}
	
	if (rc_auth(rh, 0, send, &received, msg) == OK_RC) {
		LM_DBG("success\n");
		rc_avpair_free(send);
		generate_avps(received);
		rc_avpair_free(received);
		pkg_free(uri);
		return 1;
	} else {
		LM_DBG("failure\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		pkg_free(uri);
		return -5;
	}
}
Esempio n. 16
0
int send_acct_func(struct sip_msg* msg, str *s) {

	int i, index = -1;
	VALUE_PAIR *send = NULL;

	if (!rh) {
		if (init_radius_handle()) {
			LM_ERR("invalid radius handle\n");
			return -1;
		}
	}

	for (i = 0; i < set_size; i++) {
		if (sets[i]->set_name.len == s->len &&
				!strncmp(sets[i]->set_name.s, s->s, s->len))
				index = i;
	}

	if (index == -1) {
		LM_ERR("set not found\n");
		return -1;
	}

	if (make_send_message(msg, index, &send) < 0) {
		LM_ERR("make message failed\n");
		return -1;
	}

	if (rc_acct(rh, SIP_PORT, send) != OK_RC){
		if (send) rc_avpair_free(send);
		LM_ERR("radius accounting message failed to send\n");
		return -1;
	}

	if (send) rc_avpair_free(send);
	return 1;
}
Esempio n. 17
0
int rc_auth_using_server(SERVER *authserver,
			 UINT4 client_port,
			 VALUE_PAIR *send,
			 VALUE_PAIR **received,
			 char *msg, REQUEST_INFO *info)
{
	SEND_DATA       data;
	int		result;
	int		i;
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = send;
	data.receive_pairs = NULL;

	/*
	 * Fill in NAS-IP-Address or NAS-Identifier
	 */

	if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC)
	    return (ERROR_RC);

	/*
	 * Fill in NAS-Port
	 */

	if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL)
		return (ERROR_RC);

	result = ERROR_RC;
	for(i=0; (i<authserver->max) && (result != OK_RC) && (result != BADRESP_RC)
		; i++)
	{
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i],
			    authserver->port[i], timeout, retries);

		result = rc_send_server (&data, msg, info);
	}

	*received = data.receive_pairs;

	return result;
}
Esempio n. 18
0
/**
 * Perform authenticate request.
 * @param[in] radh Radius handle.
 * @param[out] reply_attr Reply attributes.
 * @param[in,out] reply_msg Reply message.
 * @return One of ZRAD_* codes.
 */
static zrad_status_t zrad_auth_request(rc_handle *radh, const zrad_auth_req_t *req,
                                       VALUE_PAIR **reply_attrs, char *reply_msg)
{
    zrad_status_t ret = ZRAD_OTHER;
    VALUE_PAIR *request_attrs = NULL;

    int success = rc_avpair_add(radh, &request_attrs, PW_USER_NAME, req->username, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_USER_PASSWORD, req->password, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_NAS_IDENTIFIER, req->nas_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_CALLING_STATION_ID, req->calling_station_id, -1, 0);

    if (likely(success)) {
        ret = (zrad_status_t) rc_auth(radh, 0, request_attrs, reply_attrs, reply_msg);
    }

    if (likely(request_attrs)) {
        rc_avpair_free(request_attrs);
    }

    return ret;
}
Esempio n. 19
0
static int radius_log(struct ast_cdr *cdr)
{
	int result = ERROR_RC;
	VALUE_PAIR *tosend = NULL;

	if (build_radius_record(&tosend, cdr)) {
		ast_debug(1, "Unable to create RADIUS record. CDR not recorded!\n");
		goto return_cleanup;
	}

	result = rc_acct(rh, 0, tosend);
	if (result != OK_RC) {
		ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n");
	}

return_cleanup:
	if (tosend) {
		rc_avpair_free(tosend);
	}

	return result;
}
Esempio n. 20
0
static void radius_log(struct ast_event *event)
{
	int result = ERROR_RC;
	VALUE_PAIR *send = NULL;
	int ret = 0;
	char cdr_full_path[256];
	struct ast_cel_event_record record = {
		.version = AST_CEL_EVENT_RECORD_VERSION,
	};

	if (ast_cel_fill_record(event, &record)) {
		return;
	}
	if (build_radius_record(&send, &record)) {
		ast_debug(1, "Unable to create RADIUS record. CEL not recorded!\n");
		goto return_cleanup;
	}

	result = rc_acct(rh, 0, send);
	if (result != OK_RC) {
		ast_log(LOG_ERROR, "Failed to record Radius CEL record! unique_id=%s\n", record.unique_id);
        	/* file name */
        	if(record.unique_id && (!ast_strlen_zero(record.unique_id))){
            		snprintf(cdr_full_path,sizeof(cdr_full_path),"%s/%s",cdr_dir_tmp,record.unique_id);
			/* write cdr to file if rc_acct failed */
			ret = save_avp_to_file(cdr_full_path,record.unique_id,send);
			if(!ret){
				ast_log(LOG_ERROR,"Failed to write cdr to file! unique_id=%s\n", record.unique_id);
			}
        	}
		goto return_cleanup;
	}

return_cleanup:
	if (send) {
		rc_avpair_free(send);
	}
}
Esempio n. 21
0
/**
 * Authenticate and set client info.
 * @param[in] session Client session.
 * @return Zero on success.
 */
zrad_status_t zradius_session_auth(zscope_t *scope, zsession_t *session)
{
    zrad_status_t ret;
    VALUE_PAIR *reply_attrs = NULL;
    char reply_msg[PW_MAX_MSG_SIZE] = {0};

    zclient_rules_t rules;
    zclient_rules_init(&rules);

    zrad_auth_req_t req;
    zrad_auth_prepare(scope, session, &req);

    ret = zrad_auth_request(scope->radh, &req, &reply_attrs, reply_msg);
    if (unlikely(ZRAD_OK != ret)) {
        str_rtrim(reply_msg);
        ZLOG(LOG_ERR, "%s: Session authentication failed for %s (code: %s, msg: %s)",
             scope->cfg->name, session->ip_str, zrad_decode_state(ret), reply_msg);
        goto end;
    }

    zrad_auth_parse(session, reply_attrs, &rules);

    if (unlikely(!rules.have.user_id || !rules.have.login)) {
        ZLOG(LOG_ERR, "%s: Session authentication failed for %s (login or user_id not found)",
             scope->cfg->name, session->ip_str);
        ret = ZRAD_OTHER;
        goto end;
    }

    zscope_session_rules_apply(scope, session, &rules);
    zrad_auth_log(scope, session, reply_attrs);

    end:
    zclient_rules_destroy(&rules);
    if (likely(reply_attrs)) rc_avpair_free(reply_attrs);

    return ret;
}
/** Get a sequence of attribute value pairs from the file input and make them into a list of value_pairs
 *
 * @param rh a handle to parsed configuration.
 * @param input a %FILE handle.
 * @return the array of value pairs.
 */
VALUE_PAIR *rc_avpair_readin(rc_handle const *rh, FILE *input)
{
	VALUE_PAIR *vp = NULL;
	char buffer[1024], *q;

	while (fgets(buffer, sizeof(buffer), input) != NULL)
	{
		q = buffer;

		while(*q && isspace(*q)) q++;

		if ((*q == '\n') || (*q == '#') || (*q == '\0'))
			continue;

		if (rc_avpair_parse(rh, q, &vp) < 0) {
			rc_log(LOG_ERR, "rc_avpair_readin: malformed attribute: %s", buffer);
			rc_avpair_free(vp);
			return NULL;
		}
	}

	return vp;
}
Esempio n. 23
0
/**
 * @param[in] session Session
 * @param[in] status Accounting status (PW_STATUS_START, PW_STATUS_STOP, PW_STATUS_ALIVE)
 * @param[in] cause Accounting termination cause (used only in case of PW_STATUS_STOP)
 * @param[in] req Accounting request data.
 */
static zrad_status_t zrad_acct_request(rc_handle *radh, const zrad_acct_req_t *req)
{
    zrad_status_t ret;
    VALUE_PAIR *request_attrs = NULL;

    int success = rc_avpair_add(radh, &request_attrs, PW_CALLING_STATION_ID, req->calling_station_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_AUTHENTIC, &req->authentic, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_FRAMED_IP_ADDRESS, &req->framed_ip_addr, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_USER_NAME, req->username, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_SESSION_ID, req->session_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_NAS_IDENTIFIER, req->nas_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_OCTETS, &req->octets_down, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_PACKETS, &req->packets_down, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_OCTETS, &req->octets_up, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_PACKETS, &req->packets_down, -1, 0)
                  && (!req->gigawords_down ||
                      rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_GIGAWORDS, &req->gigawords_up, -1, 0))
                  && (!req->gigawords_down ||
                      rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_GIGAWORDS, &req->gigawords_down, -1, 0))
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_STATUS_TYPE, &req->status, -1, 0);

    if (success && PW_STATUS_STOP == req->status) {
        success = success
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_SESSION_TIME, &req->session_time, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_TERMINATE_CAUSE, &req->term_cause, -1, 0);
    }

    if (likely(success)) {
        ret = (zrad_status_t) rc_acct(radh, 0, request_attrs);
    } else {
        ret = ZRAD_OTHER;
    }

    if (likely(request_attrs)) rc_avpair_free(request_attrs);

    return ret;
}
Esempio n. 24
0
int send_auth_func(struct sip_msg* msg, str* s1, str* s2) {

	int i, res;
	int index1 = -1, index2 = -1;
	map_list *mp;
	pv_value_t pvt;
	char mess[1024];

	VALUE_PAIR *send = NULL, *recv = NULL, *vp = NULL;

	if (!rh) {
		if (init_radius_handle()) {
			LM_ERR("invalid radius handle\n");
			return -1;
		}
	}

	for (i = 0; i < set_size; i++) {
		if (sets[i]->set_name.len == s1->len &&
				!strncmp(sets[i]->set_name.s, s1->s, s1->len))
				index1 = i;
		if (sets[i]->set_name.len == s2->len &&
				!strncmp(sets[i]->set_name.s, s2->s, s2->len))
				index2 = i;
	}

	if (index1 == -1) {
		LM_ERR("the first set was not found\n");
		return -1;
	}

	if (index2 == -1) {
		LM_ERR("the second set was not found\n");
		return -1;
	}

	if (make_send_message(msg, index1, &send) < 0) {
		LM_ERR("make message failed\n");
		return -1;
	}

	res = rc_auth(rh, SIP_PORT, send, &recv, mess);
	if (res!=OK_RC && res!=BADRESP_RC) {
		LM_ERR("radius authentication message failed with %s\n",
			(res==TIMEOUT_RC)?"TIMEOUT":"ERROR");
	}else{
		LM_DBG("radius authentication message sent\n");
	}

	for ( mp=sets[index2]->parsed; mp ; mp = mp->next) {
		vp = recv;
		while ( (vp=rc_avpair_get(vp, ATTRID(mp->value), VENDOR(mp->value)))!=NULL ) {
			memset(&pvt, 0, sizeof(pv_value_t));
			if (vp->type == PW_TYPE_INTEGER) {
				pvt.flags = PV_VAL_INT|PV_TYPE_INT;
				pvt.ri = vp->lvalue;
			}
			else
			if (vp->type == PW_TYPE_STRING) {
				pvt.flags = PV_VAL_STR;
				pvt.rs.s = vp->strvalue;
				pvt.rs.len = vp->lvalue;
			}
			if (pv_set_value(msg, mp->pv, (int)EQ_T, &pvt) < 0) {
				LM_ERR("setting avp failed....skipping\n");
			}
			vp = fetch_all_values ? vp->next : NULL;
		}
	}

	vp = recv;
	if (attr)
		for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
			extract_avp(vp);

	if ( res!=OK_RC && res!=BADRESP_RC)
		goto error;


	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);

	return (res==OK_RC)?1:-2;
error:
	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);
	return -1;
}
Esempio n. 25
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, str* _rpid) 
{
	static char msg[4096];
	VALUE_PAIR *send, *received, *vp;
	UINT4 service;
	str method, user, user_name, callid;
	int i;
	
	send = received = 0;

	if (!(_cred && _method && _user && _rpid)) {
		LOG(L_ERR, "radius_authorize_sterman(): 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) {
		if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add User-Name attribute\n");
			rc_avpair_free(send);
			return -2;
		}
	} else {
		user_name.len = _cred->username.user.len + _cred->realm.len + 1;
		user_name.s = pkg_malloc(user_name.len);
		if (!user_name.s) {
			LOG(L_ERR, "radius_authorize_sterman(): No 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)) {
			LOG(L_ERR, "sterman(): Unable to add User-Name attribute\n");
			pkg_free(user_name.s);
			rc_avpair_free(send);
			return -4;
		}
		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)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-User-Name attribute\n");
		rc_avpair_free(send);
		return -5;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s, _cred->realm.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Realm attribute\n");
		rc_avpair_free(send);
		return -6;
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s, _cred->nonce.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Nonce attribute\n");
		rc_avpair_free(send);
		return -7;
	}
	
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_URI].v, _cred->uri.s, _cred->uri.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-URI attribute\n");
		rc_avpair_free(send);
		return -8;
	}
	if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_METHOD].v, method.s, method.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Method attribute\n");
		rc_avpair_free(send);
		return -9;
	}
	
	/* 
	 * 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)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-QOP attribute\n");
			rc_avpair_free(send);
			return -10;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s, _cred->nc.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce-Count attribute\n");
			rc_avpair_free(send);
			return -11;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s, _cred->cnonce.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce attribute\n");
			rc_avpair_free(send);
			return -12;
		}
	} else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth-int", 8, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-QOP attribute\n");
			rc_avpair_free(send);
			return -13;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s, _cred->nc.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-Nonce-Count attribute\n");
			rc_avpair_free(send);
			return -14;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s, _cred->cnonce.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-CNonce attribute\n");
			rc_avpair_free(send);
			return -15;
		}
		if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v, _cred->opaque.s, _cred->opaque.len, 0)) {
			LOG(L_ERR, "sterman(): Unable to add Digest-Body-Digest attribute\n");
			rc_avpair_free(send);
			return -16;
		}
		
	} 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)) {
		LOG(L_ERR, "sterman(): Unable to add Digest-Response attribute\n");
		rc_avpair_free(send);
		return -17;
	}

	/* 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)) {
		LOG(L_ERR, "sterman(): Unable to add Service-Type attribute\n");
		rc_avpair_free(send);
	 	return -18;
	}

	/* Add SIP URI as a check item */
	if (!rc_avpair_add(rh, &send, attrs[A_SIP_URI_USER].v, user.s, user.len, 0)) {
		LOG(L_ERR, "sterman(): Unable to add Sip-URI-User attribute\n");
		rc_avpair_free(send);
	 	return -19;  	
	}

	if (attrs[A_CISCO_AVPAIR].n != NULL) {
		/* Add SIP Call-ID as a Cisco VSA, like IOS does */
		if (_msg->callid == NULL || _msg->callid->body.s == NULL) {
			LOG(L_ERR, "sterman(): Call-ID is missed\n");
			rc_avpair_free(send);
			return -20;
		}
		callid.len = _msg->callid->body.len + 8;
		callid.s = alloca(callid.len);
		if (callid.s == NULL) {
			LOG(L_ERR, "sterman(): No memory left\n");
			rc_avpair_free(send);
			return -21;
		}
		memcpy(callid.s, "call-id=", 8);
		memcpy(callid.s + 8, _msg->callid->body.s, _msg->callid->body.len);
		if (rc_avpair_add(rh, &send, attrs[A_CISCO_AVPAIR].v, callid.s,
		    callid.len, VENDOR(attrs[A_CISCO_AVPAIR].v)) == 0) {
			LOG(L_ERR, "sterman(): Unable to add Cisco-AVPair attribute\n");
			rc_avpair_free(send);
			return -22;
 		}
	}

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

		     /* Make a copy of rpid if available */
		if ((vp = rc_avpair_get(received, attrs[A_SIP_RPID].v, 0))) {
			if (MAX_RPID_LEN < vp->lvalue) {
				LOG(L_ERR, "radius_authorize_sterman(): rpid buffer too small\n");
				return -23;
			}
			memcpy(_rpid->s, vp->strvalue, vp->lvalue);
			_rpid->len = vp->lvalue;
		}

		rc_avpair_free(received);
		return 1;
	} else {
		DBG("res: %d\n", i);
		DBG("radius_authorize_sterman(): Failure\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		return -24;
	}
}
Esempio n. 26
0
/**
 * Authenticate and set client info.
 * @param[in] sess Client session.
 * @return Zero on success (or one of *_RC).
 */
static int session_authenticate(struct zsession *sess)
{
    int ret = OTHER_RC;
    VALUE_PAIR *request_attrs = NULL, *response_attrs = NULL, *attrs = NULL;
    char msg[8192]; // WARNING: libfreeradius-client has unsafe working with this buffer.
    rc_handle *rh = zinst()->radh;
    struct in_addr ip_addr;
    char ip_str[INET_ADDRSTRLEN];
    struct zcrules rules;

    crules_init(&rules);

    ip_addr.s_addr = htonl(sess->ip);
    if (unlikely(NULL == inet_ntop(AF_INET, &ip_addr, ip_str, sizeof(ip_str)))) {
        goto end;
    }

    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_USER_NAME, ip_str, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_USER_PASSWORD, "", -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_NAS_IDENTIFIER, zcfg()->radius_nas_identifier, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_CALLING_STATION_ID, ip_str, -1, 0))) {
        goto end;
    }

    ret = rc_auth(rh, 0, request_attrs, &response_attrs, msg);
    if (OK_RC != ret) {
        ZERO_LOG(LOG_ERR, "Session authentication failed for %s (code:%d)", ip_str, ret);
        goto end;
    }

    attrs = response_attrs;
    while (likely(NULL != attrs)) {
        switch (attrs->attribute) {
            case PW_FILTER_ID:
                crules_parse(&rules, attrs->strvalue);
                break;
            case PW_SESSION_TIMEOUT:
                atomic_store_explicit(&sess->max_duration, SEC2USEC(attrs->lvalue), memory_order_release);
                break;
            case PW_ACCT_INTERIM_INTERVAL:
                atomic_store_explicit(&sess->acct_interval, SEC2USEC(attrs->lvalue), memory_order_release);
                break;
        }
        attrs = attrs->next;
    }

    if (likely(rules.have.user_id && rules.have.login)) {
        struct zclient *client = sess->client;

        client_db_find_or_set_id(zinst()->client_db, rules.user_id, &client);
        if (client != sess->client) {
            // found
            pthread_rwlock_wrlock(&sess->lock_client);
            atomic_fetch_add_explicit(&client->refcnt, 1, memory_order_relaxed);
            client_release(sess->client);
            sess->client = client;
            client_session_add(sess->client, sess);
            pthread_rwlock_unlock(&sess->lock_client);
        } else {
            client_apply_rules(sess->client, &rules);
        }

        atomic_fetch_sub_explicit(&zinst()->unauth_sessions_cnt, 1, memory_order_release);

        // log successful authentication
        {
            UT_string rules_str;
            utstring_init(&rules_str);
            utstring_reserve(&rules_str, 1024);

            attrs = response_attrs;
            while (likely(NULL != attrs)) {
                switch (attrs->attribute) {
                    case PW_FILTER_ID:
                        utstring_printf(&rules_str, " %s", attrs->strvalue);
                        break;
                    default:
                        break;
                }
                attrs = attrs->next;
            }

            zero_syslog(LOG_INFO, "Authenticated session %s (rules:%s)", ip_str, utstring_body(&rules_str));
            utstring_done(&rules_str);
        }
    } else {
        ret = OTHER_RC;
        ZERO_LOG(LOG_ERR, "Session authentication failed for %s (code:%d)", ip_str, ret);
    }

    end:
    crules_free(&rules);
    if (request_attrs) rc_avpair_free(request_attrs);
    if (response_attrs) rc_avpair_free(response_attrs);

    return ret;
}
Esempio n. 27
0
/**
 * Send radius accounting packet.
 * @param[in] sess Session
 * @param[in] status Accounting status (PW_STATUS_START, PW_STATUS_STOP, PW_STATUS_ALIVE)
 * @param[in] cause Accounting termination cause (used only in case of PW_STATUS_STOP)
 * @return Zero on success (one of *_RC codes).
 */
static int session_accounting(struct zsession *sess, uint32_t status, uint32_t term_cause)
{
    int ret = OTHER_RC;
    VALUE_PAIR *request_attrs = NULL;
    rc_handle *rh = zinst()->radh;
    struct in_addr ip_addr;
    char ip_str[INET_ADDRSTRLEN];

    uint64_t traff_down = atomic_load_explicit(&sess->traff_down, memory_order_acquire);
    uint64_t traff_up = atomic_load_explicit(&sess->traff_up, memory_order_acquire);
    uint32_t octets_down = (uint32_t) (traff_down % UINT32_MAX);
    uint32_t octets_up = (uint32_t) (traff_up % UINT32_MAX);
    uint32_t packets_down = atomic_load_explicit(&sess->packets_down, memory_order_acquire) % UINT32_MAX;
    uint32_t packets_up = atomic_load_explicit(&sess->packets_up, memory_order_acquire) % UINT32_MAX;
    uint32_t gigawords_down = 0;
    uint32_t gigawords_up = 0;

    char session_id[255];
    snprintf(session_id, sizeof(session_id), "%s-%" PRIu32, sess->client->login, sess->ip);

    ip_addr.s_addr = htonl(sess->ip);
    if (unlikely(NULL == inet_ntop(AF_INET, &ip_addr, ip_str, sizeof(ip_str)))) {
        goto end;
    }

    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_CALLING_STATION_ID, ip_str, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_FRAMED_IP_ADDRESS, &sess->ip, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_USER_NAME, sess->client->login, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_SESSION_ID, session_id, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_NAS_IDENTIFIER, zcfg()->radius_nas_identifier, -1, 0))) {
        goto end;
    }
    if (PW_STATUS_STOP == status) {
        if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_TERMINATE_CAUSE, &term_cause, -1, 0))) {
            goto end;
        }
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_STATUS_TYPE, &status, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_OCTETS, &octets_down, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_PACKETS, &packets_down, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_OCTETS, &octets_up, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_PACKETS, &packets_down, -1, 0))) {
        goto end;
    }
    if (unlikely(UINT32_MAX < traff_down)) {
        gigawords_down = (uint32_t) (traff_down / UINT32_MAX);
        if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_GIGAWORDS, &gigawords_down, -1, 0))) {
            goto end;
        }
    }
    if (unlikely(UINT32_MAX < traff_up)) {
        gigawords_up = (uint32_t) (traff_up / UINT32_MAX);
        if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_GIGAWORDS, &gigawords_up, -1, 0))) {
            goto end;
        }
    }

    ret = rc_acct(rh, 0, request_attrs);
    if (unlikely(OK_RC != ret)) {
        ZERO_LOG(LOG_ERR, "radius accounting failed %s (code:%d)", ip_str, ret);
        goto end;
    }

    atomic_fetch_sub_explicit(&sess->traff_down, traff_down, memory_order_release);
    atomic_fetch_sub_explicit(&sess->traff_up, traff_up, memory_order_release);
    atomic_fetch_sub_explicit(&sess->packets_down, packets_down, memory_order_release);
    atomic_fetch_sub_explicit(&sess->packets_up, packets_up, memory_order_release);

    end:
    if (request_attrs) {
        rc_avpair_free(request_attrs);
    }

    return ret;
}
Esempio n. 28
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;
}
Esempio n. 29
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;
}
Esempio n. 30
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;
}