ansible/tacacs_plus

Switch from ASCII to PAP and back

mikeparowski opened this issue · 12 comments

I've been having a number of issues with the PAP and CHAP authentication methods since 2.0. I can authenticate just fine with a simple client.authenticate('username', 'password'), but then when I try to do the same with PAP (e.g. client.authenticate('username', 'password', authen_type=TAC_PLUS_AUTHEN_TYPE_PAP) ) it fails. In the same session, I then try to re-authenticate using the default ascii method with client.authenticate('username', 'password') and am returned "choose_authen: unacceptable authen method".

Was this closed for some reason? Do you still have the problem?

@crisidev sorry, i misstated my problem before and closed it once i realized my mistake. my big issue is i cannot successfully authenticate with CHAP. using the same process as before with a similar library, CHAP authentication continues to result in a FAIL

So, I made a lot of changes lately, hence I have probably broken the CHAP auth in some way.. Sorry about that.

I cannot actually test the CHAP auth, since I don't have a running CHAP setup. Maybe @ryanpetrello can help more with this.

Can you provide some debug logs to help figuring out where is the problem? Be aware that enabling the debug log will print you password in clear text, so please sanitize them.

Another question: do you know which was the last version of tacacs_plus python package working for you in CHAP mode?

Here's a debug log instance:

Authentication Start:
Action=Login
Priv_Lvl=0
Type=CHAP
Service=Login
User=user55
Port=python_tty0
RemAddr=python_device
Data=196pZܝ4��;,Es3 Y� ���o���s�:���B]
<87> 2017-08-08 15:07:26 [10.51.50.147:48056] Received chap login with pppID 1 and challenge 96pZܝ4��;,Es3 Y� (39-36-70-5A-DC-9D-34-DB-F9-3B-2C-45-73-33-13-59-83)
<87> 2017-08-08 15:07:26 [10.51.50.147:48056] Received 2 packets on connection
<87> 2017-08-08 15:07:26 [10.51.50.147:48056]
Sending:
MajorVersion=12
MinorVersion=1
Type=Authentication
SeqNum=2
IsEncrypted=True
IsSingleConnect=False
SessionID=-1906993337
DataLength=32
Authentication AuthReply:
Status=Fail
Flags=Debug
UserMsg=CHAP authentication failed
Data=
<87> 2017-08-08 15:07:26 [10.51.50.147:48024] Device 10.51.10.240:56162 is allowed to connect based on settings for group INTERNAL
<94> 2017-08-08 15:07:26 [10.51.50.147:48024] New client connection opened for 10.51.10.240:56162 TID:44
<87> 2017-08-08 15:07:26 [10.51.50.147:48024] TOTAL connections: 145
<87> 2017-08-08 15:07:26 [10.51.10.240:56162] Received 1 packets on connection
<87> 2017-08-08 15:07:26 [10.51.50.147:48024] Device 10.51.10.240:56163 is allowed to connect based on settings for group INTERNAL
<94> 2017-08-08 15:07:26 [10.51.50.147:48024] New client connection opened for 10.51.10.240:56163 TID:44
<87> 2017-08-08 15:07:26 [10.51.50.147:48024] TOTAL connections: 146
<87> 2017-08-08 15:07:26 [10.51.10.240:56163] Received 1 packets on connection
<87> 2017-08-08 15:07:26 [10.51.10.240:56162]
Received:
MajorVersion=12
MinorVersion=1
Type=Authentication
SeqNum=1
IsEncrypted=True
IsSingleConnect=False
SessionID=407879733
DataLength=39

To send the request, I'm using the following lines:

client = TACACSClient(host, port, secret)
challenge = "".join(chr(random.randint(1,255)) for x in xrange(15))
client.authenticate(user, password, authen_type=0x03, chap_ppp_id=str(random.randint(0,255)), chap_challenge=challenge)

I have not successfully used (or tested) any previous tacacs_plus library with a working CHAP authen. Our old library was a Python adaptation of libtac here: https://github.com/jeroennijhof/pam_tacplus/tree/master/libtac

@mikeparowski if you downgrade to pre-2.0, does CHAP work?

I just tried it with 0.2 with no success

@ryanpetrello @crisidev i resolved it by ensuring that the chap_ppp_id is 1 single digit [0-9]. Is that a bug, or how the protocol is designed?

@mikeparowski from https://datatracker.ietf.org/doc/draft-ietf-opsawg-tacacs/?include_text=1:

The length of the challenge value can be determined from the length of the data field minus the length of the id (always 1 octet)

Other implementations I've seen (such as https://github.com/xertres/tacacs_plus/blob/1f7d4dfd8c16efae94d84ba7f898c9d2e59a4c7f/lib/client.rb#L558) seem to limit it to 1 byte, so it makes sense that your code:

chap_ppp_id=str(random.randint(0,255)), chap_challenge=challenge)

...would only fail sometimes.

I could see an argument for adding some additional validation for the ppp_id and challenge; it looks like ppp_id must be 1 byte and the challenge must be < 255 bytes.

Given it looks like it is in the protocol, I think we should add some validations there.

👍 @crisidev I'll work on a PR for this shortly.

PR acked.