Date: Wed, 2 Dec 2009 00:39:31 +0200 From: Michael Pounov <misho@aitbg.com> To: freebsd-net@freebsd.org Cc: emaste@freebsd.org Subject: [patch] for missing TACACS+ accounting Message-ID: <20091202003931.255e3aed.misho@aitbg.com>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --Multipart=_Wed__2_Dec_2009_00_39_31_+0200_9Rt3U3Pd9AOft84e Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Hi all, I am sending a patch that adds support for TACACS+ accounting to libtacplus(3). Comments welcome. -- M.Punov --------------------- AITNET - Sofia/Bulgaria - Software & Network Solutions (+359) 888 73 73 58;(+359) 2 402 4000 --Multipart=_Wed__2_Dec_2009_00_39_31_+0200_9Rt3U3Pd9AOft84e Content-Type: text/x-diff; name="libtacplus-20091201-01.patch" Content-Disposition: attachment; filename="libtacplus-20091201-01.patch" Content-Transfer-Encoding: 7bit Index: libtacplus.3 =================================================================== RCS file: /home/ncvs/src/lib/libtacplus/libtacplus.3,v retrieving revision 1.14 diff -u -r1.14 libtacplus.3 --- libtacplus.3 28 Oct 2006 10:53:39 -0000 1.14 +++ libtacplus.3 1 Dec 2009 22:26:11 -0000 @@ -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 @@ 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 @@ .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 @@ .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 Index: taclib.c =================================================================== RCS file: /home/ncvs/src/lib/libtacplus/taclib.c,v retrieving revision 1.7 diff -u -r1.7 taclib.c --- taclib.c 25 Nov 2009 14:59:28 -0000 1.7 +++ taclib.c 1 Dec 2009 20:58:35 -0000 @@ -211,6 +211,8 @@ } break; + case TAC_ACCT: + default: minor = 0; break; @@ -967,6 +969,23 @@ 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) { @@ -1158,6 +1177,49 @@ } 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) { return save_str(h, &h->rem_addr, addr, addr != NULL ? strlen(addr) : 0); Index: taclib.h =================================================================== RCS file: /home/ncvs/src/lib/libtacplus/taclib.h,v retrieving revision 1.2 diff -u -r1.2 taclib.h --- taclib.h 25 Sep 2002 23:18:51 -0000 1.2 +++ taclib.h 1 Dec 2009 20:29:18 -0000 @@ -103,6 +103,17 @@ #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 @@ 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_ */ Index: taclib_private.h =================================================================== RCS file: /home/ncvs/src/lib/libtacplus/taclib_private.h,v retrieving revision 1.2 diff -u -r1.2 taclib_private.h --- taclib_private.h 25 Sep 2002 23:18:51 -0000 1.2 +++ taclib_private.h 1 Dec 2009 20:41:15 -0000 @@ -132,6 +132,26 @@ 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_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; }; --Multipart=_Wed__2_Dec_2009_00_39_31_+0200_9Rt3U3Pd9AOft84e--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20091202003931.255e3aed.misho>