mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-23 20:01:08 +01:00
Add support for TACACS+ accounting to libtacplus(3).
Submitted by: Michael Pounov misho@aitbg.com OKed by: emaste
This commit is contained in:
parent
57467e5933
commit
db3a20a518
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=200399
@ -44,6 +44,8 @@
|
||||
.Fn tac_create_authen "struct tac_handle *h" "int action" "int type" "int service"
|
||||
.Ft int
|
||||
.Fn tac_create_author "struct tac_handle *h" "int method" "int type" "int service"
|
||||
.Ft int
|
||||
.Fn tac_create_acct "struct tac_handle *h" "int acct" "int action" "int type" "int service"
|
||||
.Ft char *
|
||||
.Fn tac_get_av "struct tac_handle *h" "u_int index"
|
||||
.Ft char *
|
||||
@ -59,6 +61,8 @@
|
||||
.Ft int
|
||||
.Fn tac_send_author "struct tac_handle *h"
|
||||
.Ft int
|
||||
.Fn tac_send_acct "struct tac_handle *h"
|
||||
.Ft int
|
||||
.Fn tac_set_av "struct tac_handle *h" "u_int index" "const char *av_pair"
|
||||
.Ft int
|
||||
.Fn tac_set_data "struct tac_handle *h" "const void *data" "size_t data_len"
|
||||
@ -193,6 +197,20 @@ TACACS+ protocol specification.
|
||||
The
|
||||
.In taclib.h
|
||||
header file contains symbolic constants for these values.
|
||||
.Sh CREATING A TACACS+ ACCOUNTING REQUEST
|
||||
To begin constructing a new accounting request, call
|
||||
.Fn tac_create_acct .
|
||||
The
|
||||
.Va acct ,
|
||||
.Va action ,
|
||||
.Va type ,
|
||||
and
|
||||
.Va service
|
||||
arguments must be set to appropriate values as defined in the
|
||||
TACACS+ protocol specification.
|
||||
The
|
||||
.In taclib.h
|
||||
header file contains symbolic constants for these values.
|
||||
.Sh SETTING OPTIONAL PARAMETERS ON A REQUEST
|
||||
After creating a request,
|
||||
various optional parameters may be attached to it through calls to
|
||||
@ -354,6 +372,29 @@ include:
|
||||
.Pp
|
||||
The number of AV pairs received is obtained using
|
||||
.Fn TAC_AUTHEN_AV_COUNT .
|
||||
.Sh SENDING THE ACCOUNTING REQUEST AND RECEIVING THE RESPONSE
|
||||
After the TACACS+ authorization request has been constructed, it
|
||||
is sent by means of
|
||||
.Fn tac_send_acct .
|
||||
This function connects to a server if not already connected, sends
|
||||
the request, and waits for a reply.
|
||||
On failure,
|
||||
.Fn tac_send_acct
|
||||
returns \-1.
|
||||
Otherwise, it returns the TACACS+ status code
|
||||
Possible status codes, defined in
|
||||
.In taclib.h ,
|
||||
include:
|
||||
.Pp
|
||||
.Bl -item -compact -offset indent
|
||||
.It
|
||||
.Dv TAC_ACCT_STATUS_SUCCESS
|
||||
.It
|
||||
.Dv TAC_ACCT_STATUS_ERROR
|
||||
.It
|
||||
.Dv TAC_ACCT_STATUS_FOLLOW
|
||||
.El
|
||||
.Pp
|
||||
.Sh EXTRACTING INFORMATION FROM THE SERVER'S AUTHORIZATION RESPONSE
|
||||
Like an authentication response packet, an authorization
|
||||
response packet from the
|
||||
@ -418,10 +459,14 @@ which can be retrieved using
|
||||
.It
|
||||
.Fn tac_create_author
|
||||
.It
|
||||
.Fn tac_create_acct
|
||||
.It
|
||||
.Fn tac_send_authen
|
||||
.It
|
||||
.Fn tac_send_author
|
||||
.It
|
||||
.Fn tac_send_acct
|
||||
.It
|
||||
.Fn tac_set_av
|
||||
.It
|
||||
.Fn tac_set_data
|
||||
|
@ -211,6 +211,8 @@ protocol_version(int msg_type, int var, int type)
|
||||
}
|
||||
break;
|
||||
|
||||
case TAC_ACCT:
|
||||
|
||||
default:
|
||||
minor = 0;
|
||||
break;
|
||||
@ -967,6 +969,23 @@ tac_create_author(struct tac_handle *h, int method, int type, int service)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tac_create_acct(struct tac_handle *h, int acct, int action, int type, int service)
|
||||
{
|
||||
struct tac_acct_start *as;
|
||||
|
||||
create_msg(h, TAC_ACCT, action, type);
|
||||
|
||||
as = &h->request.u.acct_start;
|
||||
as->action = acct;
|
||||
as->authen_action = action;
|
||||
as->priv_lvl = TAC_PRIV_LVL_USER;
|
||||
as->authen_type = type;
|
||||
as->authen_service = service;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
create_msg(struct tac_handle *h, int msg_type, int var, int type)
|
||||
{
|
||||
@ -1157,6 +1176,49 @@ tac_send_author(struct tac_handle *h)
|
||||
return ares->av_cnt << 8 | ares->status;
|
||||
}
|
||||
|
||||
int
|
||||
tac_send_acct(struct tac_handle *h)
|
||||
{
|
||||
register int i, current;
|
||||
struct tac_acct_start *as = &h->request.u.acct_start;
|
||||
struct tac_acct_reply *ar = &h->response.u.acct_reply;
|
||||
|
||||
/* start */
|
||||
as = &h->request.u.acct_start;
|
||||
h->request.length = htonl(offsetof(struct tac_acct_start, rest[0]));
|
||||
for (as->av_cnt = 0, i = 0; i < MAXAVPAIRS; i++)
|
||||
if (h->avs[i].len && h->avs[i].data)
|
||||
as->av_cnt++;
|
||||
h->request.length = ntohl(htonl(h->request.length) + as->av_cnt);
|
||||
|
||||
if (add_str_8(h, &as->user_len, &h->user) == -1 ||
|
||||
add_str_8(h, &as->port_len, &h->port) == -1 ||
|
||||
add_str_8(h, &as->rem_addr_len, &h->rem_addr) == -1)
|
||||
return -1;
|
||||
|
||||
for (i = current = 0; i < MAXAVPAIRS; i++)
|
||||
if (h->avs[i].len && h->avs[i].data)
|
||||
if (add_str_8(h, &as->rest[current++], &(h->avs[i])) == -1)
|
||||
return -1;
|
||||
|
||||
/* send */
|
||||
if (send_msg(h) == -1 || recv_msg(h) == -1)
|
||||
return -1;
|
||||
|
||||
/* reply */
|
||||
h->srvr_pos = offsetof(struct tac_acct_reply, rest[0]);
|
||||
if (get_srvr_str(h, "msg", &h->srvr_msg, ntohs(ar->msg_len)) == -1 ||
|
||||
get_srvr_str(h, "data", &h->srvr_data, ntohs(ar->data_len)) == -1 ||
|
||||
get_srvr_end(h) == -1)
|
||||
return -1;
|
||||
|
||||
/* Sanity checks */
|
||||
if (!h->single_connect)
|
||||
close_connection(h);
|
||||
|
||||
return ar->status;
|
||||
}
|
||||
|
||||
int
|
||||
tac_set_rem_addr(struct tac_handle *h, const char *addr)
|
||||
{
|
||||
|
@ -103,6 +103,17 @@ struct tac_handle;
|
||||
#define TAC_AUTHOR_STATUS_FAIL 0x10
|
||||
#define TAC_AUTHOR_STATUS_ERROR 0x11
|
||||
|
||||
/* Accounting actions */
|
||||
#define TAC_ACCT_MORE 0x1
|
||||
#define TAC_ACCT_START 0x2
|
||||
#define TAC_ACCT_STOP 0x4
|
||||
#define TAC_ACCT_WATCHDOG 0x8
|
||||
|
||||
/* Accounting status */
|
||||
#define TAC_ACCT_STATUS_SUCCESS 0x1
|
||||
#define TAC_ACCT_STATUS_ERROR 0x2
|
||||
#define TAC_ACCT_STATUS_FOLLOW 0x21
|
||||
|
||||
__BEGIN_DECLS
|
||||
int tac_add_server(struct tac_handle *,
|
||||
const char *, int, const char *, int, int);
|
||||
@ -127,6 +138,8 @@ int tac_set_av(struct tac_handle *, u_int, const char *);
|
||||
char *tac_get_av(struct tac_handle *, u_int);
|
||||
char *tac_get_av_value(struct tac_handle *, const char *);
|
||||
void tac_clear_avs(struct tac_handle *);
|
||||
int tac_create_acct(struct tac_handle *, int, int, int, int);
|
||||
int tac_send_acct(struct tac_handle *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _TACLIB_H_ */
|
||||
|
@ -132,6 +132,26 @@ struct tac_author_response {
|
||||
unsigned char rest[1];
|
||||
};
|
||||
|
||||
struct tac_acct_start {
|
||||
u_int8_t action;
|
||||
u_int8_t authen_action;
|
||||
u_int8_t priv_lvl;
|
||||
u_int8_t authen_type;
|
||||
u_int8_t authen_service;
|
||||
u_int8_t user_len;
|
||||
u_int8_t port_len;
|
||||
u_int8_t rem_addr_len;
|
||||
u_int8_t av_cnt;
|
||||
unsigned char rest[1];
|
||||
};
|
||||
|
||||
struct tac_acct_reply {
|
||||
u_int16_t msg_len;
|
||||
u_int16_t data_len;
|
||||
u_int8_t status;
|
||||
unsigned char rest[1];
|
||||
};
|
||||
|
||||
struct tac_msg {
|
||||
u_int8_t version;
|
||||
u_int8_t type;
|
||||
@ -145,6 +165,8 @@ struct tac_msg {
|
||||
struct tac_authen_cont authen_cont;
|
||||
struct tac_author_request author_request;
|
||||
struct tac_author_response author_response;
|
||||
struct tac_acct_start acct_start;
|
||||
struct tac_acct_reply acct_reply;
|
||||
unsigned char body[BODYSIZE];
|
||||
} u;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user