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

Commit

Permalink
Introduce session objects to contain per-session parameters
Browse files Browse the repository at this point in the history
If you're connecting to multiple servers simultaneously, then
per-server parameters can't be globals.  Move them into a
session container.

Note: this obviously has API and ABI compatibility implications.
  • Loading branch information
pprindeville committed Dec 8, 2016
1 parent cd269df commit dc81c83
Show file tree
Hide file tree
Showing 17 changed files with 380 additions and 216 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ libtac/lib/read_wait.c \
libtac/lib/version.c \
libtac/lib/xalloc.c \
libtac/lib/xalloc.h \
libtac/lib/session.c \
$(libtac_include_HEADERS)
if MY_MD5
libtac_la_SOURCES += \
Expand Down
91 changes: 56 additions & 35 deletions libtac/include/libtac.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,33 @@ extern int tac_ver_major;
extern int tac_ver_minor;
extern int tac_ver_patch;

/* header.c */
extern int session_id;
extern int tac_encryption;
extern const char *tac_secret;
extern char tac_login[64];
extern int tac_priv_lvl;
extern int tac_authen_method;
extern int tac_authen_service;
/* session.c */
struct tac_session {
unsigned tac_timeout;
const char *tac_secret;
uint32_t tac_session_id;
bool tac_encryption;
uint8_t tac_priv_lvl;
uint8_t tac_authen_method;
uint8_t tac_authen_service;
uint8_t tac_authen_type;
uint8_t seq_no;

/* user defined stuff */
uint8_t user_data[0];
};

struct tac_session *tac_session_alloc(void);
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_new_session_id(struct tac_session *);
void tac_session_reset_seq(struct tac_session *);
void *tac_session_get_user_data(struct tac_session *);
void tac_session_free(struct tac_session *);

/* header.c */
extern int tac_debug_enable;
extern int tac_readtimeout_enable;

Expand All @@ -154,44 +172,46 @@ static inline void *tac_hdr_to_body(HDR *th)
return (void *)((u_char *)th + TAC_PLUS_HDR_SIZE);
}

HDR *_tac_req_header(u_char, int);
HDR *_tac_req_header(struct tac_session *, u_char, bool);

/* connect.c */
extern int tac_timeout;

int tac_connect(struct addrinfo **, char **, int);
int tac_connect_single(const struct addrinfo *, const char *, struct addrinfo *,
int);
int tac_connect(struct addrinfo **, unsigned);
int tac_connect_single(const struct addrinfo *, struct addrinfo *, int);
char *tac_ntop(const struct sockaddr *);

/* authen_s.c */
u_char tac_get_authen_type(const char *);
void tac_authen_send_pkt(const char *, const char *, const char *,
const char *, u_char, u_char **, unsigned *);
int tac_authen_send(int, const char *, const char *, const char *,
const char *, u_char);
const char *tag_get_authen_string(uint8_t);

void tac_authen_send_pkt(struct tac_session *,
const char *, const char *, const char *, const char *, u_char,
u_char **, unsigned *);
int tac_authen_send(struct tac_session *, int,
const char *, const char *, const char *, const char *, u_char);

/* authen_r.c */
int tac_authen_parse(struct areply *, u_char *, unsigned);
int tac_authen_read(int, struct areply *);
int tac_authen_parse(struct tac_session *, struct areply *, u_char *, unsigned);
int tac_authen_read(struct tac_session *, int, struct areply *);

/* cont_s.c */
void tac_cont_send_pkt(const char *, uint8_t, u_char **, unsigned *);
int tac_cont_send_seq(int, const char *, uint8_t);
#define tac_cont_send(fd, pass) tac_cont_send_seq((fd), (pass), 3)
void tac_cont_send_pkt(struct tac_session *, const char *,
u_char **, unsigned *);
int tac_cont_send(struct tac_session *, int, const char *);

/* crypt.c */
void _tac_crypt(u_char *, const HDR *);
void _tac_crypt(const struct tac_session *, u_char *, const HDR *);

/* author_r.c */
int tac_author_parse(u_char *, unsigned, struct areply *);
int tac_author_read(int, struct areply *);
int tac_author_parse(struct tac_session *, u_char *, unsigned, struct areply *);
int tac_author_read(struct tac_session *, int, struct areply *);

/* author_s.c */
void tac_author_send_pkt(const char *, const char *, const char *,
struct tac_attrib *, u_char **, unsigned *);
int tac_author_send(int, const char *, const char *, const char *,
struct tac_attrib *);
void tac_author_send_pkt(struct tac_session *, const char *, const char *,
const char *, struct tac_attrib *, u_char **, unsigned *);
int tac_author_send(struct tac_session *, int, const char *, const char *,
const char *, struct tac_attrib *);

/* attrib.c */
void tac_add_attrib(struct tac_attrib **, char *, char *);
Expand All @@ -200,22 +220,23 @@ void tac_free_attrib(struct tac_attrib **);

