From 8770e6e2a7dc4fe65d00b4d68233015a2549361d Mon Sep 17 00:00:00 2001 From: Nick Porter Date: Wed, 30 Aug 2023 11:51:12 +0100 Subject: [PATCH 1/3] Add command line options to set CHAP ID and Challenge --- bin/tacacs_client | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bin/tacacs_client b/bin/tacacs_client index 8b71210..244cc22 100755 --- a/bin/tacacs_client +++ b/bin/tacacs_client @@ -58,6 +58,8 @@ def parse_args(): authentication = command.add_parser('authenticate', help="authenticate against a tacacs+ server") if not user_password: authentication.add_argument('-p', '--password', required=False, help="user password") + authentication.add_argument('-i', '--chap-id', required=False, help="CHAP ID") + authentication.add_argument('-c', '--chap-challenge', required=False, help="CHAP Challenge") authorization = command.add_parser('authorize', help="authorize a command against a tacacs+ server") authorization.add_argument('-c', '--cmds', required=True, nargs='+', help="list of cmds to authorize") @@ -108,11 +110,13 @@ def authenticate(cli, args): if not vars(args).get('password'): args.password = getpass.getpass('password for %s: ' % args.username) - chap_ppp_id = None - chap_challenge = None + chap_ppp_id = args.chap_id + chap_challenge = args.chap_challenge if args.authen_type == TAC_PLUS_AUTHEN_TYPE_CHAP: - chap_ppp_id = six.moves.input('chap PPP ID: ') - chap_challenge = six.moves.input('chap challenge: ') + if chap_ppp_id == None: + chap_ppp_id = six.moves.input('chap PPP ID: ') + if chap_challenge == None: + chap_challenge = six.moves.input('chap challenge: ') auth = cli.authenticate(args.username, args.password, priv_lvl=args.priv_lvl, authen_type=args.authen_type, chap_ppp_id=chap_ppp_id, chap_challenge=chap_challenge, rem_addr=args.rem_addr, From e24b3dbe5706133bf5ec562875d7c3d36182e3e1 Mon Sep 17 00:00:00 2001 From: Nick Porter Date: Fri, 24 Jan 2025 19:40:54 +0000 Subject: [PATCH 2/3] Add test and debug for GETDATA response --- tacacs_plus/authentication.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tacacs_plus/authentication.py b/tacacs_plus/authentication.py index 4303f86..a866fdd 100644 --- a/tacacs_plus/authentication.py +++ b/tacacs_plus/authentication.py @@ -5,7 +5,8 @@ from .flags import ( TAC_PLUS_PRIV_LVL_MIN, TAC_PLUS_AUTHEN_LOGIN, TAC_PLUS_AUTHEN_SVC_LOGIN, TAC_PLUS_AUTHEN_STATUS_PASS, TAC_PLUS_AUTHEN_STATUS_FAIL, TAC_PLUS_AUTHEN_STATUS_ERROR, - TAC_PLUS_AUTHEN_STATUS_GETPASS, TAC_PLUS_VIRTUAL_PORT, TAC_PLUS_VIRTUAL_REM_ADDR + TAC_PLUS_AUTHEN_STATUS_GETPASS, TAC_PLUS_VIRTUAL_PORT, TAC_PLUS_VIRTUAL_REM_ADDR, + TAC_PLUS_AUTHEN_STATUS_GETDATA ) @@ -165,11 +166,16 @@ def error(self): def getpass(self): return self.status == TAC_PLUS_AUTHEN_STATUS_GETPASS + @property + def getdata(self): + return self.status == TAC_PLUS_AUTHEN_STATUS_GETDATA + @property def human_status(self): return { TAC_PLUS_AUTHEN_STATUS_PASS: 'PASS', TAC_PLUS_AUTHEN_STATUS_FAIL: 'FAIL', + TAC_PLUS_AUTHEN_STATUS_GETDATA: 'GETDATA', TAC_PLUS_AUTHEN_STATUS_GETPASS: 'GETPASS', TAC_PLUS_AUTHEN_STATUS_ERROR: 'ERROR' }.get(self.status, 'UNKNOWN: %s' % self.status) From 0f62f774d60b49f880e6f620af310e4527a55f33 Mon Sep 17 00:00:00 2001 From: Nick Porter Date: Fri, 24 Jan 2025 19:41:51 +0000 Subject: [PATCH 3/3] Allow for one round of GETDATA in ASCII auth --- tacacs_plus/client.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tacacs_plus/client.py b/tacacs_plus/client.py index e024ab0..dcbb9f1 100644 --- a/tacacs_plus/client.py +++ b/tacacs_plus/client.py @@ -221,6 +221,19 @@ def authenticate(self, username, password, priv_lvl=TAC_PLUS_PRIV_LVL_MIN, ])) if reply.flags == TAC_PLUS_CONTINUE_FLAG_ABORT: reply.status = TAC_PLUS_AUTHEN_STATUS_FAIL + if authen_type == TAC_PLUS_AUTHEN_TYPE_ASCII and reply.getdata: + response = input(reply.server_msg) + packet = self.send(TACACSAuthenticationContinue(response), + TAC_PLUS_AUTHEN, + packet.seq_no + 1) + reply = TACACSAuthenticationReply.unpacked(packet.body) + logger.debug('\n'.join([ + reply.__class__.__name__, + 'recv header <%s>' % packet.header, + 'recv body <%s>' % reply + ])) + if reply.flags == TAC_PLUS_CONTINUE_FLAG_ABORT: + reply.status = TAC_PLUS_AUTHEN_STATUS_FAIL return reply