Private class to provide en/decoding for base64-based authentication conversation.
| 1714 | |
| 1715 | |
| 1716 | class _Authenticator: |
| 1717 | |
| 1718 | """Private class to provide en/decoding |
| 1719 | for base64-based authentication conversation. |
| 1720 | """ |
| 1721 | |
| 1722 | def __init__(self, mechinst): |
| 1723 | self.mech = mechinst # Callable object to provide/process data |
| 1724 | |
| 1725 | def process(self, data): |
| 1726 | ret = self.mech(self.decode(data)) |
| 1727 | if ret is None: |
| 1728 | return b'*' # Abort conversation |
| 1729 | return self.encode(ret) |
| 1730 | |
| 1731 | def encode(self, inp): |
| 1732 | # |
| 1733 | # Invoke binascii.b2a_base64 iteratively with |
| 1734 | # short even length buffers, strip the trailing |
| 1735 | # line feed from the result and append. "Even" |
| 1736 | # means a number that factors to both 6 and 8, |
| 1737 | # so when it gets to the end of the 8-bit input |
| 1738 | # there's no partial 6-bit output. |
| 1739 | # |
| 1740 | oup = b'' |
| 1741 | if isinstance(inp, str): |
| 1742 | inp = inp.encode('utf-8') |
| 1743 | while inp: |
| 1744 | if len(inp) > 48: |
| 1745 | t = inp[:48] |
| 1746 | inp = inp[48:] |
| 1747 | else: |
| 1748 | t = inp |
| 1749 | inp = b'' |
| 1750 | e = binascii.b2a_base64(t) |
| 1751 | if e: |
| 1752 | oup = oup + e[:-1] |
| 1753 | return oup |
| 1754 | |
| 1755 | def decode(self, inp): |
| 1756 | if not inp: |
| 1757 | return b'' |
| 1758 | return binascii.a2b_base64(inp) |
| 1759 | |
| 1760 | Months = ' Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ') |
| 1761 | Mon2num = {s.encode():n+1 for n, s in enumerate(Months[1:])} |