Beispiel #1
0
 def parse_p_bitstring(self, msg):
     # type: (six.binary_type) -> six.binary_type
     unused = bord(msg[0])
     r = b"".join(BITSTING[bord(c)] for c in msg)
     if unused:
         r = r[:-unused]
     return r
Beispiel #2
0
def md5crypt(password, salt=None, magic=b"$1$"):
    # type: (bytes, Optional[bytes], bytes) -> bytes
    """
    MD5 password hash
    (Used for RIPE authentication)
    >>> md5crypt("test", salt="1234")
    '$1$1234$InX9CGnHSFgHD3OZHTyt3.'
    >>> md5crypt("test", salt="1234")
    '$1$1234$InX9CGnHSFgHD3OZHTyt3.'
    >>> md5crypt("test", salt="1234", magic="$5$")
    '$5$1234$x29w4cwzSDnesjss/m2O1.'
    """
    password = smart_bytes(password)
    magic = smart_bytes(magic)
    salt = smart_bytes(salt) if salt else gen_salt(8)
    # /* The password first, since that is what is most unknown */ /* Then our magic string */ /* Then the raw salt */
    m = hashlib.md5(smart_bytes(password + magic + salt))
    # /* Then just as many characters of the MD5(pw,salt,pw) */
    mixin = hashlib.md5(smart_bytes(password + salt + password)).digest()
    for i in range(len(password)):
        m.update(bchr(mixin[i % 16]))
    # /* Then something really weird... */
    # Also really broken, as far as I can tell.  -m
    i = len(password)
    while i:
        if i & 1:
            m.update(b"\x00")
        else:
            m.update(bchr(password[0]))
        i >>= 1
    final = m.digest()
    # /* and now, just to make sure things don't run too fast */
    for i in range(1000):
        m2 = hashlib.md5()
        if i & 1:
            m2.update(smart_bytes(password))
        else:
            m2.update(smart_bytes(final))
        if i % 3:
            m2.update(smart_bytes(salt))
        if i % 7:
            m2.update(smart_bytes(password))
        if i & 1:
            m2.update(smart_bytes(final))
        else:
            m2.update(smart_bytes(password))
        final = m2.digest()
    # This is the bit that uses to64() in the original code.
    rearranged = []
    for a, b, c in REARRANGED_BITS:
        v = bord(final[a]) << 16 | bord(final[b]) << 8 | bord(final[c])
        for i in range(4):
            rearranged += [ITOA64[v & 0x3F]]
            v >>= 6
    v = bord(final[11])
    for i in range(2):
        rearranged += [ITOA64[v & 0x3F]]
        v >>= 6
    return magic + salt + b"$" + make_bytes(rearranged)
Beispiel #3
0
    def feed(self, chunk):
        # type: (six.binary_type) -> six.binary_type
        """
        Feed chunk of data to parser

        :param chunk: String
        :return: Parsed data
        """
        if self.iac_seq and chunk:
            # Restore incomplete IAC context
            chunk = self.iac_seq + chunk
            self.iac_seq = b""
        r = []  # type: List[six.binary_type]
        while chunk:
            left, seq, right = chunk.partition(B_IAC)
            # Pass clear part
            r += [left]
            # Process control sequences
            if seq:
                # Process IAC sequence
                if not right or len(right) == 1:
                    # Incomplete sequence
                    # Collect for next round
                    self.iac_seq = B_IAC + right
                    break
                ctl = bord(right[0])
                if ctl == IAC:
                    # <IAC> <IAC> leads to single <IAC>
                    r += [B_IAC]
                    chunk = right[1:]
                elif ctl in IGNORED_CMD:
                    # Ignore command
                    chunk = right[1:]
                elif ctl != SB:
                    # Process IAC <cmd> <opt>
                    self.process_iac(ctl, bord(right[1]))
                    chunk = right[2:]
                else:
                    # Process IAC SB ... SE sequence
                    # @todo: Use .partition()
                    if B_SE not in right:
                        self.iac_seq = B_IAC + right
                        break
                    i = right.index(B_SE)
                    self.process_iac_sb(right[1:i - 1])
                    chunk = right[i + 1:]
            else:
                # Return leftovers
                break
        if self.out_iac_seq:
            out_seq = b"".join(self.out_iac_seq)
            self.writer(out_seq)
            self.out_iac_seq = []
        return b"".join(r)
Beispiel #4
0
 def parse_compressed_oid(self, msg):
     # type: (bytes) -> six.text_type
     """
     :param msg:
     :return:
     """
     pos = bord(msg[0]) - 1
     parts = self.last_oid.split(".")[:pos] + [
         str(bord(d)) for d in msg[1:]
     ]
     self.last_oid = ".".join(parts)
     return smart_text(self.last_oid)
