Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

Commit

Permalink
Add support for multiplexed sessions
Browse files Browse the repository at this point in the history
Add method for setting whether session is multiplexed or not; mark
packet header flags appropriately; reset timeouts on connection when
we have received a response (since our request has been answered, no
more data will be read or written for now).
  • Loading branch information
pprindeville committed Dec 13, 2016
1 parent 0164c2f commit 55dfb26
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 57 deletions.
3 changes: 3 additions & 0 deletions libtac/include/libtac.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ struct tac_session {
const char *tac_secret;
uint32_t tac_session_id;
bool tac_encryption;
bool tac_multiplex;
uint8_t tac_priv_lvl;
uint8_t tac_authen_method;
uint8_t tac_authen_service;
Expand All @@ -183,6 +184,8 @@ struct tac_session *tac_session_alloc_extra(unsigned);
void tac_session_set_authen_type(struct tac_session *, uint8_t);
void tac_session_set_secret(struct tac_session *, const char *);
void tac_session_set_timeout(struct tac_session *, unsigned);
void tac_session_set_multiplex(struct tac_session *, bool);
void tac_session_reset_timeouts(struct tac_session *, bool);
void tac_session_set_response(struct tac_session *, response_cb_t);
void tac_session_set_oob(struct tac_session *, oob_cb_t);
struct cb_ctx *tac_session_get_context(struct tac_session *);
Expand Down
3 changes: 2 additions & 1 deletion libtac/lib/acct_s.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ void tac_acct_send_pkt(struct tac_session *sess, u_char type,
th->version = TAC_PLUS_VER_0;
th->type = TAC_PLUS_ACCT;
th->seq_no = ++sess->seq_no;
th->encryption = sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
th->encryption = sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
th->session_id = htonl(sess->tac_session_id);
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);

Expand Down
5 changes: 2 additions & 3 deletions libtac/lib/authen_s.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,8 @@ void tac_authen_send_pkt(struct tac_session *sess,
}
th->type = TAC_PLUS_AUTHEN;
th->seq_no = ++sess->seq_no;
th->encryption =
sess->tac_encryption ?
TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
th->encryption = (sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
th->session_id = htonl(sess->tac_session_id);
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);

Expand Down
3 changes: 2 additions & 1 deletion libtac/lib/author_s.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ void tac_author_send_pkt(struct tac_session *sess,
th->version = TAC_PLUS_VER_0;
th->type = TAC_PLUS_AUTHOR;
th->seq_no = ++sess->seq_no;
th->encryption = sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
th->encryption = (sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
th->session_id = htonl(sess->tac_session_id);
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);

Expand Down
5 changes: 2 additions & 3 deletions libtac/lib/cont_s.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ void tac_cont_send_pkt(struct tac_session *sess, const char *pass,
th->version = TAC_PLUS_VER_0;
th->type = TAC_PLUS_AUTHEN;
th->seq_no = ++sess->seq_no;
th->encryption =
sess->tac_encryption ?
TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
th->encryption = (sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
th->session_id = htonl(sess->tac_session_id);
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);

Expand Down
3 changes: 2 additions & 1 deletion libtac/lib/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ HDR *_tac_req_header(struct tac_session *sess, u_char type, bool cont_session) {
/* preset some packet options in header */
th->type=type;
th->seq_no=++sess->seq_no;
th->encryption=TAC_PLUS_ENCRYPTED_FLAG;
th->encryption=(sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);

/* make session_id from pseudo-random number */
if (!cont_session) {
Expand Down
8 changes: 7 additions & 1 deletion libtac/lib/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ tac_session_alloc_extra(unsigned n)
sess->tac_timeout = 5;
sess->tac_secret = NULL;
sess->tac_session_id = magic();
sess->tac_encryption = false;
sess->tac_encryption = sess->tac_multiplex = false;
sess->tac_priv_lvl = TAC_PLUS_PRIV_LVL_MIN;
sess->tac_authen_service = TAC_PLUS_AUTHEN_SVC_PPP;
sess->tac_authen_method = TAC_PLUS_AUTHEN_METH_TACACSPLUS;
Expand Down Expand Up @@ -80,6 +80,12 @@ tac_session_set_timeout(struct tac_session *sess, unsigned timeout)
sess->tac_timeout = timeout;
}

void
tac_session_set_multiplex(struct tac_session *sess, bool multiplex)
{
sess->tac_multiplex = multiplex;
}

void
tac_session_set_response(struct tac_session *sess, response_cb_t cb)
{
Expand Down
42 changes: 39 additions & 3 deletions libtac/lib/wrappers.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,25 @@ tac_event_loop_global_shutdown(void)
#endif
}

void tac_session_reset_timeouts(struct tac_session *sess, bool on)
{
struct timeval tv = { sess->tac_timeout, 0 };

TACDEBUG(LOG_DEBUG, "session %p reset_timeouts %u %s", sess, sess->tac_timeout, (on ? "on" : "off"));

if (!sess->bufev)
return;

/* nothing will be enabled if we haven't yet connected... */
if (bufferevent_get_enabled(sess->bufev) == 0)
return;

if (on)
bufferevent_set_timeouts(sess->bufev, &tv, &tv);
else
bufferevent_set_timeouts(sess->bufev, NULL, NULL);
}

static void eventcb(struct bufferevent *bev, short events, void *ptr)
{
struct cb_ctx *ctx = (struct cb_ctx *)ptr;
Expand All @@ -125,6 +144,8 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr)
if (sess->oob_cb) {
if (events & BEV_EVENT_CONNECTED) {
TACDEBUG(LOG_DEBUG, "session %p connected", sess);
/* change for setup timeout to read/write timeout values */
tac_session_reset_timeouts(sess, true);
(sess->oob_cb)(sess, &sess->context, CONNECTED);
}
if (events & BEV_EVENT_ERROR) {
Expand Down Expand Up @@ -214,10 +235,13 @@ static void readcb(struct bufferevent *bev, void *ptr)
/* copy out... */
i = evbuffer_remove(evbuf, pkt, length);

if (i < 0 || (unsigned) i != n)
TACDEBUG(LOG_DEBUG, "%s: evbuffer_remove want %ld got %d", __FUNCTION__, n, i);
if (i < 0 || (unsigned) i != length)
TACDEBUG(LOG_DEBUG, "%s: evbuffer_remove want %u got %d", __FUNCTION__, length, i);

tac_parse_pkt(ctx->sess, ctx, pkt, length);
/* turn off timeouts */
tac_session_reset_timeouts(sess, false);

tac_parse_pkt(sess, ctx, pkt, ((i > 0) ? i : 0));

free(pkt);
}
Expand Down Expand Up @@ -292,6 +316,9 @@ tac_authen_send_ev(struct tac_session *sess,
/* generate the packet */
tac_authen_send_pkt(sess, user, pass, tty, r_addr, action, &pkt, &pkt_total);

/* if reusing connection, reset timeouts */
tac_session_reset_timeouts(sess, true);

/*
* make evbuffer wrap around our packet, and call cleanup (free)
* when done
Expand Down Expand Up @@ -328,6 +355,9 @@ tac_author_send_ev(struct tac_session *sess,
/* generate the packet */
tac_author_send_pkt(sess, user, tty, r_addr, attr, &pkt, &pkt_total);

/* if reusing connection, reset timeouts */
tac_session_reset_timeouts(sess, true);

/*
* make evbuffer wrap around our packet, and call cleanup (free)
* when done
Expand Down Expand Up @@ -364,6 +394,9 @@ tac_acct_send_ev(struct tac_session *sess,
/* generate the packet */
tac_acct_send_pkt(sess, type, user, tty, r_addr, attr, &pkt, &pkt_total);

/* if reusing connection, reset timeouts */
tac_session_reset_timeouts(sess, true);

/*
* make evbuffer wrap around our packet, and call cleanup (free)
* when done
Expand Down Expand Up @@ -397,6 +430,9 @@ tac_cont_send_ev(struct tac_session *sess, const char *pass) {
/* generate the packet */
tac_cont_send_pkt(sess, pass, &pkt, &pkt_total);

/* if reusing connection, reset timeouts */
tac_session_reset_timeouts(sess, true);

/*
* make evbuffer wrap around our packet, and call cleanup (free)
* when done
Expand Down
58 changes: 14 additions & 44 deletions tacc.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,29 +280,31 @@ int main(int argc, char **argv) {

sess = tac_session_alloc();

ret = tac_connect_single(sess, tac_server, NULL, 60);
if (ret < 0) {
if (!quiet)
printf("Error connecting to TACACS+ server: %m\n");
exit(EXIT_ERR);
}

tac_session_set_secret(sess, tac_secret);
tac_session_set_authen_type(sess, tac_get_authen_type(tac_login));

tac_session_set_multiplex(sess, true);

if (do_authen)
authenticate(tac_server, tac_secret, user, pass, tty, remote_addr);

/* we no longer need the password in our address space */
bzero(pass, strlen(pass));
pass = NULL;

if (do_author) {
/* authorize user */
struct tac_attrib *attr = NULL;
tac_add_attrib(&attr, "service", service);
tac_add_attrib(&attr, "protocol", protocol);

tac_session_new_session_id(sess);
tac_session_reset_seq(sess);

ret = tac_connect_single(sess, tac_server, NULL, 60);
if (ret < 0) {
if (!quiet)
printf("Error connecting to TACACS+ server: %m\n");
exit(EXIT_ERR);
}

tac_session_set_secret(sess, tac_secret);

tac_author_send(sess, user, tty, remote_addr, attr);

tac_author_read(sess, &arep);
Expand All @@ -319,10 +321,6 @@ int main(int argc, char **argv) {
tac_free_attrib(&attr);
}

/* we no longer need the password in our address space */
bzero(pass, strlen(pass));
pass = NULL;

if (do_account) {
/* start accounting */
struct tac_attrib *attr = NULL;
Expand All @@ -334,18 +332,6 @@ int main(int argc, char **argv) {
tac_add_attrib(&attr, "service", service);
tac_add_attrib(&attr, "protocol", protocol);

tac_session_new_session_id(sess);
tac_session_reset_seq(sess);

ret = tac_connect_single(sess, tac_server, NULL, 60);
if (ret < 0) {
if (!quiet)
printf("Error connecting to TACACS+ server: %m\n");
exit(EXIT_ERR);
}

tac_session_set_secret(sess, tac_secret);

tac_acct_send(sess, TAC_PLUS_ACCT_FLAG_START, user, tty, remote_addr,
attr);

Expand Down Expand Up @@ -425,18 +411,6 @@ int main(int argc, char **argv) {
sprintf(buf, "%hu", task_id);
tac_add_attrib(&attr, "task_id", buf);

tac_session_new_session_id(sess);
tac_session_reset_seq(sess);

ret = tac_connect_single(sess, tac_server, NULL, 60);
if (ret < 0) {
if (!quiet)
printf("Error connecting to TACACS+ server: %m\n");
exit(EXIT_ERR);
}

tac_session_set_secret(sess, tac_secret);

tac_acct_send(sess, TAC_PLUS_ACCT_FLAG_STOP, user, tty, remote_addr,
attr);
ret = tac_acct_read(sess, &arep);
Expand All @@ -447,8 +421,6 @@ int main(int argc, char **argv) {
} else if (!login_mode && !quiet)
printf("Accounting: STOP OK\n");

tac_close(sess);

tac_free_attrib(&attr);
}

Expand Down Expand Up @@ -519,8 +491,6 @@ void authenticate(const struct addrinfo *tac_server, const char *tac_secret,
if (!quiet)
printf("Authentication OK\n");
syslog(LOG_INFO, "authentication OK for %s", user);

tac_close(sess);
}

void showusage(char *progname) {
Expand Down

0 comments on commit 55dfb26

Please sign in to comment.