Private class to provide en/decoding for base64-based authentication conversation.
| 1396 | |
| 1397 | |
| 1398 | class _Authenticator: |
| 1399 | |
| 1400 | """Private class to provide en/decoding |
| 1401 | for base64-based authentication conversation. |
| 1402 | """ |
| 1403 | |
| 1404 | def __init__(self, mechinst): |
| 1405 | self.mech = mechinst # Callable object to provide/process data |
| 1406 | |
| 1407 | def process(self, data): |
| 1408 | ret = self.mech(self.decode(data)) |
| 1409 | if ret is None: |
| 1410 | return b'*' # Abort conversation |
| 1411 | return self.encode(ret) |
| 1412 | |
| 1413 | def encode(self, inp): |
| 1414 | # |
| 1415 | # Invoke binascii.b2a_base64 iteratively with |
| 1416 | # short even length buffers, strip the trailing |
| 1417 | # line feed from the result and append. "Even" |
| 1418 | # means a number that factors to both 6 and 8, |
| 1419 | # so when it gets to the end of the 8-bit input |
| 1420 | # there's no partial 6-bit output. |
| 1421 | # |
| 1422 | oup = b'' |
| 1423 | if isinstance(inp, str): |
| 1424 | inp = inp.encode('utf-8') |
| 1425 | while inp: |
| 1426 | if len(inp) > 48: |
| 1427 | t = inp[:48] |
| 1428 | inp = inp[48:] |
| 1429 | else: |
| 1430 | t = inp |
| 1431 | inp = b'' |
| 1432 | e = binascii.b2a_base64(t) |
| 1433 | if e: |
| 1434 | oup = oup + e[:-1] |
| 1435 | return oup |
| 1436 | |
| 1437 | def decode(self, inp): |
| 1438 | if not inp: |
| 1439 | return b'' |
| 1440 | return binascii.a2b_base64(inp) |
| 1441 | |
| 1442 | Months = ' Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ') |
| 1443 | Mon2num = {s.encode():n+1 for n, s in enumerate(Months[1:])} |