Esempio n. 1
0
    def __init__(self, name, default, length_from, get_class, evaluators=None):
        """
        @param length_from: function to obtain the field length
        @type length_from: C{callable}

        @param get_class: function to obtain the class
        @type get_class: C{callable}

        @param evaluators: evaluators
        @type evaluators: C{list} of C{callable}
        """
        StrLenField.__init__(self, name, default, length_from=length_from)
        self.evaluators = evaluators or []
        self._get_class = get_class
Esempio n. 2
0
 def i2m(self, pkt, x):
     cls = self.subtypes_dict.get(pkt.subtype, StrLenField)
     try:
         return (cls.i2m.__func__ if six.PY2 else cls.i2m)(self, pkt, x)
     except Exception:
         log_runtime.exception("Failed to build " + self.name + " ! ")
         return StrLenField.i2m(self, pkt, x)
Esempio n. 3
0
 def m2i(self, pkt, x):
     cls = self.subtypes_dict.get(pkt.subtype, StrLenField)
     try:
         return (cls.m2i.__func__ if six.PY2 else cls.m2i)(self, pkt, x)
     except Exception:
         log_runtime.exception("Failed to dissect " + self.name + " ! ")
         return StrLenField.m2i(self, pkt, x)
Esempio n. 4
0
class TacacsPacketArguments(Packet):

    '''

    Class defined to handle the arguments listed at the end of tacacs+
    Authorization and Accounting packets.

    '''

    __slots__ = ['_len']
    name = 'Arguments in Tacacs+ packet'
    fields_desc = [StrLenField('data', '', length_from=lambda pkt: pkt._len)]

    def pre_dissect(self, s):
        cur = self.underlayer
        i = 0

        # Searching the position in layer in order to get its length

        while isinstance(cur, TacacsPacketArguments):
            cur = cur.underlayer
            i += 1
        self._len = cur.arg_len_list[i]
        return s

    def guess_payload_class(self, pay):
        cur = self.underlayer
        i = 0

        # Guessing if Argument packet. Nothing in encapsulated via tacacs+

        while isinstance(cur, TacacsPacketArguments):
            cur = cur.underlayer
            i += 1
        if i+1 < cur.arg_cnt:
            return TacacsPacketArguments
        return conf.padding_layer
Esempio n. 5
0
class LLTDAttribute(Packet):
    name = "LLTD Attribute"
    show_indent = False
    show_summary = False
    # section 2.2.1.1
    fields_desc = [
        ByteEnumField(
            "type", 0, {
                0: "End Of Property",
                1: "Host ID",
                2: "Characteristics",
                3: "Physical Medium",
                7: "IPv4 Address",
                9: "802.11 Max Rate",
                10: "Performance Counter Frequency",
                12: "Link Speed",
                14: "Icon Image",
                15: "Machine Name",
                18: "Device UUID",
                20: "QoS Characteristics",
                21: "802.11 Physical Medium",
                24: "Detailed Icon Image",
            }),
        FieldLenField("len", None, length_of="value", fmt="B"),
        StrLenField("value", "", length_from=lambda pkt: pkt.len),
    ]

    @classmethod
    def dispatch_hook(cls, _pkt=None, *_, **kargs):
        if _pkt:
            cmd = struct.unpack("B", _pkt[0])[0]
        elif "type" in kargs:
            cmd = kargs["type"]
            if isinstance(cmd, basestring):
                cmd = cls.fields_desc[0].s2i[cmd]
        return SPECIFIC_CLASSES.get(cmd, cls)
Esempio n. 6
0
class SCTPChunkData(_SCTPChunkGuessPayload, Packet):
    # TODO : add a padding function in post build if this layer is used to generate SCTP chunk data  # noqa: E501
    fields_desc = [
        ByteEnumField("type", 0, sctpchunktypes),
        BitField("reserved", None, 4),
        BitField("delay_sack", 0, 1),
        BitField("unordered", 0, 1),
        BitField("beginning", 0, 1),
        BitField("ending", 0, 1),
        FieldLenField("len",
                      None,
                      length_of="data",
                      adjust=lambda pkt, x: x + 16),  # noqa: E501
        XIntField("tsn", None),
        XShortField("stream_id", None),
        XShortField("stream_seq", None),
        IntEnumField("proto_id", None,
                     SCTP_PAYLOAD_PROTOCOL_INDENTIFIERS),  # noqa: E501
        PadField(
            StrLenField("data", None,
                        length_from=lambda pkt: pkt.len - 16),  # noqa: E501
            4,
            padwith=b"\x00"),
    ]
Esempio n. 7
0
class PPP_LCP_Option(Packet):
    name = "PPP LCP Option"
    fields_desc = [
        ByteEnumField("type", None, _PPP_lcp_optiontypes),
        FieldLenField("len", None, fmt="B", length_of="data",
                      adjust=lambda _, val: val + 2),
        StrLenField("data", None, length_from=lambda pkt: pkt.len - 2),
    ]

    def extract_padding(self, pay):
        return b"", pay

    registered_options = {}

    @classmethod
    def register_variant(cls):
        cls.registered_options[cls.type.default] = cls

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt:
            o = orb(_pkt[0])
            return cls.registered_options.get(o, cls)
        return cls
Esempio n. 8
0
class ZCLPricePublishPrice(Packet):
    name = "Price Cluster: Publish Price Command (Server: Generated)"
    fields_desc = [
        XLEIntField("provider_id", 0x00000000),  # Unsigned 32-bit Integer (4 octets)  # noqa: E501
        # Rate Label is a UTF-8 encoded Octet String (0-12 octets). The first Octet indicates the length.  # noqa: E501
        StrLenField("rate_label", "", length_from=lambda pkt:int(pkt.rate_label[0])),  # TODO verify  # noqa: E501
        XLEIntField("issuer_event_id", 0x00000000),  # Unsigned 32-bit Integer (4 octets)  # noqa: E501
        XLEIntField("current_time", 0x00000000),  # UTCTime (4 octets)
        ByteField("unit_of_measure", 0),  # 8 bits enumeration (1 octet)
        XLEShortField("currency", 0x0000),  # Unsigned 16-bit Integer (2 octets)  # noqa: E501
        ByteField("price_trailing_digit", 0),  # 8-bit BitMap (1 octet)
        ByteField("number_of_price_tiers", 0),  # 8-bit BitMap (1 octet)
        XLEIntField("start_time", 0x00000000),  # UTCTime (4 octets)
        XLEShortField("duration_in_minutes", 0x0000),  # Unsigned 16-bit Integer (2 octets)  # noqa: E501
        XLEIntField("price", 0x00000000),  # Unsigned 32-bit Integer (4 octets)
        ByteField("price_ratio", 0),  # Unsigned 8-bit Integer (1 octet)
        XLEIntField("generation_price", 0x00000000),  # Unsigned 32-bit Integer (4 octets)  # noqa: E501
        ByteField("generation_price_ratio", 0),  # Unsigned 8-bit Integer (1 octet)  # noqa: E501
        XLEIntField("alternate_cost_delivered", 0x00000000),  # Unsigned 32-bit Integer (4 octets)  # noqa: E501
        ByteField("alternate_cost_unit", 0),  # 8-bit enumeration (1 octet)
        ByteField("alternate_cost_trailing_digit", 0),  # 8-bit BitMap (1 octet)  # noqa: E501
        ByteField("number_of_block_thresholds", 0),  # 8-bit BitMap (1 octet)
        ByteField("price_control", 0),  # 8-bit BitMap (1 octet)
    ]
