diff options
Diffstat (limited to 'debian')
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | debian/control | 22 | ||||
-rw-r--r-- | debian/gbp.conf | 3 | ||||
-rw-r--r-- | debian/libtac-dev.install | 2 | ||||
-rw-r--r-- | debian/libtac3.install (renamed from debian/libtac1.install) | 0 | ||||
-rw-r--r-- | debian/patches/connect_timeout_socket_leak.patch | 34 | ||||
-rw-r--r-- | debian/patches/read_timeout.patch | 170 | ||||
-rw-r--r-- | debian/patches/series | 8 | ||||
-rw-r--r-- | debian/patches/tac_add_attrib_pair_arg_cnt_overflow.patch | 47 | ||||
-rw-r--r-- | debian/patches/tac_add_attrib_pair_strlen_overflow.patch | 57 | ||||
-rw-r--r-- | debian/patches/tac_add_attrib_return_error.patch | 101 | ||||
-rw-r--r-- | debian/patches/tac_add_attrib_truncate.patch | 76 | ||||
-rw-r--r-- | debian/patches/tac_connect_set_dscp.patch | 51 | ||||
-rw-r--r-- | debian/patches/tac_connect_single_individual-timeout.patch | 69 | ||||
-rwxr-xr-x | debian/rules | 4 |
15 files changed, 642 insertions, 8 deletions
diff --git a/debian/changelog b/debian/changelog index 5ba2e14..1f80157 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libpam-tacplus (1.3.9-0vyatta12) unstable; urgency=medium + + * DANOS import master + + -- Vyatta Package Maintainers <DL-vyatta-help@att.com> Wed, 13 Nov 2019 11:34:29 +0000 + libpam-tacplus (1.3.8-2) unstable; urgency=low * Added postinst and prerm scripts for pam-auth-update. Closes: #739274 diff --git a/debian/control b/debian/control index 6dde527..73ac3d4 100644 --- a/debian/control +++ b/debian/control @@ -1,30 +1,40 @@ Source: libpam-tacplus Section: admin Priority: extra -Maintainer: Jeroen Nijhof <jeroen@jeroennijhof.nl> -Build-Depends: debhelper (>= 9), libpam-dev, dh-autoreconf, autoconf-archive +Maintainer: Vyatta Package Maintainers <DL-vyatta-help@att.com> +Build-Depends: debhelper (>= 9), libpam-dev, dh-autoreconf, autoconf-archive, + libevent-dev Standards-Version: 3.9.5 Homepage: https://github.com/jeroennijhof/pam_tacplus Package: libpam-tacplus Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-runtime, libtac1 +Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-runtime, libtac3 Description: PAM module for using TACACS+ as an authentication service This PAM module support authentication, authorization (account management) and accounting (session management) performed using TACACS+ protocol designed by Cisco. -Package: libtac1 +Package: libtac3 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: TACACS+ protocol library - This library implemenents the fundamentls of the TACACS+ protocol and supports + This library implemenents the fundamentals of the TACACS+ protocol and supports authentication, authorization (account management) and accounting (session management). Package: libtac-dev Section: libdevel Architecture: any -Depends: ${misc:Depends}, libtac1 (= ${binary:Version}), libc6-dev|libc-dev +Depends: ${misc:Depends}, libtac3 (= ${binary:Version}), libevent-dev, + libc6-dev|libc-dev Description: Development files for TACACS+ protocol library Contains C header files and development files for libtac, a TACACS+ protocol implementation. + +Package: libpam-tacplus-dbg +Architecture: any +Section: debug +Priority: extra +Depends: ${misc:Depends}, libtac3 (= ${binary:Version}) +Description: libpam-tacplus and libtac3 debugging symbols + The debugging symbols for libpam-tacplus and libtac3 packages. diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000..aa1e8fe --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,3 @@ +[DEFAULT] +upstream-tree=db09c62ce678dc292a328f7e982dcb8773194fad +#upstream-branch=origin/upstream diff --git a/debian/libtac-dev.install b/debian/libtac-dev.install index 8bad7da..8ee9e2f 100644 --- a/debian/libtac-dev.install +++ b/debian/libtac-dev.install @@ -1,3 +1,3 @@ usr/lib/*/*.so -usr/lib/*/pkgconfig/libtac.pc +usr/lib/*/pkgconfig/libtac*.pc usr/include/ diff --git a/debian/libtac1.install b/debian/libtac3.install index 3de3b10..3de3b10 100644 --- a/debian/libtac1.install +++ b/debian/libtac3.install diff --git a/debian/patches/connect_timeout_socket_leak.patch b/debian/patches/connect_timeout_socket_leak.patch new file mode 100644 index 0000000..95500a7 --- /dev/null +++ b/debian/patches/connect_timeout_socket_leak.patch @@ -0,0 +1,34 @@ +--- a/libtac/lib/connect.c ++++ b/libtac/lib/connect.c +@@ -136,6 +136,7 @@ + + /* timeout */ + if ( rc == 0 ) { ++ close(fd); + return LIBTAC_STATUS_CONN_TIMEOUT; + } + +@@ -143,6 +144,7 @@ + if ( rc < 0 ) { + TACSYSLOG((LOG_ERR,\ + "%s: connection failed with %s: %m", __FUNCTION__, ip)) ++ close(fd); + return LIBTAC_STATUS_CONN_ERR; + } + +@@ -151,6 +153,7 @@ + if(getpeername(fd, (struct sockaddr*)&addr, &len) == -1) { + TACSYSLOG((LOG_ERR,\ + "%s: connection failed with %s: %m", __FUNCTION__, ip)) ++ close(fd); + return LIBTAC_STATUS_CONN_ERR; + } + +@@ -158,6 +161,7 @@ + if(fcntl(fd, F_SETFL, flags) == -1) { + TACSYSLOG((LOG_ERR, "%s: cannot restore socket flags: %m",\ + __FUNCTION__)) ++ close(fd); + return LIBTAC_STATUS_CONN_ERR; + } + diff --git a/debian/patches/read_timeout.patch b/debian/patches/read_timeout.patch new file mode 100644 index 0000000..4962e3e --- /dev/null +++ b/debian/patches/read_timeout.patch @@ -0,0 +1,170 @@ +--- a/libtac/include/libtac.h ++++ b/libtac/include/libtac.h +@@ -131,6 +131,7 @@ + extern int tac_timeout; + + void tac_set_dscp(uint8_t val); ++void tac_enable_readtimeout(int enable); + int tac_connect(struct addrinfo **, char **, int); + int tac_connect_single(struct addrinfo *, const char *, struct addrinfo *, int); + char *tac_ntop(const struct sockaddr *); +@@ -138,6 +139,7 @@ + int tac_authen_send(int, const char *, char *, char *, + char *); + int tac_authen_read(int); ++int tac_authen_read_timeout(int, int); + int tac_cont_send(int, char *); + HDR *_tac_req_header(u_char, int); + void _tac_crypt(u_char *, HDR *, int); +@@ -148,6 +150,7 @@ + int tac_acct_send(int, int, const char *, char *, char *, + struct tac_attrib *); + int tac_acct_read(int, struct areply *); ++int tac_acct_read_timeout(int, struct areply *, int); + void *xcalloc(size_t, size_t); + void *xrealloc(void *, size_t); + char *xstrcpy(char *, const char *, size_t); +@@ -155,6 +158,7 @@ + int tac_author_send(int, const char *, char *, char *, + struct tac_attrib *); + int tac_author_read(int, struct areply *); ++int tac_author_read_timeout(int, struct areply *, int); + int tac_add_attrib_pair(struct tac_attrib **, char *, char, + char *); + int tac_add_attrib_truncate(struct tac_attrib **attr, char *name, char *value); +--- a/libtac/lib/acct_r.c ++++ b/libtac/lib/acct_r.c +@@ -32,7 +32,7 @@ + * 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_timeout(int fd, struct areply *re, int timeout) { + HDR th; + struct acct_reply *tb = NULL; + int len_from_header, r, len_from_body; +@@ -42,9 +42,9 @@ + re->msg = NULL; + + if (tac_readtimeout_enable && +- tac_read_wait(fd,tac_timeout*1000, TAC_PLUS_HDR_SIZE,&timeleft) < 0 ) { ++ tac_read_wait(fd,timeout*1000, TAC_PLUS_HDR_SIZE,&timeleft) < 0 ) { + TACSYSLOG((LOG_ERR,\ +- "%s: reply timeout after %d secs", __FUNCTION__, tac_timeout)) ++ "%s: reply timeout after %d secs", __FUNCTION__, timeout)) + re->msg = xstrdup(acct_syserr_msg); + re->status = LIBTAC_STATUS_READ_TIMEOUT; + free(tb); +@@ -80,7 +80,7 @@ + if (tac_readtimeout_enable && + tac_read_wait(fd,timeleft,len_from_header,NULL) < 0 ) { + TACSYSLOG((LOG_ERR,\ +- "%s: reply timeout after %d secs", __FUNCTION__, tac_timeout)) ++ "%s: reply timeout after %d secs", __FUNCTION__, timeout)) + re->msg = xstrdup(acct_syserr_msg); + re->status = LIBTAC_STATUS_READ_TIMEOUT; + free(tb); +@@ -156,3 +156,7 @@ + free(tb); + return re->status; + } ++ ++int tac_acct_read(int fd, struct areply *re) { ++ return tac_acct_read_timeout(fd, re, tac_timeout); ++} +--- a/libtac/lib/authen_r.c ++++ b/libtac/lib/authen_r.c +@@ -34,7 +34,7 @@ + * LIBTAC_STATUS_PROTOCOL_ERR + * >= 0 : server response, see TAC_PLUS_AUTHEN_STATUS_... + */ +-int tac_authen_read(int fd) { ++int tac_authen_read_timeout(int fd, int timeout) { + HDR th; + struct authen_reply *tb = NULL; + int len_from_header, r, len_from_body; +@@ -44,9 +44,9 @@ + + /* read the reply header */ + if (tac_readtimeout_enable && +- tac_read_wait(fd,tac_timeout*1000,TAC_PLUS_HDR_SIZE,&timeleft) < 0 ) { ++ tac_read_wait(fd,timeout*1000,TAC_PLUS_HDR_SIZE,&timeleft) < 0 ) { + TACSYSLOG((LOG_ERR,\ +- "%s: reply timeout after %d secs", __FUNCTION__, tac_timeout)) ++ "%s: reply timeout after %d secs", __FUNCTION__, timeout)) + status=LIBTAC_STATUS_READ_TIMEOUT; + free(tb); + return status; +@@ -77,7 +77,7 @@ + if (tac_readtimeout_enable && + tac_read_wait(fd,timeleft,len_from_header,NULL) < 0 ) { + TACSYSLOG((LOG_ERR,\ +- "%s: reply timeout after %d secs", __FUNCTION__, tac_timeout)) ++ "%s: reply timeout after %d secs", __FUNCTION__, timeout)) + status=LIBTAC_STATUS_READ_TIMEOUT; + } + r = read(fd, tb, len_from_header); +@@ -136,3 +136,7 @@ + free(tb); + return status; + } /* tac_authen_read */ ++ ++int tac_authen_read(int fd) { ++ return tac_authen_read_timeout(fd, tac_timeout); ++} +--- a/libtac/lib/author_r.c ++++ b/libtac/lib/author_r.c +@@ -38,7 +38,8 @@ + * LIBTAC_STATUS_PROTOCOL_ERR + * >= 0 : server response, see TAC_PLUS_AUTHOR_STATUS_... + */ +-int tac_author_read(int fd, struct areply *re) { ++ ++int tac_author_read_timeout(int fd, struct areply *re, int timeout) { + HDR th; + struct author_reply *tb = NULL; + int len_from_header, r, len_from_body; +@@ -49,10 +50,10 @@ + + bzero(re, sizeof(struct areply)); + if (tac_readtimeout_enable && +- tac_read_wait(fd,tac_timeout*1000,TAC_PLUS_HDR_SIZE,&timeleft) < 0 ) { ++ tac_read_wait(fd,timeout*1000,TAC_PLUS_HDR_SIZE,&timeleft) < 0 ) { + + TACSYSLOG((LOG_ERR,\ +- "%s: reply timeout after %d secs", __FUNCTION__, tac_timeout)) ++ "%s: reply timeout after %d secs", __FUNCTION__, timeout)) + re->msg = xstrdup(author_syserr_msg); + re->status = LIBTAC_STATUS_READ_TIMEOUT; + free(tb); +@@ -88,7 +89,7 @@ + tac_read_wait(fd,timeleft,len_from_header,NULL) < 0 ) { + + TACSYSLOG((LOG_ERR,\ +- "%s: reply timeout after %d secs", __FUNCTION__, tac_timeout)) ++ "%s: reply timeout after %d secs", __FUNCTION__, timeout)) + re->msg = xstrdup(author_syserr_msg); + re->status = LIBTAC_STATUS_READ_TIMEOUT; + free(tb); +@@ -240,3 +241,7 @@ + free(tb); + return re->status; + } ++ ++int tac_author_read(int fd, struct areply *re) { ++ return tac_author_read_timeout(fd, re, tac_timeout); ++} +--- a/libtac/lib/connect.c ++++ b/libtac/lib/connect.c +@@ -41,6 +41,11 @@ + tac_dscp = val; + } + ++ ++void tac_enable_readtimeout(int enable) { ++ tac_readtimeout_enable = !!enable; ++} ++ + /* Returns file descriptor of open connection + to the first available server from list passed + in server table. diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..cd7d47b --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,8 @@ +connect_timeout_socket_leak.patch +tac_connect_single_individual-timeout.patch +tac_add_attrib_pair_strlen_overflow.patch +tac_add_attrib_return_error.patch +tac_add_attrib_truncate.patch +tac_add_attrib_pair_arg_cnt_overflow.patch +tac_connect_set_dscp.patch +read_timeout.patch diff --git a/debian/patches/tac_add_attrib_pair_arg_cnt_overflow.patch b/debian/patches/tac_add_attrib_pair_arg_cnt_overflow.patch new file mode 100644 index 0000000..55686ba --- /dev/null +++ b/debian/patches/tac_add_attrib_pair_arg_cnt_overflow.patch @@ -0,0 +1,47 @@ +--- a/libtac/include/libtac.h ++++ b/libtac/include/libtac.h +@@ -67,6 +67,7 @@ + #endif + + #define TAC_PLUS_ATTRIB_MAX_LEN 255 ++#define TAC_PLUS_ATTRIB_MAX_CNT 255 + + struct tac_attrib { + char *attr; +@@ -105,6 +106,7 @@ + #define LIBTAC_STATUS_CONN_TIMEOUT -8 + #define LIBTAC_STATUS_CONN_ERR -9 + #define LIBTAC_STATUS_ATTRIB_TOO_LONG -10 ++#define LIBTAC_STATUS_ATTRIB_TOO_MANY -11 + + /* Runtime flags */ + +--- a/libtac/lib/attrib.c ++++ b/libtac/lib/attrib.c +@@ -31,6 +31,7 @@ + struct tac_attrib *a; + size_t l1 = strlen(name); + size_t l2; ++ unsigned int attr_cnt = 0; + int total_len; + + if (l1 > TAC_PLUS_ATTRIB_MAX_LEN-1) { /* take sep into account */ +@@ -69,8 +70,17 @@ + } else { + /* find the last allocated block */ + a = *attr; +- while(a->next != NULL) ++ while(a->next != NULL) { + a = a->next; /* a holds last allocated block */ ++ attr_cnt++; ++ } ++ ++ if (attr_cnt+1 >= TAC_PLUS_ATTRIB_MAX_CNT) { /* take new attrib into account */ ++ TACSYSLOG((LOG_WARNING,\ ++ "%s: Maximum number of attributes exceeded, skipping",\ ++ __FUNCTION__)) ++ return LIBTAC_STATUS_ATTRIB_TOO_MANY; ++ } + + a->next = (struct tac_attrib *) xcalloc(1, sizeof(struct tac_attrib)); + a = a->next; /* set current block pointer to the new one */ diff --git a/debian/patches/tac_add_attrib_pair_strlen_overflow.patch b/debian/patches/tac_add_attrib_pair_strlen_overflow.patch new file mode 100644 index 0000000..8f7632b --- /dev/null +++ b/debian/patches/tac_add_attrib_pair_strlen_overflow.patch @@ -0,0 +1,57 @@ +--- a/libtac/include/libtac.h ++++ b/libtac/include/libtac.h +@@ -66,6 +66,8 @@ extern int logmsg __P((int, const char*, + typedef unsigned int u_int32_t; + #endif + ++#define TAC_PLUS_ATTRIB_MAX_LEN 255 ++ + struct tac_attrib { + char *attr; + u_char attr_len; +--- a/libtac/lib/attrib.c ++++ b/libtac/lib/attrib.c +@@ -29,24 +29,34 @@ void tac_add_attrib(struct tac_attrib ** + + void tac_add_attrib_pair(struct tac_attrib **attr, char *name, char sep, char *value) { + struct tac_attrib *a; +- u_char l1 = (u_char) strlen(name); +- u_char l2; ++ size_t l1 = strlen(name); ++ size_t l2; + int total_len; +- ++ ++ if (l1 > TAC_PLUS_ATTRIB_MAX_LEN-1) { /* take sep into account */ ++ TACSYSLOG((LOG_WARNING,\ ++ "%s: attribute `%s' exceeds max. %d characters, skipping",\ ++ __FUNCTION__, name, TAC_PLUS_ATTRIB_MAX_LEN-1)) ++ return; ++ } ++ ++ total_len = l1 + 1; /* "name" + "sep" */ ++ + if (value == NULL) { + l2 = 0; + } else { +- l2 = (u_char) strlen(value); ++ l2 = strlen(value); + } +- total_len = l1 + l2 + 1; /* "name" + "=" + "value" */ + +- if (total_len > 255) { ++ if (l2 > TAC_PLUS_ATTRIB_MAX_LEN-total_len) { + TACSYSLOG((LOG_WARNING,\ +- "%s: attribute `%s' total length exceeds 255 characters, skipping",\ +- __FUNCTION__, name)) ++ "%s: attribute `%s' total length exceeds %d characters, skipping",\ ++ __FUNCTION__, name, TAC_PLUS_ATTRIB_MAX_LEN)) + return; + } +- ++ ++ total_len += l2; ++ + /* initialize the list if application passed us a null pointer */ + if(*attr == NULL) { + *attr = (struct tac_attrib *) xcalloc(1, sizeof(struct tac_attrib)); diff --git a/debian/patches/tac_add_attrib_return_error.patch b/debian/patches/tac_add_attrib_return_error.patch new file mode 100644 index 0000000..a886698 --- /dev/null +++ b/debian/patches/tac_add_attrib_return_error.patch @@ -0,0 +1,101 @@ +--- a/Makefile.am ++++ b/Makefile.am +@@ -41,7 +41,7 @@ libtac/lib/xalloc.c \ + libtac/lib/xalloc.h \ + $(libtac_include_HEADERS) + libtac_la_CFLAGS = $(AM_CFLAGS) -Ilibtac/include +-libtac_la_LDFLAGS = -version-info 1:0:0 -shared ++libtac_la_LDFLAGS = -version-info 3:0:0 -shared + + moduledir = @pamdir@ + module_LTLIBRARIES = pam_tacplus.la +--- a/libtac/include/libtac.h ++++ b/libtac/include/libtac.h +@@ -95,15 +95,16 @@ struct areply { + * all negative, tacplus status codes are >= 0 + */ + +-#define LIBTAC_STATUS_ASSEMBLY_ERR -1 +-#define LIBTAC_STATUS_PROTOCOL_ERR -2 +-#define LIBTAC_STATUS_READ_TIMEOUT -3 +-#define LIBTAC_STATUS_WRITE_TIMEOUT -4 +-#define LIBTAC_STATUS_WRITE_ERR -5 +-#define LIBTAC_STATUS_SHORT_HDR -6 +-#define LIBTAC_STATUS_SHORT_BODY -7 +-#define LIBTAC_STATUS_CONN_TIMEOUT -8 +-#define LIBTAC_STATUS_CONN_ERR -9 ++#define LIBTAC_STATUS_ASSEMBLY_ERR -1 ++#define LIBTAC_STATUS_PROTOCOL_ERR -2 ++#define LIBTAC_STATUS_READ_TIMEOUT -3 ++#define LIBTAC_STATUS_WRITE_TIMEOUT -4 ++#define LIBTAC_STATUS_WRITE_ERR -5 ++#define LIBTAC_STATUS_SHORT_HDR -6 ++#define LIBTAC_STATUS_SHORT_BODY -7 ++#define LIBTAC_STATUS_CONN_TIMEOUT -8 ++#define LIBTAC_STATUS_CONN_ERR -9 ++#define LIBTAC_STATUS_ATTRIB_TOO_LONG -10 + + /* Runtime flags */ + +@@ -138,7 +139,7 @@ int tac_cont_send(int, char *); + HDR *_tac_req_header(u_char, int); + void _tac_crypt(u_char *, HDR *, int); + u_char *_tac_md5_pad(int, HDR *); +-void tac_add_attrib(struct tac_attrib **, char *, char *); ++int tac_add_attrib(struct tac_attrib **, char *, char *); + void tac_free_attrib(struct tac_attrib **); + char *tac_acct_flag2str(int); + int tac_acct_send(int, int, const char *, char *, char *, +@@ -151,7 +152,7 @@ char *_tac_check_header(HDR *, int); + int tac_author_send(int, const char *, char *, char *, + struct tac_attrib *); + int tac_author_read(int, struct areply *); +-void tac_add_attrib_pair(struct tac_attrib **, char *, char, ++int tac_add_attrib_pair(struct tac_attrib **, char *, char, + char *); + int tac_read_wait(int, int, int, int *); + +--- a/libtac/lib/attrib.c ++++ b/libtac/lib/attrib.c +@@ -23,11 +23,11 @@ + #include "libtac.h" + #include "xalloc.h" + +-void tac_add_attrib(struct tac_attrib **attr, char *name, char *value) { +- tac_add_attrib_pair(attr, name, '=', value); ++int tac_add_attrib(struct tac_attrib **attr, char *name, char *value) { ++ return tac_add_attrib_pair(attr, name, '=', value); + } + +-void tac_add_attrib_pair(struct tac_attrib **attr, char *name, char sep, char *value) { ++int tac_add_attrib_pair(struct tac_attrib **attr, char *name, char sep, char *value) { + struct tac_attrib *a; + size_t l1 = strlen(name); + size_t l2; +@@ -37,7 +37,7 @@ void tac_add_attrib_pair(struct tac_attr + TACSYSLOG((LOG_WARNING,\ + "%s: attribute `%s' exceeds max. %d characters, skipping",\ + __FUNCTION__, name, TAC_PLUS_ATTRIB_MAX_LEN-1)) +- return; ++ return LIBTAC_STATUS_ATTRIB_TOO_LONG; + } + + total_len = l1 + 1; /* "name" + "sep" */ +@@ -52,7 +52,7 @@ void tac_add_attrib_pair(struct tac_attr + TACSYSLOG((LOG_WARNING,\ + "%s: attribute `%s' total length exceeds %d characters, skipping",\ + __FUNCTION__, name, TAC_PLUS_ATTRIB_MAX_LEN)) +- return; ++ return LIBTAC_STATUS_ATTRIB_TOO_LONG; + } + + total_len += l2; +@@ -85,6 +85,8 @@ void tac_add_attrib_pair(struct tac_attr + } + *(a->attr+total_len) = '\0'; /* add 0 for safety */ + a->next = NULL; /* make sure it's null */ ++ ++ return 0; + } + + void tac_free_attrib(struct tac_attrib **attr) { diff --git a/debian/patches/tac_add_attrib_truncate.patch b/debian/patches/tac_add_attrib_truncate.patch new file mode 100644 index 0000000..ee64fff --- /dev/null +++ b/debian/patches/tac_add_attrib_truncate.patch @@ -0,0 +1,76 @@ +--- a/libtac/include/libtac.h ++++ b/libtac/include/libtac.h +@@ -154,6 +154,8 @@ int tac_author_send(int, const char *, c + int tac_author_read(int, struct areply *); + int tac_add_attrib_pair(struct tac_attrib **, char *, char, + char *); ++int tac_add_attrib_truncate(struct tac_attrib **attr, char *name, char *value); ++int tac_add_attrib_pair_truncate(struct tac_attrib **attr, char *name, char sep, char *value); + int tac_read_wait(int, int, int, int *); + + /* magic.c */ +--- a/libtac/lib/attrib.c ++++ b/libtac/lib/attrib.c +@@ -20,14 +20,14 @@ + * See `CHANGES' file for revision history. + */ + ++#include <stdbool.h> ++ + #include "libtac.h" + #include "xalloc.h" + +-int tac_add_attrib(struct tac_attrib **attr, char *name, char *value) { +- return tac_add_attrib_pair(attr, name, '=', value); +-} +- +-int tac_add_attrib_pair(struct tac_attrib **attr, char *name, char sep, char *value) { ++static int _tac_add_attrib_pair(struct tac_attrib **attr, char *name, ++ char sep, char *value, bool truncate) ++{ + struct tac_attrib *a; + size_t l1 = strlen(name); + size_t l2; +@@ -49,10 +49,15 @@ int tac_add_attrib_pair(struct tac_attri + } + + if (l2 > TAC_PLUS_ATTRIB_MAX_LEN-total_len) { +- TACSYSLOG((LOG_WARNING,\ +- "%s: attribute `%s' total length exceeds %d characters, skipping",\ +- __FUNCTION__, name, TAC_PLUS_ATTRIB_MAX_LEN)) +- return LIBTAC_STATUS_ATTRIB_TOO_LONG; ++ if (truncate) { ++ l2 = TAC_PLUS_ATTRIB_MAX_LEN-total_len; ++ } ++ else { ++ TACSYSLOG((LOG_WARNING,\ ++ "%s: attribute `%s' total length exceeds %d characters, skipping",\ ++ __FUNCTION__, name, TAC_PLUS_ATTRIB_MAX_LEN)) ++ return LIBTAC_STATUS_ATTRIB_TOO_LONG; ++ } + } + + total_len += l2; +@@ -89,6 +94,22 @@ int tac_add_attrib_pair(struct tac_attri + return 0; + } + ++int tac_add_attrib(struct tac_attrib **attr, char *name, char *value) { ++ return tac_add_attrib_pair(attr, name, '=', value); ++} ++ ++int tac_add_attrib_pair(struct tac_attrib **attr, char *name, char sep, char *value) { ++ return _tac_add_attrib_pair(attr, name, sep, value, false); ++} ++ ++int tac_add_attrib_truncate(struct tac_attrib **attr, char *name, char *value) { ++ return tac_add_attrib_pair_truncate(attr, name, '=', value); ++} ++ ++int tac_add_attrib_pair_truncate(struct tac_attrib **attr, char *name, char sep, char *value) { ++ return _tac_add_attrib_pair(attr, name, sep, value, true); ++} ++ + void tac_free_attrib(struct tac_attrib **attr) { + struct tac_attrib *a; + struct tac_attrib *b; diff --git a/debian/patches/tac_connect_set_dscp.patch b/debian/patches/tac_connect_set_dscp.patch new file mode 100644 index 0000000..3eea978 --- /dev/null +++ b/debian/patches/tac_connect_set_dscp.patch @@ -0,0 +1,51 @@ +--- a/libtac/include/libtac.h ++++ b/libtac/include/libtac.h +@@ -130,6 +130,7 @@ extern int tac_readtimeout_enable; + /* connect.c */ + extern int tac_timeout; + ++void tac_set_dscp(uint8_t val); + int tac_connect(struct addrinfo **, char **, int); + int tac_connect_single(struct addrinfo *, const char *, struct addrinfo *, int); + char *tac_ntop(const struct sockaddr *); +--- a/libtac/lib/connect.c ++++ b/libtac/lib/connect.c +@@ -34,6 +34,13 @@ + /* Pointer to TACACS+ connection timeout */ + int tac_timeout = 5; + ++unsigned int tac_dscp = 0; ++ ++void tac_set_dscp(uint8_t val) { ++ /* Value should already be left shifted by 2 bits (those are used for ECN) */ ++ tac_dscp = val; ++} ++ + /* Returns file descriptor of open connection + to the first available server from list passed + in server table. +@@ -91,6 +98,24 @@ int tac_connect_single(struct addrinfo * + return LIBTAC_STATUS_CONN_ERR; + } + ++ switch (server->ai_family) { ++ case AF_INET: ++ rc = setsockopt(fd, IPPROTO_IP, IP_TOS, &tac_dscp, sizeof tac_dscp); ++ break; ++ case AF_INET6: ++ rc = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tac_dscp, sizeof tac_dscp); ++ break; ++ default: ++ rc = 0; ++ } ++ if (rc < 0) { ++ TACSYSLOG((LOG_ERR,"%s: setsockopt(%s) error: %s", __FUNCTION__, ++ server->ai_family == AF_INET ? "IP_TOS" : "IPV6_TCLASS", ++ strerror(errno))) ++ close(fd); ++ return LIBTAC_STATUS_CONN_ERR; ++ } ++ + /* get flags for restoration later */ + flags = fcntl(fd, F_GETFL, 0); + diff --git a/debian/patches/tac_connect_single_individual-timeout.patch b/debian/patches/tac_connect_single_individual-timeout.patch new file mode 100644 index 0000000..3df2617 --- /dev/null +++ b/debian/patches/tac_connect_single_individual-timeout.patch @@ -0,0 +1,69 @@ +--- a/libtac/include/libtac.h ++++ b/libtac/include/libtac.h +@@ -126,7 +126,7 @@ + extern int tac_timeout; + + int tac_connect(struct addrinfo **, char **, int); +-int tac_connect_single(struct addrinfo *, const char *, struct addrinfo *); ++int tac_connect_single(struct addrinfo *, const char *, struct addrinfo *, int); + char *tac_ntop(const struct sockaddr *); + + int tac_authen_send(int, const char *, char *, char *, +--- a/libtac/lib/connect.c ++++ b/libtac/lib/connect.c +@@ -50,7 +50,7 @@ + TACSYSLOG((LOG_ERR, "%s: no TACACS+ servers defined", __FUNCTION__)) + } else { + for ( tries = 0; tries < servers; tries++ ) { +- if((fd=tac_connect_single(server[tries], key[tries], NULL)) >= 0 ) { ++ if((fd=tac_connect_single(server[tries], key[tries], NULL, tac_timeout)) >= 0 ) { + /* tac_secret was set in tac_connect_single on success */ + break; + } +@@ -67,7 +67,7 @@ + * >= 0 : valid fd + * < 0 : error status code, see LIBTAC_STATUS_... + */ +-int tac_connect_single(struct addrinfo *server, const char *key, struct addrinfo *srcaddr) { ++int tac_connect_single(struct addrinfo *server, const char *key, struct addrinfo *srcaddr, int timeout) { + int retval = LIBTAC_STATUS_CONN_ERR; /* default retval */ + int fd = -1; + int flags, rc; +@@ -128,7 +128,7 @@ + FD_SET(fd, &writefds); + + /* set timeout seconds */ +- tv.tv_sec = tac_timeout; ++ tv.tv_sec = timeout; + tv.tv_usec = 0; + + /* check if socket is ready for read and write */ +--- a/pam_tacplus.c ++++ b/pam_tacplus.c +@@ -169,7 +169,7 @@ + + status = PAM_SESSION_ERR; + for(srv_i = 0; srv_i < tac_srv_no; srv_i++) { +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL); ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout); + if (tac_fd < 0) { + _pam_log(LOG_WARNING, "%s: error sending %s (fd)", + __FUNCTION__, typemsg); +@@ -266,7 +266,7 @@ + if (ctrl & PAM_TAC_DEBUG) + syslog(LOG_DEBUG, "%s: trying srv %d", __FUNCTION__, srv_i ); + +- tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL); ++ tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key, NULL, tac_timeout); + if (tac_fd < 0) { + _pam_log(LOG_ERR, "connection failed srv %d: %m", srv_i); + continue; +@@ -487,7 +487,7 @@ + if(tac_protocol != NULL && tac_protocol[0] != '\0') + tac_add_attrib(&attr, "protocol", tac_protocol); + +- tac_fd = tac_connect_single(active_server.addr, active_server.key, NULL); ++ tac_fd = tac_connect_single(active_server.addr, active_server.key, NULL, tac_timeout); + if(tac_fd < 0) { + _pam_log (LOG_ERR, "TACACS+ server unavailable"); + if(arep.msg != NULL) diff --git a/debian/rules b/debian/rules index 0fa1f54..82b372d 100755 --- a/debian/rules +++ b/debian/rules @@ -17,10 +17,12 @@ override_dh_clean: dh_clean override_dh_auto_configure: - dh_auto_configure -- --enable-pamdir=/lib/$(DEB_HOST_MULTIARCH)/security --docdir=/usr/share/doc/libpam-tacplus + dh_auto_configure -- --enable-pamdir=/lib/$(DEB_HOST_MULTIARCH)/security --docdir=/usr/share/doc/libpam-tacplus --with-libevent override_dh_install: mkdir -p debian/libpam-tacplus/usr/share/pam-configs cp debian/tacplus debian/libpam-tacplus/usr/share/pam-configs/ dh_install +override_dh_strip: + dh_strip --dbg-package=libpam-tacplus-dbg |