Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft: fix for UTF-8 #167

Merged
merged 2 commits into from
Jul 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions pyrad/packet.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,10 +710,14 @@ def RequestPacket(self):
return header + attr

def PwDecrypt(self, password):
"""Obfuscate a RADIUS password. RADIUS hides passwords in packets by
"""De-Obfuscate a RADIUS password. RADIUS hides passwords in packets by
using an algorithm based on the MD5 hash of the packet authenticator
and RADIUS secret. This function reverses the obfuscation process.

Although RFC2865 does not explicitly state UTF-8 for the password field,
the rest of RFC2865 defines UTF-8 as the encoding expected for the decrypted password.


:param password: obfuscated form of password
:type password: binary string
:return: plaintext password
Expand All @@ -729,10 +733,16 @@ def PwDecrypt(self, password):
pw += bytes((hash[i] ^ buf[i],))
(last, buf) = (buf[:16], buf[16:])

# This is safe even with UTF-8 encoding since no valid encoding of UTF-8
# (other than encoding U+0000 NULL) will produce a bytestream containing 0x00 byte.
while pw.endswith(b'\x00'):
pw = pw[:-1]

return pw.decode('utf-8')
# If the shared secret with the client is not the same, then de-obfuscating the password
# field may yield illegal UTF-8 bytes. Therefore, in order not to provoke an Exception here
# (which would be not consistently generated since this will depend on the random data chosen
# by the client) we simply ignore un-parsable UTF-8 sequences.
return pw.decode('utf-8', errors="ignore")

def PwCrypt(self, password):
"""Obfuscate password.
Expand Down
Loading