Beispiel #5
0
 def encode_int(self, data):
     """
     >>> BEREncoder().encode_int(0)
     '\\x02\\x01\\x00'
     >>> BEREncoder().encode_int(1)
     '\\x02\\x01\\x01'
     >>> BEREncoder().encode_int(127)
     '\\x02\\x01\\x7f'
     >>> BEREncoder().encode_int(128)
     '\\x02\\x02\\x00\\x80'
     >>> BEREncoder().encode_int(256)
     '\\x02\\x02\\x01\\x00'
     >>> BEREncoder().encode_int(-128)
     '\\x02\\x01\\x80'
     >>> BEREncoder().encode_int(-129)
     '\\x02\\x02\\xff\\x7f'
     """
     if data == 0:
         return b"\x02\x01\x00"
     if data > 0:
         return encode_int(data)
     data = -data
     r = self.struct_Q.pack(data).lstrip(b"\x00")
     ln = len(r)
     comp = 1 << (ln * 8 - 1)
     if comp < data:
         comp <<= 8
     r = self.struct_Q.pack(comp - data).lstrip(b"\x00")
     if r:
         r = self.struct_B.pack(bord(r[0]) | 0x80) + r[1:]
     else:
         r = b"\x80" + b"\x00" * (ln - 1)
     return self.encode_tlv(2, True, r)
Beispiel #6
0
 def parse_real(self, msg):
     # type: (bytes) -> float
     """
     """
     if not msg:
         return 0.0
     f = bord(msg[0])
     if f & 0x80:  # Binary encoding, 8.5.6
         # @todo: Снести в конец
         base = {0x00: 2, 0x10: 4, 0x20: 16}[f & 0x30]  # 8.5.6.2
         n = (f & 0x03) + 1
         e = self.parse_int(msg[1:n + 1])  # 8.5.6.4
         p = self.parse_int(msg[n + 1:])  # 8.5.6.5
         if f & 0x40:
             p = -p  # 8.5.6.1
         return p * pow(base, e)
     elif f & 0xC0 == 0:  # Decimal encoding, 8.5.7
         try:
             if f & 0x3F == 0x01:  # ISO 6093 NR1 form
                 return float(msg[1:])  # 456
             elif f & 0x3F == 0x02:  # ISO 6093 NR2 form
                 return float(msg[1:])  # 4.56
             elif f & 0x3F == 0x03:  # ISO 6093 NR3 form
                 return float(msg[1:])  # 0123e456
         except ValueError:
             raise ValueError("Invalid REAL representation: %s" % msg[1:])
     elif f & 0x40:  # infinitive, 8.5.8
         return float("-inf" if f & 0x01 else "inf")
     else:
         raise ValueError("Unknown REAL encoding: %s" % f)
Beispiel #7
0
    def parse_int(self, msg):
        # type: (bytes) -> int
        """
        >>> BERDecoder().parse_int('')
        0
        >>> BERDecoder().parse_int('\\x00')
        0
        >>> BERDecoder().parse_int('\\x01')
        1
        >>> BERDecoder().parse_int('\\x7f')
        127
        >>> BERDecoder().parse_int('\\x00\\x80')
        128
        >>> BERDecoder().parse_int('\\x01\\x00')
        256
        >>> BERDecoder().parse_int('\\x80')
        -128
        >>> BERDecoder().parse_int('\\xff\\x7f')
        -129

        :param msg:
        :return: integer
        """
        if not msg:
            return 0
        # Try to speedup
        mask = self.INT_MASK.get(len(msg))
        if mask:
            return mask.unpack(msg)[0]
        # Decode as is
        v = 0
        for c in msg:
            v = (v << 8) + bord(c)
        if bord(msg[0]) & 0x80:
            # Negative number
            m = 1 << (8 * len(msg))
            v -= m
        return v
Beispiel #8
0
def _replace_re_group_binary(expr, group, pattern):
    # type: (six.binary_type, six.binary_type, six.binary_type) -> six.binary_type
    """
    Replace regular expression group with pattern

    >>> replace_re_group("nothing","(?P<groupname>","groupvalue")
    'nothing'
    >>> replace_re_group("the (?P<groupname>simple) test","(?P<groupname>","groupvalue")
    'the groupvalue test'
    >>> replace_re_group("the (?P<groupname> nested (test)>)","(?P<groupname>","groupvalue")
    'the groupvalue'
    """
    r = []
    lg = len(group)
    while expr:
        idx = expr.find(group)
        if idx == -1:
            break
        r += [expr[:idx]]
        expr = expr[idx + lg :]
        level = 1  # Level of parenthesis nesting
        while expr:
            c = bord(expr[0])
            expr = expr[1:]
            if c == 0x5C:  # "\\"
                # Skip quoted character
                expr = expr[1:]
                continue
            elif c == 0x28:  # "("
                # Increase nesting level
                level += 1
                continue
            elif c == 0x29:  # ")"
                # Decrease nesting level
                level -= 1
                if level == 0:
                    # Replace with pattern and search for next
                    r += [pattern]
                    break
    r += [expr]
    return b"".join(r)
Beispiel #9
0
 def parse_boolean(self, msg):
     # type: (bytes) -> bool
     if not msg:
         return False
     return bool(bord(msg[0]))
Beispiel #10
0
 def parse_a_ipaddress(self, msg):
     # type: (bytes) -> six.text_type
     if not msg:
         raise ValueError("Invalid IP Address: '%s'" % msg.encode("hex"))
     return "%d.%d.%d.%d" % (bord(msg[0]), bord(msg[1]), bord(
         msg[2]), bord(msg[3]))
Beispiel #11
0
def test_bord(input, expected):
    assert bord(input[0]) == expected