/* acct_s.c */
char *tac_acct_flag2str(u_char);
void tac_acct_send_pkt(u_char, const char *, const char *, const char *,
struct tac_attrib *, u_char **, unsigned *);
int tac_acct_send(int, u_char, const char *, const char *, const char *,
struct tac_attrib *);
void tac_acct_send_pkt(struct tac_session *, u_char, const char *,
const char *, const char *, struct tac_attrib *, u_char **, unsigned *);
int tac_acct_send(struct tac_session *, int, u_char, const char *,
const char *, const char *, struct tac_attrib *);

/* acct_r.c */
int tac_acct_parse(u_char *, unsigned, struct areply *);
int tac_acct_read(int, struct areply *);
int tac_acct_parse(struct tac_session *, u_char *, unsigned,
struct areply *);
int tac_acct_read(struct tac_session *, int, struct areply *);

/* xalloc.c */
void *xcalloc(size_t, size_t);
void *xrealloc(void *, size_t);
char *xstrcpy(char *, const char *, size_t);

/* hdr_check.c */
char *_tac_check_header(HDR *, uint8_t);
char *_tac_check_header(struct tac_session *, HDR *, uint8_t);

/* magic.c */
u_int32_t magic(void);
Expand Down
11 changes: 6 additions & 5 deletions libtac/lib/acct_r.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
* LIBTAC_STATUS_PROTOCOL_ERR
* >= 0 : server response, see TAC_PLUS_AUTHEN_STATUS_...
*/
int tac_acct_parse(u_char *pkt, unsigned pkt_total, struct areply *re) {
int tac_acct_parse(struct tac_session *sess, u_char *pkt, unsigned pkt_total,
struct areply *re) {
HDR *th = (HDR *)pkt;
struct acct_reply *tb = NULL;
size_t ulen_from_header, len_from_body;
Expand All @@ -42,7 +43,7 @@ int tac_acct_parse(u_char *pkt, unsigned pkt_total, struct areply *re) {
re->msg = re->data = NULL;

/* check the reply fields in header */
msg = _tac_check_header(th, TAC_PLUS_ACCT);
msg = _tac_check_header(sess, th, TAC_PLUS_ACCT);
if(msg != NULL) {
re->msg = xstrdup(msg);
re->status = LIBTAC_STATUS_PROTOCOL_ERR;
Expand All @@ -66,7 +67,7 @@ int tac_acct_parse(u_char *pkt, unsigned pkt_total, struct areply *re) {
}

/* decrypt the body */
_tac_crypt((u_char *) tb, th);
_tac_crypt(sess, (u_char *) tb, th);

/* Convert network byte order to host byte order */
tb->msg_len = ntohs(tb->msg_len);
Expand Down Expand Up @@ -136,7 +137,7 @@ int tac_acct_parse(u_char *pkt, unsigned pkt_total, struct areply *re) {
* LIBTAC_STATUS_PROTOCOL_ERR
* >= 0 : server response, see TAC_PLUS_AUTHEN_STATUS_...
*/
int tac_acct_read(int fd, struct areply *re) {
int tac_acct_read(struct tac_session *sess, int fd, struct areply *re) {
HDR *th;
struct acct_reply *tb = NULL;
size_t ulen_from_header;
Expand Down Expand Up @@ -207,7 +208,7 @@ int tac_acct_read(int fd, struct areply *re) {
}

/* now parse remaining packet fields */
status = tac_acct_parse((u_char *)th,
status = tac_acct_parse(sess, (u_char *)th,
TAC_PLUS_HDR_SIZE + ulen_from_header, re);

/* all useful data has been copied out */
Expand Down
32 changes: 16 additions & 16 deletions libtac/lib/acct_s.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ char *tac_acct_flag2str(u_char flag) {
}

/* allocate and format an Accounting Start packet */
void tac_acct_send_pkt(u_char type, const char *user, const char *tty,
const char *r_addr, struct tac_attrib *attr,
u_char **_pkt, unsigned *_len) {
void tac_acct_send_pkt(struct tac_session *sess, u_char type,
const char *user, const char *tty, const char *r_addr,
struct tac_attrib *attr, u_char **_pkt, unsigned *_len) {

HDR *th;
struct acct *tb;
Expand All @@ -52,7 +52,7 @@ void tac_acct_send_pkt(u_char type, const char *user, const char *tty,

TACDEBUG(LOG_DEBUG, "%s: user '%s', tty '%s', rem_addr '%s', encrypt: %s, type: %s", \
__FUNCTION__, user, tty, r_addr, \
(tac_encryption) ? "yes" : "no", \
(sess->tac_encryption) ? "yes" : "no", \
tac_acct_flag2str(type));

/*
Expand Down Expand Up @@ -82,19 +82,18 @@ void tac_acct_send_pkt(u_char type, const char *user, const char *tty,
/* tacacs header */
th->version = TAC_PLUS_VER_0;
th->type = TAC_PLUS_ACCT;
th->seq_no = 1;
th->encryption = tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
session_id = magic();
th->session_id = htonl(session_id);
th->seq_no = ++sess->seq_no;
th->encryption = sess->tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
th->session_id = htonl(sess->tac_session_id);
th->datalength = htonl(pkt_total - TAC_PLUS_HDR_SIZE);

/* fixed part of tacacs body */
tb = tac_hdr_to_body(th);
tb->flags = type;
tb->authen_method = tac_authen_method;
tb->priv_lvl = tac_priv_lvl;
tb->authen_type = tac_get_authen_type(tac_login);
tb->authen_service = tac_authen_service;
tb->authen_method = sess->tac_authen_method;
tb->priv_lvl = sess->tac_priv_lvl;
tb->authen_type = sess->tac_authen_type;
tb->authen_service = sess->tac_authen_service;
tb->user_len = user_len;
tb->port_len = port_len;
tb->r_addr_len = r_addr_len;
Expand Down Expand Up @@ -122,7 +121,7 @@ void tac_acct_send_pkt(u_char type, const char *user, const char *tty,
assert(pkt_len == pkt_total);

/* encrypt packet body */
_tac_crypt((u_char *)tb, th);
_tac_crypt(sess, (u_char *)tb, th);

*_pkt = pkt;
*_len = pkt_total;
Expand All @@ -136,15 +135,16 @@ void tac_acct_send_pkt(u_char type, const char *user, const char *tty,
* LIBTAC_STATUS_WRITE_TIMEOUT (pending impl)
* LIBTAC_STATUS_ASSEMBLY_ERR (pending impl)
*/
int tac_acct_send(int fd, u_char type, const char *user, const char *tty,
const char *r_addr, struct tac_attrib *attr) {
int tac_acct_send(struct tac_session *sess, int fd,
u_char type, const char *user,
const char *tty, const char *r_addr, struct tac_attrib *attr) {

u_char *pkt = NULL;
unsigned pkt_total = 0;
int w, ret = 0;

/* generate the packet */
tac_acct_send_pkt(type, user, tty, r_addr, attr, &pkt, &pkt_total);
tac_acct_send_pkt(sess, type, user, tty, r_addr, attr, &pkt, &pkt_total);

/* write packet */
w = write(fd, pkt, pkt_total);
Expand Down
14 changes: 7 additions & 7 deletions libtac/lib/authen_r.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
* LIBTAC_STATUS_PROTOCOL_ERR
* >= 0 : server response, see TAC_PLUS_AUTHEN_STATUS_...
*/
int tac_authen_parse(struct areply *re, u_char *pkt, unsigned pkt_total) {
int tac_authen_parse(struct tac_session *sess, struct areply *re,
u_char *pkt, unsigned pkt_total) {

HDR *th = (HDR *)pkt;
struct authen_reply *tb = NULL;
size_t len_from_header, len_from_body;
Expand All @@ -41,15 +43,13 @@ int tac_authen_parse(struct areply *re, u_char *pkt, unsigned pkt_total) {
memset(re, 0, sizeof(*re));

/* check the reply fields in header */
msg = _tac_check_header(th, TAC_PLUS_AUTHEN);
msg = _tac_check_header(sess, th, TAC_PLUS_AUTHEN);
if (msg != NULL) {
re->msg = xstrdup(msg);
re->status = LIBTAC_STATUS_PROTOCOL_ERR;
return re->status;
}

re->seq_no = th->seq_no;

len_from_header = ntohl(th->datalength);

tb = tac_hdr_to_body(th);
Expand All @@ -64,7 +64,7 @@ int tac_authen_parse(struct areply *re, u_char *pkt, unsigned pkt_total) {
}

/* decrypt the body */
_tac_crypt((u_char *) tb, th);
_tac_crypt(sess, (u_char *) tb, th);

/* Convert network byte order to host byte order */
tb->msg_len = ntohs(tb->msg_len);
Expand Down Expand Up @@ -140,7 +140,7 @@ int tac_authen_parse(struct areply *re, u_char *pkt, unsigned pkt_total) {
* LIBTAC_STATUS_PROTOCOL_ERR
* >= 0 : server response, see TAC_PLUS_AUTHEN_STATUS_...
*/
int tac_authen_read(int fd, struct areply *re) {
int tac_authen_read(struct tac_session *sess, int fd, struct areply *re) {
HDR *th;
struct authen_reply *tb = NULL;
size_t len_from_header;
Expand Down Expand Up @@ -204,7 +204,7 @@ int tac_authen_read(int fd, struct areply *re) {
}

/* now parse remaining packet fields */
status = tac_authen_parse(re, (u_char *)th, TAC_PLUS_HDR_SIZE + len_from_header);
status = tac_authen_parse(sess, re, (u_char *)th, TAC_PLUS_HDR_SIZE + len_from_header);

/* all useful data has been copied out */
free(th);
Expand Down
Loading

0 comments on commit dc81c83

Please sign in to comment.