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

Commit dfee11a

Browse files
committed
Add support for multiplexed sessions
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).
1 parent 898f17c commit dfee11a

File tree

9 files changed

+73
-57
lines changed

9 files changed

+73
-57
lines changed

libtac/include/libtac.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct tac_session {
160160
const char *tac_secret;
161161
uint32_t tac_session_id;
162162
bool tac_encryption;
163+
bool tac_multiplex;
163164
uint8_t tac_priv_lvl;
164165
uint8_t tac_authen_method;
165166
uint8_t tac_authen_service;
@@ -183,6 +184,8 @@ struct tac_session *tac_session_alloc_extra(unsigned);
183184
void tac_session_set_authen_type(struct tac_session *, uint8_t);
184185
void tac_session_set_secret(struct tac_session *, const char *);
185186
void tac_session_set_timeout(struct tac_session *, unsigned);
187+
void tac_session_set_multiplex(struct tac_session *, bool);
188+
void tac_session_reset_timeouts(struct tac_session *, bool);
186189
void tac_session_set_response(struct tac_session *, response_cb_t);
187190
void tac_session_set_oob(struct tac_session *, oob_cb_t);
188191
struct cb_ctx *tac_session_get_context(struct tac_session *);

libtac/lib/acct_s.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ void tac_acct_send_pkt(struct tac_session *sess, u_char type,
8383
th->version = TAC_PLUS_VER_0;
8484
th->type = TAC_PLUS_ACCT;
8585
th->seq_no = ++sess->seq_no;
86-
th->encryption = sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
86+
th->encryption = sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG
87+
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
8788
th->session_id = htonl(sess->tac_session_id);
8889
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);
8990

libtac/lib/authen_s.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,8 @@ void tac_authen_send_pkt(struct tac_session *sess,
152152
}
153153
th->type = TAC_PLUS_AUTHEN;
154154
th->seq_no = ++sess->seq_no;
155-
th->encryption =
156-
sess->tac_encryption ?
157-
TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
155+
th->encryption = (sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
156+
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
158157
th->session_id = htonl(sess->tac_session_id);
159158
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);
160159

libtac/lib/author_s.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ void tac_author_send_pkt(struct tac_session *sess,
6767
th->version = TAC_PLUS_VER_0;
6868
th->type = TAC_PLUS_AUTHOR;
6969
th->seq_no = ++sess->seq_no;
70-
th->encryption = sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
70+
th->encryption = (sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
71+
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
7172
th->session_id = htonl(sess->tac_session_id);
7273
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);
7374

libtac/lib/cont_s.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ void tac_cont_send_pkt(struct tac_session *sess, const char *pass,
5656
th->version = TAC_PLUS_VER_0;
5757
th->type = TAC_PLUS_AUTHEN;
5858
th->seq_no = ++sess->seq_no;
59-
th->encryption =
60-
sess->tac_encryption ?
61-
TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
59+
th->encryption = (sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
60+
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
6261
th->session_id = htonl(sess->tac_session_id);
6362
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);
6463

libtac/lib/header.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ HDR *_tac_req_header(struct tac_session *sess, u_char type, bool cont_session) {
4747
/* preset some packet options in header */
4848
th->type=type;
4949
th->seq_no=++sess->seq_no;
50-
th->encryption=TAC_PLUS_ENCRYPTED_FLAG;
50+
th->encryption=(sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG)
51+
| (sess->tac_multiplex ? TAC_PLUS_SINGLE_CONNECT_FLAG : 0);
5152

5253
/* make session_id from pseudo-random number */
5354
if (!cont_session) {

libtac/lib/session.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ tac_session_alloc_extra(unsigned n)
3636
sess->tac_timeout = 5;
3737
sess->tac_secret = NULL;
3838
sess->tac_session_id = magic();
39-
sess->tac_encryption = false;
39+
sess->tac_encryption = sess->tac_multiplex = false;
4040
sess->tac_priv_lvl = TAC_PLUS_PRIV_LVL_MIN;
4141
sess->tac_authen_service = TAC_PLUS_AUTHEN_SVC_PPP;
4242
sess->tac_authen_method = TAC_PLUS_AUTHEN_METH_TACACSPLUS;
@@ -80,6 +80,12 @@ tac_session_set_timeout(struct tac_session *sess, unsigned timeout)
8080
sess->tac_timeout = timeout;
8181
}
8282

83+
void
84+
tac_session_set_multiplex(struct tac_session *sess, bool multiplex)
85+
{
86+
sess->tac_multiplex = multiplex;
87+
}
88+
8389
void
8490
tac_session_set_response(struct tac_session *sess, response_cb_t cb)
8591
{

libtac/lib/wrappers.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,25 @@ tac_event_loop_global_shutdown(void)
9999
#endif
100100
}
101101

102+
void tac_session_reset_timeouts(struct tac_session *sess, bool on)
103+
{
104+
struct timeval tv = { sess->tac_timeout, 0 };
105+
106+
TACDEBUG(LOG_DEBUG, "session %p reset_timeouts %u %s", sess, sess->tac_timeout, (on ? "on" : "off"));
107+
108+
if (!sess->bufev)
109+
return;
110+
111+
/* nothing will be enabled if we haven't yet connected... */
112+
if (bufferevent_get_enabled(sess->bufev) == 0)
113+
return;
114+
115+
if (on)
116+
bufferevent_set_timeouts(sess->bufev, &tv, &tv);
117+
else
118+
bufferevent_set_timeouts(sess->bufev, NULL, NULL);
119+
}
120+
102121
static void eventcb(struct bufferevent *bev, short events, void *ptr)
103122
{
104123
struct cb_ctx *ctx = (struct cb_ctx *)ptr;
@@ -125,6 +144,8 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr)
125144
if (sess->oob_cb) {
126145
if (events & BEV_EVENT_CONNECTED) {
127146
TACDEBUG(LOG_DEBUG, "session %p connected", sess);
147+
/* change for setup timeout to read/write timeout values */
148+
tac_session_reset_timeouts(sess, true);
128149
(sess->oob_cb)(sess, &sess->context, CONNECTED);
129150
}
130151
if (events & BEV_EVENT_ERROR) {
@@ -214,10 +235,13 @@ static void readcb(struct bufferevent *bev, void *ptr)
214235
/* copy out... */
215236
i = evbuffer_remove(evbuf, pkt, length);
216237

217-
if (i < 0 || (unsigned) i != n)
218-
TACDEBUG(LOG_DEBUG, "%s: evbuffer_remove want %ld got %d", __FUNCTION__, n, i);
238+
if (i < 0 || (unsigned) i != length)
239+
TACDEBUG(LOG_DEBUG, "%s: evbuffer_remove want %u got %d", __FUNCTION__, length, i);
219240

220-
tac_parse_pkt(ctx->sess, ctx, pkt, length);
241+
/* turn off timeouts */
242+
tac_session_reset_timeouts(sess, false);
243+
244+
tac_parse_pkt(sess, ctx, pkt, ((i > 0) ? i : 0));
221245

222246
free(pkt);
223247
}
@@ -292,6 +316,9 @@ tac_authen_send_ev(struct tac_session *sess,
292316
/* generate the packet */
293317
tac_authen_send_pkt(sess, user, pass, tty, r_addr, action, &pkt, &pkt_total);
294318

319+
/* if reusing connection, reset timeouts */
320+
tac_session_reset_timeouts(sess, true);
321+
295322
/*
296323
* make evbuffer wrap around our packet, and call cleanup (free)
297324
* when done
@@ -328,6 +355,9 @@ tac_author_send_ev(struct tac_session *sess,
328355
/* generate the packet */
329356
tac_author_send_pkt(sess, user, tty, r_addr, attr, &pkt, &pkt_total);
330357

358+
/* if reusing connection, reset timeouts */
359+
tac_session_reset_timeouts(sess, true);
360+
331361
/*
332362
* make evbuffer wrap around our packet, and call cleanup (free)
333363
* when done
@@ -364,6 +394,9 @@ tac_acct_send_ev(struct tac_session *sess,
364394
/* generate the packet */
365395
tac_acct_send_pkt(sess, type, user, tty, r_addr, attr, &pkt, &pkt_total);
366396

397+
/* if reusing connection, reset timeouts */
398+
tac_session_reset_timeouts(sess, true);
399+
367400
/*
368401
* make evbuffer wrap around our packet, and call cleanup (free)
369402
* when done
@@ -397,6 +430,9 @@ tac_cont_send_ev(struct tac_session *sess, const char *pass) {
397430
/* generate the packet */
398431
tac_cont_send_pkt(sess, pass, &pkt, &pkt_total);
399432

433+
/* if reusing connection, reset timeouts */
434+
tac_session_reset_timeouts(sess, true);
435+
400436
/*
401437
* make evbuffer wrap around our packet, and call cleanup (free)
402438
* when done

tacc.c

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -281,29 +281,31 @@ int main(int argc, char **argv) {
281281

282282
sess = tac_session_alloc();
283283

284+
ret = tac_connect_single(sess, tac_server, NULL, 60);
285+
if (ret < 0) {
286+
if (!quiet)
287+
printf("Error connecting to TACACS+ server: %m\n");
288+
exit(EXIT_ERR);
289+
}
290+
291+
tac_session_set_secret(sess, tac_secret);
284292
tac_session_set_authen_type(sess, tac_get_authen_type(tac_login));
285293

294+
tac_session_set_multiplex(sess, true);
295+
286296
if (do_authen)
287297
authenticate(tac_server, tac_secret, user, pass, tty, remote_addr);
288298

299+
/* we no longer need the password in our address space */
300+
bzero(pass, strlen(pass));
301+
pass = NULL;
302+
289303
if (do_author) {
290304
/* authorize user */
291305
struct tac_attrib *attr = NULL;
292306
tac_add_attrib(&attr, "service", service);
293307
tac_add_attrib(&attr, "protocol", protocol);
294308

295-
tac_session_new_session_id(sess);
296-
tac_session_reset_seq(sess);
297-
298-
ret = tac_connect_single(sess, tac_server, NULL, 60);
299-
if (ret < 0) {
300-
if (!quiet)
301-
printf("Error connecting to TACACS+ server: %m\n");
302-
exit(EXIT_ERR);
303-
}
304-
305-
tac_session_set_secret(sess, tac_secret);
306-
307309
tac_author_send(sess, user, tty, remote_addr, attr);
308310

309311
tac_author_read(sess, &arep);
@@ -320,10 +322,6 @@ int main(int argc, char **argv) {
320322
tac_free_attrib(&attr);
321323
}
322324

323-
/* we no longer need the password in our address space */
324-
bzero(pass, strlen(pass));
325-
pass = NULL;
326-
327325
if (do_account) {
328326
/* start accounting */
329327
struct tac_attrib *attr = NULL;
@@ -335,18 +333,6 @@ int main(int argc, char **argv) {
335333
tac_add_attrib(&attr, "service", service);
336334
tac_add_attrib(&attr, "protocol", protocol);
337335

338-
tac_session_new_session_id(sess);
339-
tac_session_reset_seq(sess);
340-
341-
ret = tac_connect_single(sess, tac_server, NULL, 60);
342-
if (ret < 0) {
343-
if (!quiet)
344-
printf("Error connecting to TACACS+ server: %m\n");
345-
exit(EXIT_ERR);
346-
}
347-
348-
tac_session_set_secret(sess, tac_secret);
349-
350336
tac_acct_send(sess, TAC_PLUS_ACCT_FLAG_START, user, tty, remote_addr,
351337
attr);
352338

@@ -426,18 +412,6 @@ int main(int argc, char **argv) {
426412
sprintf(buf, "%hu", task_id);
427413
tac_add_attrib(&attr, "task_id", buf);
428414

429-
tac_session_new_session_id(sess);
430-
tac_session_reset_seq(sess);
431-
432-
ret = tac_connect_single(sess, tac_server, NULL, 60);
433-
if (ret < 0) {
434-
if (!quiet)
435-
printf("Error connecting to TACACS+ server: %m\n");
436-
exit(EXIT_ERR);
437-
}
438-
439-
tac_session_set_secret(sess, tac_secret);
440-
441415
tac_acct_send(sess, TAC_PLUS_ACCT_FLAG_STOP, user, tty, remote_addr,
442416
attr);
443417
ret = tac_acct_read(sess, &arep);
@@ -448,8 +422,6 @@ int main(int argc, char **argv) {
448422
} else if (!login_mode && !quiet)
449423
printf("Accounting: STOP OK\n");
450424

451-
tac_close(sess);
452-
453425
tac_free_attrib(&attr);
454426
}
455427

@@ -520,8 +492,6 @@ void authenticate(const struct addrinfo *tac_server, const char *tac_secret,
520492
if (!quiet)
521493
printf("Authentication OK\n");
522494
syslog(LOG_INFO, "authentication OK for %s", user);
523-
524-
tac_close(sess);
525495
}
526496

527497
void showusage(char *progname) {

0 commit comments

Comments
 (0)