Esempio n. 9
0
class RTRRouterKey(Packet):
    '''

    Router Key packet from version 1 standard section 5.10
    https://tools.ietf.org/html/rfc8210#section-5.10

    '''
    name = 'Router Key'
    fields_desc = [
        ByteEnumField('rtr_version', 1, RTR_VERSION),
        ByteEnumField('pdu_type', 9, PDU_TYPE),
        ByteField('flags', 0),
        ByteField('zeros', 0),
        IntField('length', None),
        StrFixedLenField('subject_key_identifier', '', 20),
        IntField('asn', 0),
        StrLenField('subject_PKI', '', length_from=lambda x: x.length - 32)
    ]

    def post_build(self, pkt, pay):
        temp_len = len(pkt) + 2
        if not self.length:
            pkt = pkt[:2] + struct.pack('!I', temp_len) + pkt[6:]
        return pkt + pay
Esempio n. 10
0
class DNSRR(InheritOriginDNSStrPacket):
    name = "DNS Resource Record"
    show_indent = 0
    fields_desc = [
        DNSStrField("rrname", ""),
        ShortEnumField("type", 1, dnstypes),
        ShortEnumField("rclass", 1, dnsclasses),
        IntField("ttl", 0),
        FieldLenField("rdlen", None, length_of="rdata", fmt="H"),
        MultipleTypeField(
            [
                # A
                (IPField("rdata", "0.0.0.0"), lambda pkt: pkt.type == 1),
                # AAAA
                (IP6Field("rdata", "::"), lambda pkt: pkt.type == 28),
                # NS, MD, MF, CNAME, PTR
                (DNSStrField("rdata", "", length_from=lambda pkt: pkt.rdlen),
                 lambda pkt: pkt.type in [2, 3, 4, 5, 12]),
                # TEXT
                (DNSTextField("rdata", [], length_from=lambda pkt: pkt.rdlen),
                 lambda pkt: pkt.type == 16),
            ],
            StrLenField("rdata", "", length_from=lambda pkt: pkt.rdlen))
    ]
Esempio n. 11
0
class KeyShareEntry(Packet):
    """
    When building from scratch, we create a DH private key, and when
    dissecting, we create a DH public key. Default group is secp256r1.
    """
    __slots__ = ["privkey", "pubkey"]
    name = "Key Share Entry"
    fields_desc = [
        ShortEnumField("group", None, _tls_named_groups),
        FieldLenField("kxlen", None, length_of="key_exchange"),
        StrLenField("key_exchange", "", length_from=lambda pkt: pkt.kxlen)
    ]

    def __init__(self, *args, **kargs):
        self.privkey = None
        self.pubkey = None
        super(KeyShareEntry, self).__init__(*args, **kargs)

    def do_build(self):
        """
        We need this hack, else 'self' would be replaced by __iter__.next().
        """
        tmp = self.explicit
        self.explicit = True
        b = super(KeyShareEntry, self).do_build()
        self.explicit = tmp
        return b

    @crypto_validator
    def create_privkey(self):
        """
        This is called by post_build() for key creation.
        """
        if self.group in _tls_named_ffdh_groups:
            params = _ffdh_groups[_tls_named_ffdh_groups[self.group]][0]
            privkey = params.generate_private_key()
            self.privkey = privkey
            pubkey = privkey.public_key()
            self.key_exchange = pubkey.public_numbers().y
        elif self.group in _tls_named_curves:
            if _tls_named_curves[self.group] == "x25519":
                if conf.crypto_valid_advanced:
                    privkey = x25519.X25519PrivateKey.generate()
                    self.privkey = privkey
                    pubkey = privkey.public_key()
                    self.key_exchange = pubkey.public_bytes(
                        serialization.Encoding.Raw,
                        serialization.PublicFormat.Raw)
            elif _tls_named_curves[self.group] != "x448":
                curve = ec._CURVE_TYPES[_tls_named_curves[self.group]]()
                privkey = ec.generate_private_key(curve, default_backend())
                self.privkey = privkey
                pubkey = privkey.public_key()
                try:
                    # cryptography >= 2.5
                    self.key_exchange = pubkey.public_bytes(
                        serialization.Encoding.X962,
                        serialization.PublicFormat.UncompressedPoint)
                except TypeError:
                    # older versions
                    self.key_exchange = pubkey.public_numbers().encode_point()

    def post_build(self, pkt, pay):
        if self.group is None:
            self.group = 23  # secp256r1

        if not self.key_exchange:
            try:
                self.create_privkey()
            except ImportError:
                pass

        if self.kxlen is None:
            self.kxlen = len(self.key_exchange)

        group = struct.pack("!H", self.group)
        kxlen = struct.pack("!H", self.kxlen)
        return group + kxlen + self.key_exchange + pay

    @crypto_validator
    def register_pubkey(self):
        if self.group in _tls_named_ffdh_groups:
            params = _ffdh_groups[_tls_named_ffdh_groups[self.group]][0]
            pn = params.parameter_numbers()
            public_numbers = dh.DHPublicNumbers(self.key_exchange, pn)
            self.pubkey = public_numbers.public_key(default_backend())
        elif self.group in _tls_named_curves:
            if _tls_named_curves[self.group] == "x25519":
                if conf.crypto_valid_advanced:
                    import_point = x25519.X25519PublicKey.from_public_bytes
                    self.pubkey = import_point(self.key_exchange)
            elif _tls_named_curves[self.group] != "x448":
                curve = ec._CURVE_TYPES[_tls_named_curves[self.group]]()
                try:  # cryptography >= 2.5
                    import_point = ec.EllipticCurvePublicKey.from_encoded_point  # noqa: E501
                    self.pubkey = import_point(curve, self.key_exchange)
                except AttributeError:
                    import_point = ec.EllipticCurvePublicNumbers.from_encoded_point  # noqa: E501
                    pub_num = import_point(
                        curve,
                        self.key_exchange).public_numbers()  # noqa: E501
                    self.pubkey = pub_num.public_key(default_backend())

    def post_dissection(self, r):
        try:
            self.register_pubkey()
        except ImportError:
            pass

    def extract_padding(self, s):
        return "", s
