From mark.thomas at corp.aol.com Tue Jun 10 14:59:03 2008 From: mark.thomas at corp.aol.com (Mark Ellzey Thomas) Date: Tue, 10 Jun 2008 10:59:03 -0400 Subject: [tac_plus] accounting + syslog Message-ID: <20080610145903.GB1347@corp.aol.com> Greetings all, We have recently needed the support of sysloging accounting data here. Attached is a patch for the F4.0.4.15 branch that allows for this feature. A new configuration option has been added: "accounting syslog" This will use the global syslog facility and log to the priority LOG_INFO. Thank you for the project. -------------- next part -------------- Index: acct.c =================================================================== RCS file: /cvs/netsec-dev/tacacs/acct.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- acct.c 4 Jun 2008 14:49:54 -0000 1.3 +++ acct.c 9 Jun 2008 14:53:37 -0000 1.4 @@ -1,5 +1,5 @@ /* - * $Id: acct.c,v 1.3 2008/06/04 14:49:54 jathan Exp $ + * $Id: acct.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ * * Copyright (c) 1995-1998 by Cisco systems, Inc. * @@ -145,7 +145,11 @@ if (wtmpfile) { errors = do_wtmp(&rec); } else { - errors = do_acct(&rec); + if (session.acctfile != NULL) + errors = do_acct(&rec); + if (session.acct_syslog) + errors = do_syslog_acct(&rec); + } if (errors) { Index: config.c =================================================================== RCS file: /cvs/netsec-dev/tacacs/config.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- config.c 4 Jun 2008 14:49:55 -0000 1.3 +++ config.c 9 Jun 2008 14:53:37 -0000 1.4 @@ -1,5 +1,5 @@ /* - * $Id: config.c,v 1.3 2008/06/04 14:49:55 jathan Exp $ + * $Id: config.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ * * Copyright (c) 1995-1998 by Cisco systems, Inc. * @@ -749,11 +749,21 @@ case S_accounting: sym_get(); - parse(S_file); - parse(S_separator); - if (session.acctfile) - free(session.acctfile); - session.acctfile = tac_strdup(sym_buf); + + switch(sym_code) { + case S_file: + parse(S_file); + parse(S_separator); + if (session.acctfile) + free(session.acctfile); + session.acctfile = tac_strdup(sym_buf); + break; + + case S_syslog: + session.acct_syslog = 1; + break; + } + sym_get(); continue; Index: do_acct.c =================================================================== RCS file: /cvs/netsec-dev/tacacs/do_acct.c,v retrieving revision 1.3 retrieving revision 1.5 diff -u -r1.3 -r1.5 --- do_acct.c 4 Jun 2008 14:49:55 -0000 1.3 +++ do_acct.c 9 Jun 2008 18:46:21 -0000 1.5 @@ -1,5 +1,5 @@ /* - * $Id: do_acct.c,v 1.3 2008/06/04 14:49:55 jathan Exp $ + * $Id: do_acct.c,v 1.5 2008/06/09 18:46:21 mthomas Exp $ * * Copyright (c) 1995-1998 by Cisco systems, Inc. * @@ -64,6 +64,66 @@ return(0); } +int do_syslog_acct(struct acct_rec *rec) +{ + char *acct_type = "unknown"; + char *cmdbuf; + int written, i; + size_t bufsize; + + bufsize = 1024; + + cmdbuf = tac_malloc(bufsize); + bzero(cmdbuf, bufsize); + written = 0; + + switch(rec->acct_type) + { + case ACCT_TYPE_UPDATE: + acct_type = "update"; + break; + case ACCT_TYPE_START: + acct_type = "start"; + break; + case ACCT_TYPE_STOP: + acct_type = "stop"; + break; + } + + for (i = 0; i < rec->num_args; i++) + { + /* possible 4 spaces and and a null terminator == 5 */ + if ((strlen(rec->args[i]) + written + 5) > bufsize) + { + cmdbuf = tac_realloc(cmdbuf, strlen(rec->args[i]) + written + 5); + bufsize += strlen(rec->args[i]) + written + 5; + } + + strncat(cmdbuf, rec->args[i], strlen(rec->args[i])); + written += strlen(rec->args[i]); + + if (i < (rec->num_args-1)) + { + strncat(cmdbuf, " ", 4); + written += 4; + } + } + + syslog(LOG_INFO, "%s %s %s %s %s %s", + ((rec->identity->NAS_name) && rec->identity->NAS_name[0]) ? + rec->identity->NAS_name:"unknown", + ((rec->identity->username) && rec->identity->username[0]) ? + rec->identity->username:"unknown", + ((rec->identity->NAS_port) && rec->identity->NAS_port[0]) ? + rec->identity->NAS_port:"unknown", + ((rec->identity->NAC_address) && rec->identity->NAC_address[0]) ? + rec->identity->NAC_address:"unknown", acct_type, cmdbuf); + + free(cmdbuf); + + return 0; +} + int do_acct(struct acct_rec *rec) { Index: parse.c =================================================================== RCS file: /cvs/netsec-dev/tacacs/parse.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- parse.c 4 Jun 2008 14:49:55 -0000 1.3 +++ parse.c 9 Jun 2008 14:53:37 -0000 1.4 @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.3 2008/06/04 14:49:55 jathan Exp $ + * $Id: parse.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ * * Copyright (c) 1995-1998 by Cisco systems, Inc. * @@ -117,6 +117,7 @@ #ifdef HAVE_PAM declare("PAM", S_pam); #endif + declare("syslog", S_syslog); } /* Return a keyword code if a keyword is recognized. 0 otherwise */ @@ -256,5 +257,7 @@ case S_pam: return("PAM"); #endif + case S_syslog: + return("syslog"); } } Index: parse.h =================================================================== RCS file: /cvs/netsec-dev/tacacs/parse.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- parse.h 4 Jun 2008 14:49:55 -0000 1.3 +++ parse.h 9 Jun 2008 14:53:37 -0000 1.4 @@ -1,5 +1,5 @@ /* - * $Id: parse.h,v 1.3 2008/06/04 14:49:55 jathan Exp $ + * $Id: parse.h,v 1.4 2008/06/09 14:53:37 mthomas Exp $ * * Copyright (c) 1995-1998 by Cisco systems, Inc. * @@ -86,3 +86,4 @@ #ifdef HAVE_PAM # define S_pam 49 #endif +#define S_syslog 50 Index: tac_plus.c =================================================================== RCS file: /cvs/netsec-dev/tacacs/tac_plus.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- tac_plus.c 4 Jun 2008 14:49:55 -0000 1.3 +++ tac_plus.c 9 Jun 2008 14:53:37 -0000 1.4 @@ -1,5 +1,5 @@ /* - * $Id: tac_plus.c,v 1.3 2008/06/04 14:49:55 jathan Exp $ + * $Id: tac_plus.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ * * TACACS_PLUS daemon suitable for using on Un*x systems. * @@ -101,7 +101,8 @@ report(LOG_NOTICE, "Reading config"); - session.acctfile = tac_strdup(TACPLUS_ACCTFILE); + session.acctfile = NULL; + //session.acctfile = tac_strdup(TACPLUS_ACCTFILE); if (!session.cfgfile) { report(LOG_ERR, "no config file specified"); Index: tac_plus.h =================================================================== RCS file: /cvs/netsec-dev/tacacs/tac_plus.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- tac_plus.h 4 Jun 2008 14:49:55 -0000 1.3 +++ tac_plus.h 9 Jun 2008 14:53:37 -0000 1.4 @@ -1,5 +1,5 @@ /* - * $Id: tac_plus.h,v 1.3 2008/06/04 14:49:55 jathan Exp $ + * $Id: tac_plus.h,v 1.4 2008/06/09 14:53:37 mthomas Exp $ * * Copyright (c) 1995-1998 by Cisco systems, Inc. * @@ -335,6 +335,7 @@ char *acctfile; /* name of accounting file */ char port[NAS_PORT_MAX_LEN+1]; /* For error reporting */ u_char version; /* version of last packet read */ + u_char acct_syslog; /* syslog the accounting data */ }; extern struct session session; /* the session */ @@ -633,6 +634,7 @@ char *tac_realloc(); /* do_acct.c */ +int do_syslog_acct(struct acct_rec *); int do_acct(struct acct_rec *); int do_wtmp(struct acct_rec *); From nschrenk at depthfirst.net Fri Jun 13 20:36:21 2008 From: nschrenk at depthfirst.net (Nathan Schrenk) Date: Fri, 13 Jun 2008 13:36:21 -0700 Subject: [tac_plus] Patch for tac_plus to fix the -G option Message-ID: <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> Attached is a patch against version F4.0.4.15 of the tacacs+ package that fixes support for the -G command-line option. My understanding of -G is that it is supposed to keep tac_plus running in the foreground: no forking, no detaching from the tty, etc. The code in the F4.0.4.15 distribution does not do this: it forks and detaches. Thanks, Nathan Schrenk -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: tacacs+-F4.0.4.15-foreground.patch.txt Url: http://www.shrubbery.net/pipermail/tac_plus/attachments/20080613/df90d121/attachment.txt From kissg at ssg.ki.iif.hu Mon Jun 16 16:51:23 2008 From: kissg at ssg.ki.iif.hu (Kiss Gabor (Bitman)) Date: Mon, 16 Jun 2008 18:51:23 +0200 (CEST) Subject: [tac_plus] Re: Patch for tac_plus to fix the -G option In-Reply-To: <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> References: <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> Message-ID: Dear Nathan, > Attached is a patch against version F4.0.4.15 of the tacacs+ package > that fixes support for the -G command-line option. My understanding > of -G is that it is supposed to keep tac_plus running in the > foreground: no forking, no detaching from the tty, etc. The code in > the F4.0.4.15 distribution does not do this: it forks and detaches. Eeerrrr... tac_plus(8) writes: -g Single threaded mode. The daemon will only accept and service a single connection at a time without forking and without closing file descriptors. All log messages appear on standard output. -G Remain in the foreground, but not single-threaded nor logging to the tty. So as far as I can understand -G never promised to log on tty. Maybe you wanted to use -g. How did you figure out if it "detached" from control terminal or not? Did process accept SIGINT (^C) from keyboard or not? Cheers Gabor From heas at shrubbery.net Mon Jun 16 18:51:20 2008 From: heas at shrubbery.net (john heasley) Date: Mon, 16 Jun 2008 11:51:20 -0700 Subject: [tac_plus] Re: Patch for tac_plus to fix the -G option In-Reply-To: References: <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> Message-ID: <20080616185120.GI23913@shrubbery.net> Mon, Jun 16, 2008 at 06:51:23PM +0200, Kiss Gabor (Bitman): > Dear Nathan, > > > Attached is a patch against version F4.0.4.15 of the tacacs+ package > > that fixes support for the -G command-line option. My understanding > > of -G is that it is supposed to keep tac_plus running in the > > foreground: no forking, no detaching from the tty, etc. The code in > > the F4.0.4.15 distribution does not do this: it forks and detaches. > > Eeerrrr... tac_plus(8) writes: > > -g Single threaded mode. The daemon will only accept and service a > single connection at a time without forking and without closing > file descriptors. All log messages appear on standard output. > > -G Remain in the foreground, but not single-threaded nor logging to > the tty. > > So as far as I can understand -G never promised to log on tty. > Maybe you wanted to use -g. It (the daemon with -g, IIRC) used to log to the tty, which I tought was silly since some stuff would go to the syslog and others to the tty, which may it a pain to correlate. I changed that long ago. > How did you figure out if it "detached" from control terminal or not? > Did process accept SIGINT (^C) from keyboard or not? > > Cheers > > Gabor > _______________________________________________ > tac_plus mailing list > tac_plus at shrubbery.net > http://www.shrubbery.net/mailman/listinfo.cgi/tac_plus From nschrenk at depthfirst.net Mon Jun 16 17:04:42 2008 From: nschrenk at depthfirst.net (Nathan Schrenk) Date: Mon, 16 Jun 2008 10:04:42 -0700 Subject: [tac_plus] Re: Patch for tac_plus to fix the -G option In-Reply-To: References: <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> Message-ID: <6121a88b0806161004t38cef4g6a9e29d7d8b8b6e@mail.gmail.com> On Mon, Jun 16, 2008 at 9:51 AM, Kiss Gabor (Bitman) wrote: > Dear Nathan, > >> Attached is a patch against version F4.0.4.15 of the tacacs+ package >> that fixes support for the -G command-line option. My understanding >> of -G is that it is supposed to keep tac_plus running in the >> foreground: no forking, no detaching from the tty, etc. The code in >> the F4.0.4.15 distribution does not do this: it forks and detaches. > > Eeerrrr... tac_plus(8) writes: > > -g Single threaded mode. The daemon will only accept and service a > single connection at a time without forking and without closing > file descriptors. All log messages appear on standard output. > > -G Remain in the foreground, but not single-threaded nor logging to > the tty. > > So as far as I can understand -G never promised to log on tty. > Maybe you wanted to use -g. > > How did you figure out if it "detached" from control terminal or not? > Did process accept SIGINT (^C) from keyboard or not? -G might not have promised to keep logging to the tty, but it certainly is not remaining in the foreground as implemented in version 4.0.4.15 of the code. Try it yourself -- running "tac_plus -G" from an interactive shell will fork into the background and control will return to the shell immediately. Without -G tac_plus fork()s twice, and with -G it still forks once and the parent process exits. Maybe my patch isn't correct, because it skips closing tty, but I think the part of my patch that avoids the second fork when -G is specified is correct. Nathan From kissg at ssg.ki.iif.hu Mon Jun 16 19:27:44 2008 From: kissg at ssg.ki.iif.hu (Kiss Gabor (Bitman)) Date: Mon, 16 Jun 2008 21:27:44 +0200 (CEST) Subject: [tac_plus] Re: Patch for tac_plus to fix the -G option In-Reply-To: <6121a88b0806161004t38cef4g6a9e29d7d8b8b6e@mail.gmail.com> References: <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> <6121a88b0806161004t38cef4g6a9e29d7d8b8b6e@mail.gmail.com> Message-ID: > -G might not have promised to keep logging to the tty, but it > certainly is not remaining in the foreground as implemented in version > 4.0.4.15 of the code. Try it yourself -- running "tac_plus -G" from > an interactive shell will fork into the background and control will Uhmmm... You are right. Gabor From heas at shrubbery.net Mon Jun 16 19:37:12 2008 From: heas at shrubbery.net (john heasley) Date: Mon, 16 Jun 2008 12:37:12 -0700 Subject: [tac_plus] Re: Patch for tac_plus to fix the -G option In-Reply-To: <20080616193449.2D7DB8655B@guelah.shrubbery.net> <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> References: <20080616193449.2D7DB8655B@guelah.shrubbery.net> <6121a88b0806131336t686e48a8nb93036456027a685@mail.gmail.com> Message-ID: <20080616193712.GJ23913@shrubbery.net> Fri, Jun 13, 2008 at 01:36:21PM -0700, Nathan Schrenk: > Attached is a patch against version F4.0.4.15 of the tacacs+ package > that fixes support for the -G command-line option. My understanding > of -G is that it is supposed to keep tac_plus running in the > foreground: no forking, no detaching from the tty, etc. The code in > the F4.0.4.15 distribution does not do this: it forks and detaches. I've applied the following variation of your patch. @@ -41,7 +41,7 @@ int port; /* port we're listening on */ int console; /* write all syslog messages to console */ int parse_only; /* exit after verbose parsing */ -int childpid = 1; /* child pid, global for unlink(PIDFILE) */ +int childpid; /* child pid, global for unlink(PIDFILE) */ int single; /* single thread (for debugging) */ int opt_G; /* foreground */ int wtmpfd; /* for wtmp file logging */ @@ -392,7 +392,6 @@ if (debug) report(LOG_DEBUG, "Backgrounded"); - } #ifndef REAPCHILD #if SETPGRP_VOID @@ -430,19 +429,17 @@ signal(SIGCHLD, SIG_IGN); #endif /* REAPCHILD */ - /* - * after forking to disassociate; make sure we know we're the mother - * so that we remove our pid file upon exit in die(). - */ - childpid = 1; - - closelog(); /* some systems require this */ + closelog(); /* some systems require this */ - for (c = 0; c < getdtablesize(); c++) - (void) close(c); + for (c = 0; c < getdtablesize(); c++) + (void) close(c); - /* make sure we can still log to syslog now we've closed everything */ - open_logfile(); + /* + * make sure we can still log to syslog now that we have closed + * everything + */ + open_logfile(); + } } ostream = NULL; @@ -482,16 +479,23 @@ if (c >= PIDSZ) { pidfilebuf[PIDSZ - 1] = '\0'; report(LOG_ERR, "pid filename truncated: %s", pidfilebuf); + childpid = 0; + } else { + /* write process id to pidfile */ + if ((fp = fopen(pidfilebuf, "w")) != NULL) { + fprintf(fp, "%d\n", (int) getpid()); + fclose(fp); + /* + * After forking to disassociate; make sure we know we're the + * mother so that we remove our pid file upon exit in die(). + */ + childpid = 1; + } else { + report(LOG_ERR, "Cannot write pid to %s %s", pidfilebuf, + strerror(errno)); + childpid = 0; + } } - - /* write process id to pidfile */ - if ((fp = fopen(pidfilebuf, "w")) != NULL) { - fprintf(fp, "%d\n", (int) getpid()); - fclose(fp); - } else - report(LOG_ERR, "Cannot write pid to %s %s", - pidfilebuf, strerror(errno)); - #ifdef TACPLUS_GROUPID if (setgid(TACPLUS_GROUPID)) report(LOG_ERR, "Cannot set group id to %d %s", From kdclaver at xpert-tic.com Wed Jun 18 19:41:01 2008 From: kdclaver at xpert-tic.com (Dominique Claver KOUAME) Date: Wed, 18 Jun 2008 19:41:01 +0000 Subject: [tac_plus] Looking for Tacacs+ server howto Message-ID: <20080618194101.bym24122isgoskww@www.xpert-tic.com> Dear sirs, I want to congratulate you for your very best product TACACS+ Server. I've deployed it and I'm looking for a tutorial to use it and make advanced configuration. Thanks more for your reply. Best regards -- Dominique Claver KOUAME Cabinet XPERT-TIC 25 BP 1464 Abidjan 25 +225-45802315 www.xpert-tic.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.shrubbery.net/pipermail/tac_plus/attachments/20080618/3493f71e/attachment.html From mark.thomas at corp.aol.com Mon Jun 23 19:11:54 2008 From: mark.thomas at corp.aol.com (Mark Ellzey Thomas) Date: Mon, 23 Jun 2008 15:11:54 -0400 Subject: [tac_plus] tac_plus AFL (Auth Fail Lock) Message-ID: <20080623191154.GG3872@corp.aol.com> Greetings all, Recently we have had the need for tac_plus to temporarily disable user accounts based on the number of authentication failures the user has had in a defined window of time. Attached is a patch against F4.0.4.15 with the previously submitted acct+syslog patch (if this is a problem please inform me and I will patch against the base F4.0.4.15 tree). The following global configuration parameter has been added: auth-fail-lock $int1 $int2 $int3 Where $int1 is the number of authentication failures Where $int2 is the window (in seconds) in which to watch for auth fails Where $int3 is the number of seconds to disable the user. An example would be: # Watch for 10 authentication failures within 60 seconds, if triggered # disable user for 120 seconds. auth-fail-lock 10 60 120 The tac_plus daemon will log when a trigger is hit, and when the account has been re-enabled: Jun 23 14:51:36 192.168.0.1 tac_plus[27731]: User mark has been disabled for 120 seconds Jun 23 14:53:46 192.168.0.1 tac_plus[28244]: Re-enabling account: mark Unfortunately since tac_plus is a forked architecture, I had to achieve persistence of data via IPC. I understand that some may be weary of this mechanism so they can turn the feature off at compile time by passing the --disable-afl flag to configure. Thanks for the project! -- Mark E. Thomas - AOL Network Security -------------- next part -------------- diff -Naur ../tacacs_orig/authen.c ./authen.c --- ../tacacs_orig/authen.c 2008-06-18 18:24:09.000000000 -0400 +++ ./authen.c 2008-06-19 18:24:01.000000000 -0400 @@ -326,10 +326,21 @@ return; } - if ((*func) (datap)) { +#ifdef AFL + if ((session.afl_cfg) && + cfg_is_user_disabled(datap->NAS_id->username) == 1) + datap->status = TAC_PLUS_AUTHEN_STATUS_FAIL; + else if ((*func) (datap)) { send_authen_error("Unexpected authentication function failure"); return; } +#else + if((*func) (datap)) + { + send_authen_error("Unexpected authentication function failure"); + return; + } +#endif switch (datap->status) { @@ -359,6 +370,10 @@ case TAC_PLUS_AUTHEN_STATUS_FAIL: /* An invalid user/password combination */ +#ifdef AFL + if(session.afl_cfg) + cfg_increment_failure(datap->NAS_id->username); +#endif send_authen_reply(TAC_PLUS_AUTHEN_STATUS_FAIL, datap->server_msg, datap->server_msg ? strlen(datap->server_msg) : 0, diff -Naur ../tacacs_orig/config.c ./config.c --- ../tacacs_orig/config.c 2008-06-18 18:24:09.000000000 -0400 +++ ./config.c 2008-06-22 13:38:15.000000000 -0400 @@ -113,6 +113,11 @@ static int no_user_dflt = 0; /* default if user doesn't exist */ static char *authen_default = NULL; /* top level authentication default */ static char *nopasswd_str = "nopassword"; +#ifdef AFL +static unsigned int user_count = 0; /* the number of users in the config */ +static key_t failed_key; /* the shm key for AFL */ +#endif + /* * A host definition structure. @@ -176,6 +181,9 @@ #ifdef MAXSESS int maxsess; /* Max sessions/user */ #endif /* MAXSESS */ +#ifdef AFL + int shm_offset; /* where the user is stored in shared memory */ +#endif }; typedef struct user USER; @@ -214,6 +222,16 @@ typedef union hash HASH; +#ifdef AFL +struct failed_node { + char username[65]; + unsigned int failures; + time_t first_failure; + time_t locked_time; /* the time the lock was set */ + char disabled; +}; +#endif + void *grouptable[HASH_TAB_SIZE];/* Table of group declarations */ void *usertable[HASH_TAB_SIZE]; /* Table of user declarations */ #ifdef ACLS @@ -521,6 +539,14 @@ session.acctfile = NULL; } +#ifdef AFL + if (session.afl_cfg) { + cfg_destroy_failure_shm(); + free(session.afl_cfg); + session.afl_cfg = NULL; + } +#endif + #ifdef ACLS /* clean the acltable */ for (i = 0; i < HASH_TAB_SIZE; i++) { @@ -746,7 +772,23 @@ switch (sym_code) { case S_eof: return(0); - +#ifdef AFL + case S_auth_fail_lock: + /* faillock a b c + * a = number of failures + * b = in this many seconds + * c = lock for this many seconds */ + session.afl_cfg = (struct afl_cfg *)tac_malloc(sizeof(struct afl_cfg)); + bzero(session.afl_cfg, sizeof(struct afl_cfg)); + sym_get(); + session.afl_cfg->num_failures = atoi(sym_buf); + sym_get(); + session.afl_cfg->seconds = atoi(sym_buf); + sym_get(); + session.afl_cfg->lock_time = atoi(sym_buf); + sym_get(); + break; +#endif case S_accounting: sym_get(); @@ -2388,6 +2430,306 @@ return(authen_default); } +#ifdef AFL +static unsigned int fetch_user_count(void) +{ + int i; + unsigned int count; + USER *entry; + + count = 0; + + for (i=0; i < HASH_TAB_SIZE; i++) + { + entry = (USER *)usertable[i]; + while (entry) + { + count++; + entry = entry->hash; + } + } + return count; +} + +/* + * Create a user-table in shared memory for AFL. + */ +void cfg_create_failure_shm(const char *path, int id) +{ + unsigned int shm_sz; + int offset; + int i, shmid; + char *shm = NULL; + + user_count = shm_sz = offset = 0; + + user_count = fetch_user_count(); + shm_sz = user_count * sizeof(struct failed_node); + + if((failed_key = ftok(path, id))<0) + { + report(LOG_ERR, "ftok unable to create key: %s", + strerror(errno)); + tac_exit(1); + } + + if ((shmid = shmget(failed_key, shm_sz, IPC_CREAT|0666)) < 0) + { + report(LOG_ERR, "shmget unable to get memory: %s", + strerror(errno)); + tac_exit(1); + } + + if ((shm = (char *)shmat(shmid, NULL, 0)) == (char *)-1) + { + report(LOG_ERR, "shmat: %s", strerror(errno)); + tac_exit(1); + } + + /* iterate over all the users and add them a failed_node + * structure to the shared memory */ + for (i=0; i < HASH_TAB_SIZE; i++) + { + struct failed_node *failed_node; + USER *entry = (USER *)usertable[i]; + + while(entry) + { + entry->shm_offset = offset; + failed_node = (struct failed_node *)&shm[offset]; + bzero(failed_node, sizeof(struct failed_node)); + + if (strlen(entry->name) > 64) + { + report(LOG_ERR, "username %s > length of 64", + entry->name); + tac_exit(1); + } + + strncpy(failed_node->username, entry->name, 64); + offset += sizeof(struct failed_node); + + if (offset > user_count * sizeof(struct failed_node)) + { + report(LOG_ERR, "More users than previously allocated"); + tac_exit(1); + } + + entry = entry->hash; + } + } + + /* now create a semaphore for locking */ + if(semget(failed_key, 1, 0666 | IPC_CREAT) < 0) + { + report(LOG_ERR, "Unable to create semaphore: %s", strerror(errno)); + tac_exit(1); + } +} + +char *shm_fetch_and_lock(key_t key, unsigned int sz) +{ + int shmid, semid; + struct sembuf sem[2]; + char *shm = NULL; + + if((semid = semget(key, 1, 0666)) < 0) + { + report(LOG_ERR, "unable to fetch semaphore: %s", strerror(errno)); + tac_exit(1); + } + + sem[0].sem_num = 0; + sem[1].sem_num = 0; + sem[0].sem_flg = SEM_UNDO; + sem[1].sem_flg = SEM_UNDO; + sem[0].sem_op = 0; + sem[1].sem_op = 1; + + semop(semid, sem, 2); + + if((shmid = shmget(key, sz, 0666)) < 0) + { + report(LOG_ERR, "shm_fetchnlock unable to get shmid: %s", + strerror(errno)); + tac_exit(1); + } + + if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) + { + report(LOG_ERR, "shm_fetchnlock Unable to find shm segment: %s", + strerror(errno)); + tac_exit(1); + } + + return shm; +} + +static void shm_unlock(key_t key) +{ + int semid; + struct sembuf sem; + + if ((semid = semget(key, 1, 0666)) < 0) + tac_exit(1); + + sem.sem_num = 0; + sem.sem_flg = SEM_UNDO; + sem.sem_op = -1; + + semop(semid, &sem, 1); +} + +static void destroy_semaphore(key_t key) +{ + int semid; + semid = semget(key, 0, 0666); + semctl(semid, 0, IPC_RMID, NULL); +} + +static void destroy_shm(key_t key) +{ + int shmid; + shmid = shmget(key, 1, 0666); + shmctl(shmid, IPC_RMID, NULL); +} + + +void cfg_destroy_failure_shm(void) +{ + destroy_semaphore(failed_key); + destroy_shm(failed_key); +} + +static int shm_failed_offset(char *username, void *arg) +{ + USER *user; + + if (arg == NULL) + user = (USER *)hash_lookup(usertable, username); + else + user = (USER *)arg; + + return (user ? user->shm_offset:-1); +} + +void cfg_increment_failure(char *username) +{ + USER *user; + int offset; + char *data; + struct failed_node *node; + time_t now; + + user = hash_lookup(usertable, username); + + if (user == NULL) + return; + + if ((offset = shm_failed_offset(username, user)) < 0) + return; + + data = shm_fetch_and_lock(failed_key, + user_count * sizeof(struct failed_node)); + + node = (struct failed_node *)&data[user->shm_offset]; + + if (strcmp(node->username, username) != 0) + { + report(LOG_ERR, "Shared memory has something amiss (%s!=%s)", + node->username, username); + shm_unlock(failed_key); + return; + } + + time(&now); + + if (!node->first_failure) + node->first_failure = now; + + /* determine if this fail has exceeded the number of failures within + * the time window. If it has then lock the account. + */ + if((!node->disabled) && ++node->failures >= session.afl_cfg->num_failures) + { + report(LOG_WARNING, "User %s has been disabled for %d seconds", + username, session.afl_cfg->lock_time); + node->locked_time = now; + node->disabled = 1; + } + + shm_unlock(failed_key); +} + +/* + * Attempt to determine whether a user is locked out or not, + * this function also does timer expiration. + */ +int cfg_is_user_disabled(char *username) +{ + USER *user; + int offset; + char *data; + struct failed_node *node; + int ret = 0; + time_t now; + + user = hash_lookup(usertable, username); + + if (user == NULL) + return -1; + + if ((offset = shm_failed_offset(username, user))<0) + return -1; + + data = shm_fetch_and_lock(failed_key, + user_count * sizeof(struct failed_node)); + + node = (struct failed_node *)&data[user->shm_offset]; + + /* check to make sure what we have is true */ + if (strcmp(node->username, username) != 0) + { + report(LOG_ERR, "Shared memory has something amiss (%s!=%s)", + node->username, username); + shm_unlock(failed_key); + return -1; + } + + ret = node->disabled?1:0; + time(&now); + + if (ret) + { + /* Check locked account expiration. Unlock if expired. */ + if (difftime(now, node->locked_time) > session.afl_cfg->lock_time) + { + report(LOG_WARNING, "Re-enabling account: %s", username); + node->first_failure = 0; + node->disabled = 0; + node->failures = 0; + node->locked_time = 0; + ret = 0; + } + } + else { + /* Check to see if the auth-fail window has expired. */ + if ((node->first_failure) && + difftime(now, node->first_failure) > session.afl_cfg->seconds) + { + report(LOG_INFO,"Resetting failure clock for user: %s\n", username); + node->first_failure = 0; + node->disabled = 0; + node->failures = 0; + node->locked_time = 0; + } + } + + shm_unlock(failed_key); + return ret; +} +#endif /* AFL */ + /* * Return 1 if this user has any ppp services configured. Used for * authorizing ppp/lcp requests diff -Naur ../tacacs_orig/config.h.in ./config.h.in --- ../tacacs_orig/config.h.in 2008-06-18 18:24:09.000000000 -0400 +++ ./config.h.in 2008-06-19 18:05:43.000000000 -0400 @@ -210,5 +210,7 @@ # define socklen_t int #endif +#undef AFL + #endif /* CONFIG_H */ diff -Naur ../tacacs_orig/configure ./configure --- ../tacacs_orig/configure 2008-06-18 18:24:09.000000000 -0400 +++ ./configure 2008-06-19 18:29:11.000000000 -0400 @@ -722,6 +722,7 @@ TACPLUS_LOGFILE PROFLAGS PROFLIBS +AFL TAR INST_PROGS PERLV_PATH @@ -1327,6 +1328,7 @@ --enable-uenable tacacs config per-user enable support (default) --enable-maxsess Enforce a limit on maximum sessions per user --enable-finger finger NAS for number of sessions a user is using + --enable-afl Enable AFL support (default) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -6112,6 +6114,52 @@ +{ echo "$as_me:$LINENO: checking whether to enable AFL support" >&5 +echo $ECHO_N "checking whether to enable AFL support... $ECHO_C" >&6; } + + +# Check whether --enable-afl was given. +if test "${enable_afl+set}" = set; then + enableval=$enable_afl; case "$enable_afl" in + no) + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + use_afl=0 + ;; + yes) + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + cat >>confdefs.h <<\_ACEOF +#define AFL 1 +_ACEOF + + use_afl=1 + ;; + *) + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + cat >>confdefs.h <<\_ACEOF +#define AFL 1 +_ACEOF + + use_afl=1 + ;; + esac +else + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + cat >>confdefs.h <<\_ACEOF +#define AFL 1 +_ACEOF + + use_afl=1 + +fi + + + + + # look for PAM @@ -7953,6 +8001,7 @@ TACPLUS_LOGFILE!$TACPLUS_LOGFILE$ac_delim PROFLAGS!$PROFLAGS$ac_delim PROFLIBS!$PROFLIBS$ac_delim +AFL!$AFL$ac_delim TAR!$TAR$ac_delim INST_PROGS!$INST_PROGS$ac_delim PERLV_PATH!$PERLV_PATH$ac_delim @@ -7961,7 +8010,7 @@ LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 17; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 18; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff -Naur ../tacacs_orig/configure.in ./configure.in --- ../tacacs_orig/configure.in 2008-06-18 18:24:09.000000000 -0400 +++ ./configure.in 2008-06-19 18:29:07.000000000 -0400 @@ -557,6 +557,37 @@ AC_SUBST(PROFLAGS) AC_SUBST(PROFLIBS) +dnl +dnl DISABLE AFL Support (Authentication Failure Locking) +dnl +AC_MSG_CHECKING(whether to enable AFL support) +AH_TEMPLATE(AFL, [define this to disable Authentication Failure Locking support]) +AC_ARG_ENABLE(afl, +[ --enable-afl Enable AFL support (default)], +[ case "$enable_afl" in + no) + AC_MSG_RESULT(no) + use_afl=0 + ;; + yes) + AC_MSG_RESULT(yes) + AC_DEFINE(AFL) + use_afl=1 + ;; + *) + AC_MSG_RESULT(yes) + AC_DEFINE(AFL) + use_afl=1 + ;; + esac ], + AC_MSG_RESULT(yes) + AC_DEFINE(AFL) + use_afl=1 +) +AC_SUBST(AFL) + + + # look for PAM AH_TEMPLATE(HAVE_PAM, [define if your system has libpam]) AC_CHECK_LIB([pam], [pam_start], diff -Naur ../tacacs_orig/parse.c ./parse.c --- ../tacacs_orig/parse.c 2008-06-18 18:24:10.000000000 -0400 +++ ./parse.c 2008-06-19 18:19:00.000000000 -0400 @@ -118,6 +118,9 @@ declare("PAM", S_pam); #endif declare("syslog", S_syslog); +#ifdef AFL + declare("auth-fail-lock", S_auth_fail_lock); +#endif } /* Return a keyword code if a keyword is recognized. 0 otherwise */ diff -Naur ../tacacs_orig/parse.h ./parse.h --- ../tacacs_orig/parse.h 2008-06-18 18:24:10.000000000 -0400 +++ ./parse.h 2008-06-19 18:19:13.000000000 -0400 @@ -87,3 +87,6 @@ # define S_pam 49 #endif #define S_syslog 50 +#ifdef AFL +#define S_auth_fail_lock 51 +#endif diff -Naur ../tacacs_orig/tac_plus.c ./tac_plus.c --- ../tacacs_orig/tac_plus.c 2008-06-18 18:24:10.000000000 -0400 +++ ./tac_plus.c 2008-06-23 14:39:14.000000000 -0400 @@ -90,6 +90,10 @@ report(LOG_NOTICE, "Received signal %d, shutting down", signum); if (childpid > 0) unlink(pidfilebuf); + +#ifdef AFL + cfg_destroy_failure_shm(); +#endif tac_exit(0); } @@ -102,7 +106,9 @@ report(LOG_NOTICE, "Reading config"); session.acctfile = NULL; - //session.acctfile = tac_strdup(TACPLUS_ACCTFILE); +#ifdef AFL + session.afl_cfg = NULL; +#endif if (!session.cfgfile) { report(LOG_ERR, "no config file specified"); @@ -115,6 +121,11 @@ tac_exit(1); } +#ifdef AFL + if(session.afl_cfg) + cfg_create_failure_shm(session.cfgfile, 'A'); +#endif + initialised++; report(LOG_NOTICE, "Version %s Initialized %d", version, initialised); @@ -326,6 +337,9 @@ signal(SIGUSR1, handler); signal(SIGHUP, handler); signal(SIGTERM, die); +#ifdef AFL + signal(SIGINT, die); +#endif signal(SIGPIPE, SIG_IGN); if (parse_only) @@ -863,6 +877,9 @@ #if __STDC__ fprintf(stdout, "__STDC__\n"); #endif +#if AFL + fprintf(stdout, "AFL\n"); +#endif return; } diff -Naur ../tacacs_orig/tac_plus.h ./tac_plus.h --- ../tacacs_orig/tac_plus.h 2008-06-18 18:24:10.000000000 -0400 +++ ./tac_plus.h 2008-06-19 18:23:13.000000000 -0400 @@ -177,6 +177,12 @@ # include #endif +#ifdef AFL +#include +#include +#include +#endif + #if ! HAVE_STRCHR # define index strchr #endif @@ -321,6 +327,14 @@ #define NAS_PORT_MAX_LEN 255 +#ifdef AFL +struct afl_cfg { + int num_failures; + int seconds; + int lock_time; +}; +#endif + struct session { int session_id; /* host specific unique session id */ int aborted; /* have we received an abort flag? */ @@ -336,6 +350,9 @@ char port[NAS_PORT_MAX_LEN+1]; /* For error reporting */ u_char version; /* version of last packet read */ u_char acct_syslog; /* syslog the accounting data */ +#ifdef AFL + struct afl_cfg *afl_cfg; /* authentication failure lock cfg */ +#endif }; extern struct session session; /* the session */ @@ -689,6 +706,12 @@ int cfg_read_config(char *); int cfg_user_exists(char *); int cfg_user_svc_default_is_permit(char *); +#ifdef AFL +void cfg_create_failure_shm(const char *, int); +void cfg_destroy_failure_shm(void); +void cfg_increment_failure(char *); +int cfg_is_user_disabled(char *); +#endif /* default_fn.c */ int default_fn(struct authen_data *); From heas at shrubbery.net Mon Jun 23 22:26:50 2008 From: heas at shrubbery.net (john heasley) Date: Mon, 23 Jun 2008 15:26:50 -0700 Subject: [tac_plus] Re: accounting + syslog In-Reply-To: <20080623222335.5B98C8655B@guelah.shrubbery.net> <20080610145903.GB1347@corp.aol.com> References: <20080623222335.5B98C8655B@guelah.shrubbery.net> <20080610145903.GB1347@corp.aol.com> Message-ID: <20080623222650.GW18678@shrubbery.net> Tue, Jun 10, 2008 at 10:59:03AM -0400, Mark Ellzey Thomas: > Index: acct.c > =================================================================== > RCS file: /cvs/netsec-dev/tacacs/acct.c,v > retrieving revision 1.3 > retrieving revision 1.4 > diff -u -r1.3 -r1.4 > --- acct.c 4 Jun 2008 14:49:54 -0000 1.3 > +++ acct.c 9 Jun 2008 14:53:37 -0000 1.4 > @@ -1,5 +1,5 @@ > /* > - * $Id: acct.c,v 1.3 2008/06/04 14:49:54 jathan Exp $ > + * $Id: acct.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ > * > * Copyright (c) 1995-1998 by Cisco systems, Inc. > * > @@ -145,7 +145,11 @@ > if (wtmpfile) { > errors = do_wtmp(&rec); > } else { > - errors = do_acct(&rec); > + if (session.acctfile != NULL) > + errors = do_acct(&rec); > + if (session.acct_syslog) > + errors = do_syslog_acct(&rec); > + Doesn't that change the accounting default? While this would preserve it: Index: acct.c =================================================================== RCS file: /home/heas/.CVS/src/routers/tac_plus/acct.c,v retrieving revision 1.5 retrieving revision 1.6 diff -d -u -r1.5 -r1.6 --- acct.c 22 Mar 2008 18:54:40 -0000 1.5 +++ acct.c 23 Jun 2008 22:22:08 -0000 1.6 @@ -144,7 +144,10 @@ if (wtmpfile) { errors = do_wtmp(&rec); } else { - errors = do_acct(&rec); + if (session.acctfile != NULL) + errors = do_acct_file(&rec); + else + errors = do_acct_syslog(&rec); } if (errors) { Index: config.c =================================================================== RCS file: /home/heas/.CVS/src/routers/tac_plus/config.c,v retrieving revision 1.35 retrieving revision 1.36 diff -d -u -r1.35 -r1.36 --- config.c 25 Apr 2007 15:30:32 -0000 1.35 +++ config.c 23 Jun 2008 22:22:08 -0000 1.36 @@ -749,11 +749,22 @@ case S_accounting: sym_get(); - parse(S_file); - parse(S_separator); - if (session.acctfile) - free(session.acctfile); - session.acctfile = tac_strdup(sym_buf); + + switch(sym_code) { + case S_file: + parse(S_file); + parse(S_separator); + if (session.acctfile) + free(session.acctfile); + session.acctfile = tac_strdup(sym_buf); + break; + + case S_syslog: + if (session.acctfile) + free(session.acctfile); + break; + } + sym_get(); continue; From mark.thomas at corp.aol.com Mon Jun 23 22:52:50 2008 From: mark.thomas at corp.aol.com (Mark Ellzey Thomas) Date: Mon, 23 Jun 2008 18:52:50 -0400 Subject: [tac_plus] Re: accounting + syslog In-Reply-To: <20080623222650.GW18678@shrubbery.net> References: <20080623222335.5B98C8655B@guelah.shrubbery.net> <20080610145903.GB1347@corp.aol.com> <20080623222650.GW18678@shrubbery.net> Message-ID: <20080623225250.GH3872@corp.aol.com> On Mon, Jun 23, 2008 at 03:26:50PM -0700, john heasley wrote: > Tue, Jun 10, 2008 at 10:59:03AM -0400, Mark Ellzey Thomas: > > Index: acct.c > > =================================================================== > > RCS file: /cvs/netsec-dev/tacacs/acct.c,v > > retrieving revision 1.3 > > retrieving revision 1.4 > > diff -u -r1.3 -r1.4 > > --- acct.c 4 Jun 2008 14:49:54 -0000 1.3 > > +++ acct.c 9 Jun 2008 14:53:37 -0000 1.4 > > @@ -1,5 +1,5 @@ > > /* > > - * $Id: acct.c,v 1.3 2008/06/04 14:49:54 jathan Exp $ > > + * $Id: acct.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ > > * > > * Copyright (c) 1995-1998 by Cisco systems, Inc. > > * > > @@ -145,7 +145,11 @@ > > if (wtmpfile) { > > errors = do_wtmp(&rec); > > } else { > > - errors = do_acct(&rec); > > + if (session.acctfile != NULL) > > + errors = do_acct(&rec); > > + if (session.acct_syslog) > > + errors = do_syslog_acct(&rec); > > + > > Doesn't that change the accounting default? While this would preserve it: > The idea was to give the administrator the ability to log to both syslog and a local file (or one or the other), if they wanted to. From heas at shrubbery.net Tue Jun 24 06:50:18 2008 From: heas at shrubbery.net (john heasley) Date: Mon, 23 Jun 2008 23:50:18 -0700 Subject: [tac_plus] Re: accounting + syslog In-Reply-To: <20080623225250.GH3872@corp.aol.com> References: <20080623222335.5B98C8655B@guelah.shrubbery.net> <20080610145903.GB1347@corp.aol.com> <20080623222650.GW18678@shrubbery.net> <20080623225250.GH3872@corp.aol.com> Message-ID: <20080624065018.GE1770@shrubbery.net> Mon, Jun 23, 2008 at 06:52:50PM -0400, Mark Ellzey Thomas: > On Mon, Jun 23, 2008 at 03:26:50PM -0700, john heasley wrote: > > Tue, Jun 10, 2008 at 10:59:03AM -0400, Mark Ellzey Thomas: > > > Index: acct.c > > > =================================================================== > > > RCS file: /cvs/netsec-dev/tacacs/acct.c,v > > > retrieving revision 1.3 > > > retrieving revision 1.4 > > > diff -u -r1.3 -r1.4 > > > --- acct.c 4 Jun 2008 14:49:54 -0000 1.3 > > > +++ acct.c 9 Jun 2008 14:53:37 -0000 1.4 > > > @@ -1,5 +1,5 @@ > > > /* > > > - * $Id: acct.c,v 1.3 2008/06/04 14:49:54 jathan Exp $ > > > + * $Id: acct.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ > > > * > > > * Copyright (c) 1995-1998 by Cisco systems, Inc. > > > * > > > @@ -145,7 +145,11 @@ > > > if (wtmpfile) { > > > errors = do_wtmp(&rec); > > > } else { > > > - errors = do_acct(&rec); > > > + if (session.acctfile != NULL) > > > + errors = do_acct(&rec); > > > + if (session.acct_syslog) > > > + errors = do_syslog_acct(&rec); > > > + > > > > Doesn't that change the accounting default? While this would preserve it: > > > > The idea was to give the administrator the ability to log to both syslog > and a local file (or one or the other), if they wanted to. Why would I want two copies of the same data? Syslog of accounting data is dubious, given that syslogds usually filter duplicates. From mark.thomas at corp.aol.com Tue Jun 24 14:19:43 2008 From: mark.thomas at corp.aol.com (Mark Ellzey Thomas) Date: Tue, 24 Jun 2008 10:19:43 -0400 Subject: [tac_plus] Re: accounting + syslog In-Reply-To: <20080624065018.GE1770@shrubbery.net> References: <20080623222335.5B98C8655B@guelah.shrubbery.net> <20080610145903.GB1347@corp.aol.com> <20080623222650.GW18678@shrubbery.net> <20080623225250.GH3872@corp.aol.com> <20080624065018.GE1770@shrubbery.net> Message-ID: <20080624141943.GA923@corp.aol.com> On Mon, Jun 23, 2008 at 11:50:18PM -0700, john heasley wrote: > Mon, Jun 23, 2008 at 06:52:50PM -0400, Mark Ellzey Thomas: > > On Mon, Jun 23, 2008 at 03:26:50PM -0700, john heasley wrote: > > > Tue, Jun 10, 2008 at 10:59:03AM -0400, Mark Ellzey Thomas: > > > > Index: acct.c > > > > =================================================================== > > > > RCS file: /cvs/netsec-dev/tacacs/acct.c,v > > > > retrieving revision 1.3 > > > > retrieving revision 1.4 > > > > diff -u -r1.3 -r1.4 > > > > --- acct.c 4 Jun 2008 14:49:54 -0000 1.3 > > > > +++ acct.c 9 Jun 2008 14:53:37 -0000 1.4 > > > > @@ -1,5 +1,5 @@ > > > > /* > > > > - * $Id: acct.c,v 1.3 2008/06/04 14:49:54 jathan Exp $ > > > > + * $Id: acct.c,v 1.4 2008/06/09 14:53:37 mthomas Exp $ > > > > * > > > > * Copyright (c) 1995-1998 by Cisco systems, Inc. > > > > * > > > > @@ -145,7 +145,11 @@ > > > > if (wtmpfile) { > > > > errors = do_wtmp(&rec); > > > > } else { > > > > - errors = do_acct(&rec); > > > > + if (session.acctfile != NULL) > > > > + errors = do_acct(&rec); > > > > + if (session.acct_syslog) > > > > + errors = do_syslog_acct(&rec); > > > > + > > > > > > Doesn't that change the accounting default? While this would preserve it: > > > > > > > The idea was to give the administrator the ability to log to both syslog > > and a local file (or one or the other), if they wanted to. > > Why would I want two copies of the same data? Syslog of accounting data > is dubious, given that syslogds usually filter duplicates. One of the main reasons I wanted to keep both options available was to have a frequently rotated local log just in case something does go wonky with the syslog daemon itself. Our configuration may be a little different in that our syslog does not write local copies of the accounting data, it just sends remote. Though the decision is completely up to the maintainers. I did not know if you would like to be in the business of having one configuration option negate the other. Lastly, prior to this patch if no acct log file was specified it would use the default (TACPLUS_ACCTFILE). We could still maintain this functionality by doing something like: if (!session.acct_syslog && !session.acctfile) session.acctfile = tac_strdup(TACPLUS_ACCTFILE); From heas at shrubbery.net Fri Jun 27 16:46:53 2008 From: heas at shrubbery.net (john heasley) Date: Fri, 27 Jun 2008 09:46:53 -0700 Subject: [tac_plus] Re: Cisco VPN 3000 In-Reply-To: <9C976A0C-FD86-43DD-939F-A0CAF4D844B6@sackheads.org> References: <9C976A0C-FD86-43DD-939F-A0CAF4D844B6@sackheads.org> Message-ID: <20080627164653.GB15738@shrubbery.net> Fri, May 30, 2008 at 12:06:12PM -0400, John Payne: > I'm getting the feeling I'm the only one using the NAC_address > (connect_origin) field regularly, as neither Juniper nor Force10 > populate it :( > > Anyhoo. With the VPN 3000, I'm noticing that identity->NAC_address > is getting 3 extra characters appended. I suspect it's because > rem_addr_len is off-by-3, but as it hasn't otherwise affected > operation, I'm not sure if this is a potential crash waiting to happen. > > As I know that all my device that do send connect_origin are going to > be IP addresses, I think I can work around this.... but it does draw > my attention to the lack of data validation in do_start(), for example: > > identity.NAC_address = tac_make_string(p, (int)start- > >rem_addr_len); > p += start->rem_addr_len; > ... > bcopy(p, authen_data.client_data, start->data_len); > > If rem_addr_len is wrong, isn't it possible for client_data to now > contain data from uninitialized memory (past the "end" of pak)? Yes, you are correct; but if look at callers of these functions (those with this idiom), you'll see that the length is checked prior to the call to them (except for one that is self-contained). From heas at shrubbery.net Fri Jun 27 17:11:59 2008 From: heas at shrubbery.net (john heasley) Date: Fri, 27 Jun 2008 10:11:59 -0700 Subject: [tac_plus] Re: tac_plus AFL (Auth Fail Lock) In-Reply-To: <20080623191154.GG3872@corp.aol.com> References: <20080623191154.GG3872@corp.aol.com> Message-ID: <20080627171159.GE15738@shrubbery.net> Mon, Jun 23, 2008 at 03:11:54PM -0400, Mark Ellzey Thomas: > Greetings all, > > Recently we have had the need for tac_plus to temporarily disable user > accounts based on the number of authentication failures the user has had > in a defined window of time. > > Attached is a patch against F4.0.4.15 with the previously submitted > acct+syslog patch (if this is a problem please inform me and I will > patch against the base F4.0.4.15 tree). > > The following global configuration parameter has been added: > > auth-fail-lock $int1 $int2 $int3 > > Where $int1 is the number of authentication failures > Where $int2 is the window (in seconds) in which to watch for auth fails > Where $int3 is the number of seconds to disable the user. > Does this (cursory glance) purposely not clear the blocked accounts on HUP? ... I wonder if its just time to thread tac_plusd. From mark.thomas at corp.aol.com Fri Jun 27 18:00:28 2008 From: mark.thomas at corp.aol.com (Mark Ellzey Thomas) Date: Fri, 27 Jun 2008 14:00:28 -0400 Subject: [tac_plus] Re: tac_plus AFL (Auth Fail Lock) In-Reply-To: <20080627171159.GE15738@shrubbery.net> References: <20080623191154.GG3872@corp.aol.com> <20080627171159.GE15738@shrubbery.net> Message-ID: <20080627180028.GA3848@corp.aol.com> On Fri, Jun 27, 2008 at 10:11:59AM -0700, john heasley wrote: > Mon, Jun 23, 2008 at 03:11:54PM -0400, Mark Ellzey Thomas: > > Greetings all, > > > > Recently we have had the need for tac_plus to temporarily disable user > > accounts based on the number of authentication failures the user has had > > in a defined window of time. > > > > Attached is a patch against F4.0.4.15 with the previously submitted > > acct+syslog patch (if this is a problem please inform me and I will > > patch against the base F4.0.4.15 tree). > > > > The following global configuration parameter has been added: > > > > auth-fail-lock $int1 $int2 $int3 > > > > Where $int1 is the number of authentication failures > > Where $int2 is the window (in seconds) in which to watch for auth fails > > Where $int3 is the number of seconds to disable the user. > > > > Does this (cursory glance) purposely not clear the blocked accounts on > HUP? > HUP is handled by handler() who calls init() which calls cfg_create_failure_shm(). This function will reinitialize all of the users: while(entry) { ... bzero(failed_node, sizeof(struct failed_node)); ... This should in essence wipe the failed_node->disabled flag. > ... > > I wonder if its just time to thread tac_plusd. I actually started down a different path of using libevent (http://monkey.org/~provos/libevent/) which is a portable library that uses the best possible mechanism for your OS to signal fd readiness. In my own personal experience I have found that you can achieve greater performance and very maintainable code (e.g., avoiding mutex nightmares) by doing something like this. I should have the initial patches complete within the next 2 weeks or so. I not asking them to be accepted, but to be viewed as a potential new architecture. From bisminko at yahoo.com Mon Jun 30 11:55:33 2008 From: bisminko at yahoo.com (B S) Date: Mon, 30 Jun 2008 04:55:33 -0700 (PDT) Subject: [tac_plus] PAM LDAP Message-ID: <432316.2533.qm@web45515.mail.sp1.yahoo.com> Welcom, May I ask you a favour ... I search some information about autentication tacacs+ and PAM / LDAP. please send / get mail - info (to better example usage PAM) -------- mseba -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.shrubbery.net/pipermail/tac_plus/attachments/20080630/c73d71d0/attachment.html