Separated accounting from authentication.

This commit is contained in:
Nikos Mavrogiannopoulos
2015-02-23 15:19:44 +01:00
parent 783be933e5
commit 40e96aae45
23 changed files with 662 additions and 332 deletions
-215
View File
@@ -323,218 +323,6 @@ static void radius_auth_deinit(void *ctx)
talloc_free(pctx);
}
static void append_stats(rc_handle *rh, VALUE_PAIR **send, stats_st *stats)
{
uint32_t uin, uout;
if (stats->uptime) {
uin = stats->uptime;
if (rc_avpair_add(rh, send, PW_ACCT_SESSION_TIME, &uin, -1, 0) == NULL) {
return;
}
}
uin = stats->bytes_in;
uout = stats->bytes_out;
if (rc_avpair_add(rh, send, PW_ACCT_INPUT_OCTETS, &uin, -1, 0) == NULL) {
return;
}
if (rc_avpair_add(rh, send, PW_ACCT_OUTPUT_OCTETS, &uout, -1, 0) == NULL) {
return;
}
uin = stats->bytes_in / 4294967296;
if (rc_avpair_add(rh, send, PW_ACCT_INPUT_GIGAWORDS, &uin, -1, 0) == NULL) {
return;
}
uout = stats->bytes_in / 4294967296;
if (rc_avpair_add(rh, send, PW_ACCT_OUTPUT_GIGAWORDS, &uout, -1, 0) == NULL) {
return;
}
return;
}
static void append_acct_standard(struct radius_ctx_st * pctx, rc_handle *rh,
VALUE_PAIR **send)
{
int i;
if (nas_identifier[0] != 0) {
if (rc_avpair_add(rh, send, PW_NAS_IDENTIFIER, nas_identifier, -1, 0) == NULL) {
return;
}
}
if (rc_avpair_add(rh, send, PW_USER_NAME, pctx->username, -1, 0) == NULL) {
return;
}
i = PW_FRAMED;
if (rc_avpair_add(rh, send, PW_SERVICE_TYPE, &i, -1, 0) == NULL) {
return;
}
i = PW_PPP;
if (rc_avpair_add(rh, send, PW_FRAMED_PROTOCOL, &i, -1, 0) == NULL) {
return;
}
if (pctx->ipv4[0] != 0) {
struct in_addr in;
inet_pton(AF_INET, pctx->ipv4, &in);
in.s_addr = ntohl(in.s_addr);
if (rc_avpair_add(rh, send, PW_FRAMED_IP_ADDRESS, &in, sizeof(in), 0) == NULL) {
return;
}
}
if (pctx->ipv6[0] != 0) {
struct in6_addr in;
inet_pton(AF_INET6, pctx->ipv6, &in);
if (rc_avpair_add(rh, send, PW_FRAMED_IPV6_ADDRESS, &in, sizeof(in), 0) == NULL) {
return;
}
}
if (rc_avpair_add(rh, send, PW_CALLING_STATION_ID, pctx->remote_ip, -1, 0) == NULL) {
return;
}
if (rc_avpair_add(rh, send, PW_ACCT_SESSION_ID, pctx->sid, -1, 0) == NULL) {
return;
}
i = PW_RADIUS;
if (rc_avpair_add(rh, send, PW_ACCT_AUTHENTIC, &i, -1, 0) == NULL) {
return;
}
i = PW_ASYNC;
if (rc_avpair_add(rh, send, PW_NAS_PORT_TYPE, &i, -1, 0) == NULL) {
return;
}
return;
}
static void radius_auth_session_stats(void* ctx, stats_st *stats, const char *ip)
{
struct radius_ctx_st * pctx = ctx;
int ret;
uint32_t status_type;
VALUE_PAIR *send = NULL, *recvd = NULL;
if (ip)
strlcpy(pctx->remote_ip, ip, sizeof(pctx->remote_ip));
status_type = PW_STATUS_ALIVE;
syslog(LOG_DEBUG, "radius-auth: sending session interim update");
if (rc_avpair_add(rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) {
ret = -1;
goto cleanup;
}
append_acct_standard(pctx, rh, &send);
append_stats(rh, &send, stats);
ret = rc_aaa(rh, 0, send, &recvd, NULL, 1, PW_ACCOUNTING_REQUEST);
if (recvd != NULL)
rc_avpair_free(recvd);
if (ret != OK_RC) {
syslog(LOG_AUTH, "radius-auth: radius_open_session: %d", ret);
goto cleanup;
}
cleanup:
rc_avpair_free(send);
return;
}
static int radius_auth_open_session(void* ctx, const void *sid, unsigned sid_size)
{
struct radius_ctx_st * pctx = ctx;
int ret;
uint32_t status_type;
VALUE_PAIR *send = NULL, *recvd = NULL;
status_type = PW_STATUS_START;
if (sid_size != SID_SIZE) {
syslog(LOG_DEBUG, "radius-auth: incorrect sid size");
return -1;
}
base64_encode((char *)sid, sid_size, (char *)pctx->sid, sizeof(pctx->sid));
syslog(LOG_DEBUG, "radius-auth: opening session %s", pctx->sid);
if (rc_avpair_add(rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) {
ret = -1;
goto cleanup;
}
append_acct_standard(pctx, rh, &send);
ret = rc_aaa(rh, 0, send, &recvd, NULL, 1, PW_ACCOUNTING_REQUEST);
if (recvd != NULL)
rc_avpair_free(recvd);
if (ret != OK_RC) {
syslog(LOG_AUTH, "radius-auth: radius_open_session: %d", ret);
ret = -1;
goto cleanup;
}
ret = 0;
cleanup:
rc_avpair_free(send);
return ret;
}
static void radius_auth_close_session(void* ctx, stats_st *stats)
{
struct radius_ctx_st * pctx = ctx;
int ret;
uint32_t status_type;
VALUE_PAIR *send = NULL, *recvd = NULL;
status_type = PW_STATUS_STOP;
syslog(LOG_DEBUG, "radius-auth: closing session");
if (rc_avpair_add(rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL)
return;
ret = PW_USER_REQUEST;
if (rc_avpair_add(rh, &send, PW_ACCT_TERMINATE_CAUSE, &ret, -1, 0) == NULL) {
goto cleanup;
}
append_acct_standard(pctx, rh, &send);
append_stats(rh, &send, stats);
ret = rc_aaa(rh, 0, send, &recvd, NULL, 1, PW_ACCOUNTING_REQUEST);
if (recvd != NULL)
rc_avpair_free(recvd);
if (ret != OK_RC) {
syslog(LOG_INFO, "radius-auth: radius_close_session: %d", ret);
goto cleanup;
}
cleanup:
rc_avpair_free(send);
return;
}
const struct auth_mod_st radius_auth_funcs = {
.type = AUTH_TYPE_RADIUS | AUTH_TYPE_USERNAME_PASS,
.allows_retries = 1,
@@ -546,9 +334,6 @@ const struct auth_mod_st radius_auth_funcs = {
.auth_pass = radius_auth_pass,
.auth_user = radius_auth_user,
.auth_group = radius_auth_group,
.open_session = radius_auth_open_session,
.close_session = radius_auth_close_session,
.session_stats = radius_auth_session_stats,
.group_list = NULL
};