Esempio n. 12
0
class ClientECDiffieHellmanPublic(_GenericTLSSessionInheritance):
    """
    Note that the 'len' field is 1 byte longer than with the previous class.
    """
    name = "Client ECDH Public Value"
    fields_desc = [FieldLenField("ecdh_Yclen", None,
                                 length_of="ecdh_Yc", fmt="B"),
                   StrLenField("ecdh_Yc", "",
                               length_from=lambda pkt: pkt.ecdh_Yclen)]

    @crypto_validator
    def fill_missing(self):
        s = self.tls_session
        s.client_kx_privkey = _tls_named_groups_generate(
            s.client_kx_ecdh_params
        )
        # ecdh_Yc follows ECPoint.point format as defined in
        # https://tools.ietf.org/html/rfc8422#section-5.4
        pubkey = s.client_kx_privkey.public_key()
        if isinstance(pubkey, (x25519.X25519PublicKey,
                               x448.X448PublicKey)):
            self.ecdh_Yc = pubkey.public_bytes(
                serialization.Encoding.Raw,
                serialization.PublicFormat.Raw
            )
            if s.client_kx_privkey and s.server_kx_pubkey:
                pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
        else:
            # uncompressed format of an elliptic curve point
            x = pubkey.public_numbers().x
            y = pubkey.public_numbers().y
            self.ecdh_Yc = (b"\x04" +
                            pkcs_i2osp(x, pubkey.key_size // 8) +
                            pkcs_i2osp(y, pubkey.key_size // 8))
            if s.client_kx_privkey and s.server_kx_pubkey:
                pms = s.client_kx_privkey.exchange(ec.ECDH(),
                                                   s.server_kx_pubkey)

        if s.client_kx_privkey and s.server_kx_pubkey:
            s.pre_master_secret = pms
            if not s.extms or s.session_hash:
                s.compute_ms_and_derive_keys()

    def post_build(self, pkt, pay):
        if not self.ecdh_Yc:
            try:
                self.fill_missing()
            except ImportError:
                pass
        if self.ecdh_Yclen is None:
            self.ecdh_Yclen = len(self.ecdh_Yc)
        return pkcs_i2osp(self.ecdh_Yclen, 1) + self.ecdh_Yc + pay

    def post_dissection(self, m):
        s = self.tls_session

        # if there are kx params and keys, we assume the crypto library is ok
        if s.client_kx_ecdh_params:
            s.client_kx_pubkey = _tls_named_groups_import(
                s.client_kx_ecdh_params,
                self.ecdh_Yc
            )

        if s.server_kx_privkey and s.client_kx_pubkey:
            ZZ = s.server_kx_privkey.exchange(ec.ECDH(), s.client_kx_pubkey)
            s.pre_master_secret = ZZ
            if not s.extms or s.session_hash:
                s.compute_ms_and_derive_keys()
Esempio n. 13
0
class ClientDiffieHellmanPublic(_GenericTLSSessionInheritance):
    """
    If the user provides a value for dh_Yc attribute, we assume he will set
    the pms and ms accordingly and trigger the key derivation on his own.

    XXX As specified in 7.4.7.2. of RFC 4346, we should distinguish the needs
    for implicit or explicit value depending on availability of DH parameters
    in *client* certificate. For now we can only do ephemeral/explicit DH.
    """
    name = "Client DH Public Value"
    fields_desc = [FieldLenField("dh_Yclen", None, length_of="dh_Yc"),
                   StrLenField("dh_Yc", "",
                               length_from=lambda pkt: pkt.dh_Yclen)]

    @crypto_validator
    def fill_missing(self):
        s = self.tls_session
        s.client_kx_privkey = s.client_kx_ffdh_params.generate_private_key()
        pubkey = s.client_kx_privkey.public_key()
        y = pubkey.public_numbers().y
        self.dh_Yc = pkcs_i2osp(y, pubkey.key_size // 8)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
            s.pre_master_secret = pms
            if not s.extms or s.session_hash:
                # If extms is set (extended master secret), the key will
                # need the session hash to be computed. This is provided
                # by the TLSClientKeyExchange. Same in all occurrences
                s.compute_ms_and_derive_keys()

    def post_build(self, pkt, pay):
        if not self.dh_Yc:
            try:
                self.fill_missing()
            except ImportError:
                pass
        if self.dh_Yclen is None:
            self.dh_Yclen = len(self.dh_Yc)
        return pkcs_i2osp(self.dh_Yclen, 2) + self.dh_Yc + pay

    def post_dissection(self, m):
        """
        First we update the client DHParams. Then, we try to update the server
        DHParams generated during Server*DHParams building, with the shared
        secret. Finally, we derive the session keys and update the context.
        """
        s = self.tls_session

        # if there are kx params and keys, we assume the crypto library is ok
        if s.client_kx_ffdh_params:
            y = pkcs_os2ip(self.dh_Yc)
            param_numbers = s.client_kx_ffdh_params.parameter_numbers()
            public_numbers = dh.DHPublicNumbers(y, param_numbers)
            s.client_kx_pubkey = public_numbers.public_key(default_backend())

        if s.server_kx_privkey and s.client_kx_pubkey:
            ZZ = s.server_kx_privkey.exchange(s.client_kx_pubkey)
            s.pre_master_secret = ZZ
            if not s.extms or s.session_hash:
                s.compute_ms_and_derive_keys()

    def guess_payload_class(self, p):
        return Padding
Esempio n. 14
0
class PPP_LCP_Quality_Protocol_Option(PPP_LCP_Option):
    fields_desc = [ByteEnumField("type", 4, _PPP_lcp_optiontypes),
                   FieldLenField("len", None, fmt="B", length_of="data",
                                 adjust=lambda p, x:x+4),
                   ShortEnumField("quality_protocol", 0xc025, _PPP_LCP_quality_protocols),
                   StrLenField("data", "", length_from=lambda p:p.len-4)]
Esempio n. 15
0
class SAPDiagDyntAtomItem(PacketNoPadded):
    name = "SAP Diag Dynt Atom item"
    fields_desc = [
        ShortField("atom_length", 0),
        ByteField("dlg_flag_1", 0),
        ByteField("dlg_flag_2", 0),
        ByteEnumKeysField("etype", 0, diag_atom_etypes),
        ByteField("area", 0),
        ByteField("block", 0),
        ByteField("group", 0),
        ShortField("row", 0),
        ShortField("col", 0),
        # Attr flags
        BitField("attr_DIAG_BSD_COMBOSTYLE", 0, 1),  # 80
        BitField("attr_DIAG_BSD_YES3D", 0, 1),  # 40
        BitField("attr_DIAG_BSD_PROPFONT", 0, 1),  # 20
        BitField("attr_DIAG_BSD_MATCHCODE", 0, 1),  # 10
        BitField("attr_DIAG_BSD_JUSTRIGHT", 0, 1),  # 08
        BitField("attr_DIAG_BSD_INTENSIFY", 0, 1),  # 04
        BitField("attr_DIAG_BSD_INVISIBLE", 0, 1),  # 02
        BitField("attr_DIAG_BSD_PROTECTED", 0, 1),  # 01

        # DIAG_DGOTYP_FNAME
        ConditionalField(
            StrLenField("name_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype == 114),
        # DIAG_DGOTYP_PUSHBUTTON_2 */
        ConditionalField(ByteField("pushbutton_v_length", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ByteField("pushbutton_v_height", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ShortField("pushbutton_function_code_offset", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ShortField("pushbutton_text_offset", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(StrField("pushbutton_text", ""),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(StrField("pushbutton_function_code", ""),
                         lambda pkt: pkt.etype in [115]),
        # DIAG_DGOTYP_TABSTRIP_BUTTON
        ConditionalField(ByteField("tabstripbutton_v_length", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ByteField("tabstripbutton_v_height", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ByteField("tabstripbutton_page_id", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_function_code_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_text_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_id_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_text", ""),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_function_code", ""),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_id", ""),
                         lambda pkt: pkt.etype in [116]),
        # DIAG_DGOTYP_XMLPROP
        ConditionalField(
            StrLenField("xmlprop_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype == 120),
        # DIAG_DGOTYP_EFIELD_1 or DIAG_DGOTYP_OFIELD_1 or DIAG_DGOTYP_KEYWORD_1
        ConditionalField(ByteField("field1_flag1", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(
            FieldLenField("field1_dlen",
                          None,
                          fmt="B",
                          length_of="field1_text"),
            lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(ByteField("field1_mlen", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(ShortField("field1_maxnrchars", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(
            StrLenField("field1_text",
                        "",
                        length_from=lambda pkt: pkt.field1_dlen),
            lambda pkt: pkt.etype in [121, 122, 123]),
        # DIAG_DGOTYP_FRAME_1
        ConditionalField(ShortField("frame_drows", 0),
                         lambda pkt: pkt.etype in [127]),
        ConditionalField(ShortField("frame_dcols", 0),
                         lambda pkt: pkt.etype in [127]),
        ConditionalField(
            StrLenField("frame_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 17),
            lambda pkt: pkt.etype in [127]),
        # DIAG_DGOTYP_RADIOBUTTON_3
        ConditionalField(ByteField("radiobutton_button", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_visible_label_length", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_event_id_off", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ByteField("radiobutton_event_id_len", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_text_off", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_text_length", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(
            StrLenField("radiobutton_text",
                        "",
                        length_from=lambda pkt: pkt.radiobutton_event_id_len +
                        pkt.radiobutton_text_length),
            lambda pkt: pkt.etype in [129]),
        # DIAG_DGOTYP_EFIELD_2 or DIAG_DGOTYP_OFIELD_2 or DIAG_DGOTYP_KEYWORD_2
        ConditionalField(ShortField("field2_flag1", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(
            FieldLenField("field2_dlen",
                          None,
                          fmt="B",
                          length_of="field2_text"),
            lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(ByteField("field2_mlen", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(ShortField("field2_maxnrchars", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(
            StrLenField("field2_text",
                        "",
                        length_from=lambda pkt: pkt.field2_dlen),
            lambda pkt: pkt.etype in [130, 131, 132]),
        # Remaining types
        ConditionalField(
            StrLenField("value",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype not in
            [114, 115, 116, 120, 121, 122, 123, 127, 129, 130, 131, 132]),
    ]

    def post_build(self, p, pay):
        if pay is None:
            pay = ''
        # Update the atom_length field (first 2 bytes) with the packet length
        p = pack("!H", len(p)) + p[2:]
        return p + pay
Esempio n. 16
0
class CDPMsgPortID(CDPMsgGeneric):
    name = "Port ID"
    fields_desc = [XShortEnumField("type", 0x0003, _cdp_tlv_types),
                   FieldLenField("len", None, "iface", "!H",
                                 adjust=lambda pkt, x: x + 4),
                   StrLenField("iface", "Port 1", length_from=lambda x:x.len - 4)]  # noqa: E501
Esempio n. 17
0
 def m2i(self, pkt, m):
     cls = self.get_class(pkt)
     if cls is not None:
         return cls(m)
     else:
         return StrLenField.m2i(self, pkt, m)
Esempio n. 18
0
class UTF8EncodedString(Packet):
    fields_desc = [
        FieldLenField("length", None, length_of="value"),
        StrLenField("value", "", length_from=lambda pkt: pkt.length)
    ]
Esempio n. 19
0
 def i2m(self, pkt, i):
     cls = self.get_class(pkt)
     if cls is not None:
         return str(i)
     else:
         return StrLenField.i2m(self, pkt, i)
Esempio n. 20
0
 def i2m(self, pkt, i):
     cls = self.get_class(pkt)
     if cls is not None:
         return str(i)
     else:
         return StrLenField.i2m(self, pkt, i)
Esempio n. 21
0
 def m2i(self, pkt, m):
     cls = self.get_class(pkt)
     if cls is not None:
         return cls(m)
     else:
         return StrLenField.m2i(self, pkt, m)
Esempio n. 22
0
class CAN(Packet):
    """A minimal implementation of the CANopen protocol, based on
    Wireshark dissectors. See https://wiki.wireshark.org/CANopen

    """
    fields_desc = [
        FlagsField('flags', 0, 3,
                   ['error', 'remote_transmission_request', 'extended'
                    ]),  # noqa: E501
        XBitField('identifier', 0, 29),
        FieldLenField('length', None, length_of='data', fmt='B'),
        ThreeBytesField('reserved', 0),
        StrLenField('data', '', length_from=lambda pkt: pkt.length),
    ]

    @staticmethod
    def inv_endianness(pkt):
        """ Invert the order of the first four bytes of a CAN packet

        This method is meant to be used specifically to convert a CAN packet
        between the pcap format and the socketCAN format

        :param pkt: str of the CAN packet
        :return: packet str with the first four bytes swapped
        """
        len_partial = len(pkt) - 4  # len of the packet, CAN ID excluded
        return struct.pack('<I{}s'.format(len_partial),
                           *struct.unpack('>I{}s'.format(len_partial),
                                          pkt))  # noqa: E501

    def pre_dissect(self, s):
        """ Implements the swap-bytes functionality when dissecting """
        if conf.contribs['CAN']['swap-bytes']:
            return CAN.inv_endianness(s)
        return s

    def self_build(self, field_pos_list=None):
        """ Implements the swap-bytes functionality when building

        this is based on a copy of the Packet.self_build default method.
        The goal is to affect only the CAN layer data and keep
        under layers (e.g LinuxCooked) unchanged
        """
        if self.raw_packet_cache is not None:
            for fname, fval in six.iteritems(self.raw_packet_cache_fields):
                if self.getfieldval(fname) != fval:
                    self.raw_packet_cache = None
                    self.raw_packet_cache_fields = None
                    break
            if self.raw_packet_cache is not None:
                if conf.contribs['CAN']['swap-bytes']:
                    return CAN.inv_endianness(self.raw_packet_cache)
                return self.raw_packet_cache
        p = b""
        for f in self.fields_desc:
            val = self.getfieldval(f.name)
            if isinstance(val, RawVal):
                sval = raw(val)
                p += sval
                if field_pos_list is not None:
                    field_pos_list.append(
                        (f.name, sval.encode('string_escape'), len(p),
                         len(sval)))  # noqa: E501
            else:
                p = f.addfield(self, p, val)
        if conf.contribs['CAN']['swap-bytes']:
            return CAN.inv_endianness(p)
        return p

    def extract_padding(self, p):
        return b'', p
Esempio n. 23
0
class LLTDAttributeDeviceUUID(LLTDAttribute):
    name = "LLTD Attribute - Device UUID"
    fields_desc = [
        FieldLenField("len", None, length_of="uuid", fmt="B"),
        StrLenField("uuid", b"\x00" * 16, length_from=lambda pkt: pkt.len),
    ]
Esempio n. 24
0
class PSKBinderEntry(Packet):
    name = "PSK Binder Entry"
    fields_desc = [
        FieldLenField("binder_len", None, fmt="B", length_of="binder"),
        StrLenField("binder", "", length_from=lambda pkt: pkt.binder_len)
    ]
class RadioTap(Packet):
    name = "RadioTap dummy"
    fields_desc = [
        ByteField('version', 0),
        ByteField('pad', 0),
        LEShortField('len', None),
        FlagsField('present', None, -32, _rt_present),  # noqa: E501
        # Extended presence mask
        ConditionalField(
            PacketListField("Ext", [], next_cls_cb=_next_radiotap_extpm),
            lambda pkt: pkt.present and pkt.present.Ext),  # noqa: E501
        # RadioTap fields - each starts with a _RadiotapReversePadField
        # to handle padding

        # TSFT
        ConditionalField(
            _RadiotapReversePadField(LELongField("mac_timestamp", 0)),
            lambda pkt: pkt.present and pkt.present.TSFT),
        # Flags
        ConditionalField(
            _RadiotapReversePadField(FlagsField("Flags", None, -8, _rt_flags)),
            lambda pkt: pkt.present and pkt.present.Flags),
        # Rate
        ConditionalField(_RadiotapReversePadField(ByteField("Rate", 0)),
                         lambda pkt: pkt.present and pkt.present.Rate),
        # Channel
        ConditionalField(_RadiotapReversePadField(LEShortField("Channel", 0)),
                         lambda pkt: pkt.present and pkt.present.Channel),
        ConditionalField(
            FlagsField("ChannelFlags", None, -16, _rt_channelflags),
            lambda pkt: pkt.present and pkt.present.Channel),
        # dBm_AntSignal
        ConditionalField(
            _RadiotapReversePadField(_dbmField("dBm_AntSignal", -256)),
            lambda pkt: pkt.present and pkt.present.dBm_AntSignal),
        # dBm_AntNoise
        ConditionalField(
            _RadiotapReversePadField(_dbmField("dBm_AntNoise", -256)),
            lambda pkt: pkt.present and pkt.present.dBm_AntNoise),
        # Lock_Quality
        ConditionalField(
            _RadiotapReversePadField(LEShortField("Lock_Quality", 0), ),
            lambda pkt: pkt.present and pkt.present.Lock_Quality),
        # Antenna
        ConditionalField(_RadiotapReversePadField(ByteField("Antenna", 0)),
                         lambda pkt: pkt.present and pkt.present.Antenna),
        # RX Flags
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("RXFlags", None, -16, _rt_rxflags)),
            lambda pkt: pkt.present and pkt.present.RXFlags),
        # TX Flags
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("TXFlags", None, -16, _rt_txflags)),
            lambda pkt: pkt.present and pkt.present.TXFlags),
        # ChannelPlus
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("ChannelFlags2", None, -32, _rt_channelflags2)),
            lambda pkt: pkt.present and pkt.present.ChannelPlus),
        ConditionalField(LEShortField("ChannelFrequency", 0),
                         lambda pkt: pkt.present and pkt.present.ChannelPlus),
        ConditionalField(ByteField("ChannelNumber", 0),
                         lambda pkt: pkt.present and pkt.present.ChannelPlus),
        # MCS
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("knownMCS", None, -8, _rt_knownmcs)),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitField("Ness_LSB", 0, 1),
                         lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitField("STBC_streams", 0, 2),
                         lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitEnumField("FEC_type", 0, 1, {
            0: "BCC",
            1: "LDPC"
        }), lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("HT_format", 0, 1, {
                0: "mixed",
                1: "greenfield"
            }), lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("guard_interval", 0, 1, {
                0: "Long_GI",
                1: "Short_GI"
            }),  # noqa: E501
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitEnumField("MCS_bandwidth", 0, 2, _rt_bandwidth),
                         lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(ByteField("MCS_index", 0),
                         lambda pkt: pkt.present and pkt.present.MCS),
        # A_MPDU
        ConditionalField(_RadiotapReversePadField(LEIntField("A_MPDU_ref", 0)),
                         lambda pkt: pkt.present and pkt.present.A_MPDU),
        ConditionalField(
            FlagsField("A_MPDU_flags", None, -32, _rt_a_mpdu_flags),
            lambda pkt: pkt.present and pkt.present.A_MPDU),
        # VHT
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("KnownVHT", None, -16, _rt_knownvht)),
            lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(FlagsField("PresentVHT", None, -8, _rt_presentvht),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(ByteEnumField("VHT_bandwidth", 0, _rt_vhtbandwidth),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(StrFixedLenField("mcs_nss", 0, length=5),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(ByteField("GroupID", 0),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(ShortField("PartialAID", 0),
                         lambda pkt: pkt.present and pkt.present.VHT),
        # timestamp
        ConditionalField(_RadiotapReversePadField(LELongField("timestamp", 0)),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(LEShortField("ts_accuracy", 0),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(ByteField("ts_position", 0),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(ByteField("ts_flags", 0),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        # HE - XXX not complete
        ConditionalField(_RadiotapReversePadField(ShortField("he_data1", 0)),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data2", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data3", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data4", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data5", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data6", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        # HE_MU
        ConditionalField(
            _RadiotapReversePadField(LEShortField("hemu_flags1", 0)),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(LEShortField("hemu_flags2", 0),
                         lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(
            FieldListField("RU_channel1", [],
                           ByteField,
                           count_from=lambda x: 4),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(
            FieldListField("RU_channel2", [],
                           ByteField,
                           count_from=lambda x: 4),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        # HE_MU_other_user
        ConditionalField(
            _RadiotapReversePadField(LEShortField("hemuou_per_user_1",
                                                  0x7fff)),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            LEShortField("hemuou_per_user_2", 0x003f),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            ByteField("hemuou_per_user_position", 0),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            FlagsField("hemuou_per_user_known", 0, -16,
                       _rt_hemuother_per_user_known),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        # L_SIG
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("lsig_data1", 0, -16, ["rate", "length"])),
            lambda pkt: pkt.present and pkt.present.L_SIG),
        ConditionalField(BitField("lsig_length", 0, 12),
                         lambda pkt: pkt.present and pkt.present.L_SIG),
        ConditionalField(BitField("lsig_rate", 0, 4),
                         lambda pkt: pkt.present and pkt.present.L_SIG),
        # Remaining
        StrLenField(
            'notdecoded',
            "",
            length_from=lambda pkt: max(pkt.len - pkt._tmp_dissect_pos, 0))
    ]

    def guess_payload_class(self, payload):
        if self.present and self.present.Flags and self.Flags.FCS:
            return Dot11FCS
        return Dot11

    def post_build(self, p, pay):
        if self.len is None:
            p = p[:2] + struct.pack("!H", len(p))[::-1] + p[4:]
        return p + pay
Esempio n. 26
0
class IE_ProtocolConfigurationOptions(IE_Base):
    name = "Protocol Configuration Options"
    fields_desc = [ByteEnumField("ietype", 132, IEType),
                   ShortField("length", 4),
                   StrLenField("Protocol_Configuration", "",
                               length_from=lambda x: x.length)]
Esempio n. 27
0
class PPP_LCP_Callback_Option(PPP_LCP_Option):
    fields_desc = [ByteEnumField("type", 13, _PPP_lcp_optiontypes),
                   FieldLenField("len", None, fmt="B", length_of="message",
                                 adjust=lambda p, x:x+3),
                   ByteEnumField("operation", 0, _PPP_lcp_callback_operations),
                   StrLenField("message", "", length_from=lambda p:p.len-3)]
Esempio n. 28
0
class MQTTConnect(Packet):
    name = "MQTT connect"
    fields_desc = [
        FieldLenField("length", None, length_of="protoname"),
        StrLenField("protoname", "", length_from=lambda pkt: pkt.length),
        ByteEnumField("protolevel", 5, PROTOCOL_LEVEL),
        BitEnumField("usernameflag", 0, 1, {
            0: 'Disabled',
            1: 'Enabled'
        }),
        BitEnumField("passwordflag", 0, 1, {
            0: 'Disabled',
            1: 'Enabled'
        }),
        BitEnumField("willretainflag", 0, 1, {
            0: 'Disabled',
            1: 'Enabled'
        }),
        BitEnumField("willQOSflag", 0, 2, QOS_LEVEL),
        BitEnumField("willflag", 0, 1, {
            0: 'Disabled',
            1: 'Enabled'
        }),
        BitEnumField("cleansess", 0, 1, {
            0: 'Disabled',
            1: 'Enabled'
        }),
        BitEnumField("reserved", 0, 1, {
            0: 'Disabled',
            1: 'Enabled'
        }),
        ShortField("klive", 0),

        #CONNECT PROPERTIES
        FieldLenField("proplen", None, fmt='B', length_of="properties"),
        ConditionalField(
            PacketListField("properties", [],
                            pkt_cls=MQTTProperty,
                            length_from=lambda pkt: pkt.proplen),
            lambda pkt: pkt.proplen != 0),
        FieldLenField("clientIdlen", None, length_of="clientId"),
        StrLenField("clientId", "", length_from=lambda pkt: pkt.clientIdlen),
        # Payload with optional fields depending on the flags

        # WILL PROPERTIES
        ConditionalField(
            FieldLenField("willproplen",
                          None,
                          fmt='B',
                          length_of="willproperties"),
            lambda pkt: pkt.willflag == 1),
        ConditionalField(
            PacketListField("willproperties", [],
                            pkt_cls=MQTTWillProperty,
                            length_from=lambda pkt: pkt.willproplen),
            lambda pkt: pkt.willflag == 1),
        ConditionalField(FieldLenField("wtoplen", None, length_of="willtopic"),
                         lambda pkt: pkt.willflag == 1),
        ConditionalField(
            StrLenField("willtopic", "", length_from=lambda pkt: pkt.wtoplen),
            lambda pkt: pkt.willflag == 1),
        ConditionalField(FieldLenField("wmsglen", None, length_of="willmsg"),
                         lambda pkt: pkt.willflag == 1),
        ConditionalField(
            StrLenField("willmsg", "", length_from=lambda pkt: pkt.wmsglen),
            lambda pkt: pkt.willflag == 1),
        ConditionalField(FieldLenField("userlen", None, length_of="username"),
                         lambda pkt: pkt.usernameflag == 1),
        ConditionalField(
            StrLenField("username", "", length_from=lambda pkt: pkt.userlen),
            lambda pkt: pkt.usernameflag == 1),
        ConditionalField(FieldLenField("passlen", None, length_of="password"),
                         lambda pkt: pkt.passwordflag == 1),
        ConditionalField(
            StrLenField("password", "", length_from=lambda pkt: pkt.passlen),
            lambda pkt: pkt.passwordflag == 1),
    ]
Esempio n. 29
0
class Dot11Elt(Packet):
    name = "802.11 Information Element"
    fields_desc = [
        ByteEnumField("ID", 0, _dot11_info_elts_ids),
        FieldLenField("len", None, "info", "B"),
        StrLenField("info", "", length_from=lambda x: x.len, max_length=255)
    ]

    def mysummary(self):
        if self.ID == 0:
            ssid = repr(self.info)
            if ssid[:2] in ['b"', "b'"]:
                ssid = ssid[1:]
            return "SSID=%s" % ssid, [Dot11]
        else:
            return ""

    registered_ies = {}

    @classmethod
    def register_variant(cls):
        cls.registered_ies[cls.ID.default] = cls

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt:
            _id = orb(_pkt[0])
            if _id == 221:
                oui_a = orb(_pkt[2])
                oui_b = orb(_pkt[3])
                oui_c = orb(_pkt[4])
                if oui_a == 0x00 and oui_b == 0x50 and oui_c == 0xf2:
                    # MS OUI
                    type_ = orb(_pkt[5])
                    if type_ == 0x01:
                        # MS WPA IE
                        return Dot11EltMicrosoftWPA
                    else:
                        return Dot11EltVendorSpecific
                else:
                    return Dot11EltVendorSpecific
            else:
                return cls.registered_ies.get(_id, cls)
        return cls

    def haslayer(self, cls):
        if cls == "Dot11Elt":
            if isinstance(self, Dot11Elt):
                return True
        elif issubtype(cls, Dot11Elt):
            if isinstance(self, cls):
                return True
        return super(Dot11Elt, self).haslayer(cls)

    def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt):
        return super(Dot11Elt, self).getlayer(cls,
                                              nb=nb,
                                              _track=_track,
                                              _subclass=True,
                                              **flt)

    def post_build(self, p, pay):
        if self.len is None:
            p = p[:1] + chb(len(p) - 2) + p[2:]
        return p + pay
class Dot11Elt(Packet):
    __slots__ = ["info"]
    name = "802.11 Information Element"
    fields_desc = [
        ByteEnumField("ID", 0, _dot11_info_elts_ids),
        FieldLenField("len", None, "info", "B"),
        StrLenField("info", "", length_from=lambda x: x.len, max_length=255)
    ]
    show_indent = 0

    def mysummary(self):
        if self.ID == 0:
            ssid = repr(self.info)
            if ssid[:2] in ['b"', "b'"]:
                ssid = ssid[1:]
            return "SSID", [Dot11]
        else:
            return ""

    registered_ies = {}

    @classmethod
    def register_variant(cls):
        cls.registered_ies[cls.ID.default] = cls

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt:
            _id = orb(_pkt[0])
            if _id == 221:
                oui_a = orb(_pkt[2])
                oui_b = orb(_pkt[3])
                oui_c = orb(_pkt[4])
                if oui_a == 0x00 and oui_b == 0x50 and oui_c == 0xf2:
                    # MS OUI
                    type_ = orb(_pkt[5])
                    if type_ == 0x01:
                        # MS WPA IE
                        return Dot11EltMicrosoftWPA
                    else:
                        return Dot11EltVendorSpecific
                else:
                    return Dot11EltVendorSpecific
            else:
                return cls.registered_ies.get(_id, cls)
        return cls

    def haslayer(self, cls):
        if cls == "Dot11Elt":
            if isinstance(self, Dot11Elt):
                return True
        elif issubtype(cls, Dot11Elt):
            if isinstance(self, cls):
                return True
        return super(Dot11Elt, self).haslayer(cls)

    def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt):
        return super(Dot11Elt, self).getlayer(cls,
                                              nb=nb,
                                              _track=_track,
                                              _subclass=True,
                                              **flt)

    def pre_dissect(self, s):
        # Backward compatibility: add info to all elements
        # This allows to introduce new Dot11Elt classes without breaking
        # previous code
        if len(s) >= 3:
            length = orb(s[1])
            if length > 0 and length <= 255:
                self.info = s[2:2 + length]
        return s

    def post_build(self, p, pay):
        if self.len is None:
            p = p[:1] + chb(len(p) - 2) + p[2:]
        return p + pay
Esempio n. 31
0
class ServerDHParams(_GenericTLSSessionInheritance):
    """
    ServerDHParams for FFDH-based key exchanges, as defined in RFC 5246/7.4.3.

    Either with .fill_missing() or .post_dissection(), the server_kx_privkey or
    server_kx_pubkey of the TLS context are updated according to the
    parsed/assembled values. It is the user's responsibility to store and
    restore the original values if he wants to keep them. For instance, this
    could be done between the writing of a ServerKeyExchange and the receiving
    of a ClientKeyExchange (which includes secret generation).
    """
    name = "Server FFDH parameters"
    fields_desc = [FieldLenField("dh_plen", None, length_of="dh_p"),
                   StrLenField("dh_p", "",
                               length_from=lambda pkt: pkt.dh_plen),
                   FieldLenField("dh_glen", None, length_of="dh_g"),
                   StrLenField("dh_g", "",
                               length_from=lambda pkt: pkt.dh_glen),
                   FieldLenField("dh_Yslen", None, length_of="dh_Ys"),
                   StrLenField("dh_Ys", "",
                               length_from=lambda pkt: pkt.dh_Yslen)]

    @crypto_validator
    def fill_missing(self):
        """
        We do not want TLSServerKeyExchange.build() to overload and recompute
        things every time it is called. This method can be called specifically
        to have things filled in a smart fashion.

        Note that we do not expect default_params.g to be more than 0xff.
        """
        s = self.tls_session

        default_params = _ffdh_groups['modp2048'][0].parameter_numbers()
        default_mLen = _ffdh_groups['modp2048'][1]

        if not self.dh_p:
            self.dh_p = pkcs_i2osp(default_params.p, default_mLen // 8)
        if self.dh_plen is None:
            self.dh_plen = len(self.dh_p)

        if not self.dh_g:
            self.dh_g = pkcs_i2osp(default_params.g, 1)
        if self.dh_glen is None:
            self.dh_glen = 1

        p = pkcs_os2ip(self.dh_p)
        g = pkcs_os2ip(self.dh_g)
        real_params = dh.DHParameterNumbers(p, g).parameters(default_backend())

        if not self.dh_Ys:
            s.server_kx_privkey = real_params.generate_private_key()
            pubkey = s.server_kx_privkey.public_key()
            y = pubkey.public_numbers().y
            self.dh_Ys = pkcs_i2osp(y, pubkey.key_size // 8)
        # else, we assume that the user wrote the server_kx_privkey by himself
        if self.dh_Yslen is None:
            self.dh_Yslen = len(self.dh_Ys)

        if not s.client_kx_ffdh_params:
            s.client_kx_ffdh_params = real_params

    @crypto_validator
    def register_pubkey(self):
        """
        XXX Check that the pubkey received is in the group.
        """
        p = pkcs_os2ip(self.dh_p)
        g = pkcs_os2ip(self.dh_g)
        pn = dh.DHParameterNumbers(p, g)

        y = pkcs_os2ip(self.dh_Ys)
        public_numbers = dh.DHPublicNumbers(y, pn)

        s = self.tls_session
        s.server_kx_pubkey = public_numbers.public_key(default_backend())

        if not s.client_kx_ffdh_params:
            s.client_kx_ffdh_params = pn.parameters(default_backend())

    def post_dissection(self, r):
        try:
            self.register_pubkey()
        except ImportError:
            pass

    def guess_payload_class(self, p):
        """
        The signature after the params gets saved as Padding.
        This way, the .getfield() which _TLSServerParamsField inherits
        from PacketField will return the signature remain as expected.
        """
        return Padding
Esempio n. 32
0
class RadiusAttribute(Packet):
    """
    Implements a RADIUS attribute (RFC 2865). Every specific RADIUS attribute
    class should inherit from this one.
    """

    name = "Radius Attribute"
    fields_desc = [
        ByteEnumField("type", 1, _radius_attribute_types),
        FieldLenField("len",
                      None,
                      "value",
                      "B",
                      adjust=lambda pkt, x: len(pkt.value) + 2),
        StrLenField("value", "", length_from=lambda pkt: pkt.len - 2)
    ]

    registered_attributes = {}

    @classmethod
    def register_variant(cls):
        """
        Registers the RADIUS attributes defined in this module.
        """

        if hasattr(cls, "val"):
            cls.registered_attributes[cls.val] = cls
        else:
            cls.registered_attributes[cls.type.default] = cls

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        """
        Returns the right RadiusAttribute class for the given data.
        """

        if _pkt:
            attr_type = orb(_pkt[0])
            return cls.registered_attributes.get(attr_type, cls)
        return cls

    def haslayer(self, cls):
        if cls == "RadiusAttribute":
            if isinstance(self, RadiusAttribute):
                return True
        elif issubtype(cls, RadiusAttribute):
            if isinstance(self, cls):
                return True
        return super(RadiusAttribute, self).haslayer(cls)

    def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt):
        return super(RadiusAttribute, self).getlayer(cls,
                                                     nb=nb,
                                                     _track=_track,
                                                     _subclass=True,
                                                     **flt)

    def post_build(self, p, pay):
        length = self.len
        if length is None:
            length = len(p)
            p = p[:1] + struct.pack("!B", length) + p[2:]
        return p

    def guess_payload_class(self, _):
        return Padding
Esempio n. 33
0
class ECCurvePkt(Packet):
    name = "Elliptic Curve"
    fields_desc = [FieldLenField("alen", None, length_of="a", fmt="B"),
                   StrLenField("a", "", length_from=lambda pkt: pkt.alen),
                   FieldLenField("blen", None, length_of="b", fmt="B"),
                   StrLenField("b", "", length_from=lambda pkt: pkt.blen)]
Esempio n. 34
0
class ServerECDHNamedCurveParams(_GenericTLSSessionInheritance):
    name = "Server ECDH parameters - Named Curve"
    fields_desc = [ByteEnumField("curve_type", 3, _tls_ec_curve_types),
                   ShortEnumField("named_curve", None, _tls_named_curves),
                   FieldLenField("pointlen", None,
                                 length_of="point", fmt="B"),
                   StrLenField("point", None,
                               length_from=lambda pkt: pkt.pointlen)]

    @crypto_validator
    def fill_missing(self):
        """
        We do not want TLSServerKeyExchange.build() to overload and recompute
        things every time it is called. This method can be called specifically
        to have things filled in a smart fashion.

        XXX We should account for the point_format (before 'point' filling).
        """
        s = self.tls_session

        if self.curve_type is None:
            self.curve_type = _tls_ec_curve_types["named_curve"]

        if self.named_curve is None:
            self.named_curve = 23

        curve_group = self.named_curve
        if curve_group not in _tls_named_curves:
            # this fallback is arguable
            curve_group = 23  # default to secp256r1
        s.server_kx_privkey = _tls_named_groups_generate(curve_group)

        if self.point is None:
            self.point = _tls_named_groups_pubbytes(
                s.server_kx_privkey
            )

        # else, we assume that the user wrote the server_kx_privkey by himself
        if self.pointlen is None:
            self.pointlen = len(self.point)

        if not s.client_kx_ecdh_params:
            s.client_kx_ecdh_params = curve_group

    @crypto_validator
    def register_pubkey(self):
        """
        XXX Support compressed point format.
        XXX Check that the pubkey received is on the curve.
        """
        # point_format = 0
        # if self.point[0] in [b'\x02', b'\x03']:
        #    point_format = 1

        s = self.tls_session
        s.server_kx_pubkey = _tls_named_groups_import(
            self.named_curve,
            self.point
        )

        if not s.client_kx_ecdh_params:
            s.client_kx_ecdh_params = self.named_curve

    def post_dissection(self, r):
        try:
            self.register_pubkey()
        except ImportError:
            pass

    def guess_payload_class(self, p):
        return Padding
Esempio n. 35
0
class PPP_ECP_Option_OUI(PPP_ECP_Option):
    fields_desc = [ByteEnumField("type", 0, _PPP_ecpopttypes),
                   FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p, x:x+6),
                   StrFixedLenField("oui", "", 3),
                   ByteField("subtype", 0),
                   StrLenField("data", "", length_from=lambda p:p.len-6)]