PIDL TODO subcontext 0xFFFFFC01
authorStefan Metzmacher <metze@samba.org>
Mon, 21 Mar 2022 11:39:06 +0000 (12:39 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 25 Mar 2022 14:28:46 +0000 (15:28 +0100)
epan/dissectors/packet-dcerpc-ndr.c
tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm

index c4640da00fae0117f182091cd564ed92fffbb9fe..be212f36c49e4741deeea5faaff88ec20134de86 100644 (file)
@@ -562,6 +562,93 @@ dissect_ndr_ctx_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
     return offset + 20;
 }
 
+static int
+dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
+{
+       proto_tree *tree;
+       guint8 val;
+
+       tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
+
+       val = tvb_get_guint8(tvb, offset);
+       proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
+
+       offset++;
+
+       if (drep) {
+               *drep = val;
+       }
+
+       return offset;
+}
+
+        { &hf_ndr__midl_blob_len, {
+                "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
+                NULL, 0, "Length of NDR encoded data that follows", HFILL }},
+        { &hf_krb_midl_fill_bytes, {
+                "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
+                NULL, 0, "Just some fill bytes", HFILL }},
+        { &hf_type_serialization_version, {
+        "Version", "ndr.type_serialization.version", FT_UINT8, BASE_DEC,
+        NULL, 0, "Version of pickling", HFILL }},
+        { &hf_krb_midl_hdr_len, {
+                "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
+                NULL, 0, "Length of header", HFILL }},
+/*
+ * MS-RPCE
+ * - 2.2.6 Type Serialization Version 1
+ * - 2.2.7 Type Serialization Version 2
+ */
+int
+dissect_ndr_type_serialization(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
+{
+        proto_tree *tree;
+
+        tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_ndr_type_serialization_v1, NULL, "TSV1 header");
+
+        /* modified DREP field that is used for stuff that is transporetd ontop
+           of non dcerpc
+        */
+        proto_tree_add_item(tree, hf_ndr_type_serialization_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+        offset++;
+
+        offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
+
+
+        proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+        offset+=2;
+
+        proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+        offset += 4;
+
+        /* length of blob that follows */
+        proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+        offset += 8;
+
+        return offset;
+}
+
+       guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
+       static dcerpc_info di;      /* fake dcerpc_info struct */
+       static dcerpc_call_value call_data;
+
+       item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
+       tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
+
+       /* skip the first 16 bytes, they are some magic created by the idl
+        * compiler   the first 4 bytes might be flags?
+        */
+       offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
+
+       /* the PAC_LOGON_INFO blob */
+       /* fake whatever state the dcerpc runtime support needs */
+       di.conformant_run=0;
+       /* we need di->call_data->flags.NDR64 == 0 */
+       di.call_data=&call_data;
+       init_ndr_pointer_list(&di);
+       offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
+                                                                       netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
+                                                                       "PAC_LOGON_INFO:", -1);
 /*
  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
  *
index 28844fdc3c610ea86df8aff79ee70980d101f524..189fdf09c7d1053e51d2943e693fe64d6a1a0f82 100644 (file)
@@ -401,6 +401,40 @@ sub ElementLevel($$$$$$$$)
                        $call =~ s/\@PARAM\@/$param/g;
                        $self->pidl_code($call);
                }
+       } elsif ($_->{TYPE} eq "SUBCONTEXT" and $l->{HEADER_SIZE} == 0xFFFFFC01) {
+               my $varswitch;
+               if (has_property($e, "switch_is")) {
+                       $varswitch = $e->{PROPERTIES}->{switch_is};
+               }
+               my $num_bits = 32;
+               my $hf2 = $self->register_hf_field($hf."_", "Subcontext length", "$ifname.$pn.$_->{NAME}subcontext", "FT_UINT$num_bits", "BASE_HEX", "NULL", 0, "");
+               $num_bits = 3264 if ($num_bits == 32);
+               $self->{hf_used}->{$hf2} = 1;
+               $self->pidl_code("guint$num_bits size;");
+               $self->pidl_code("int conformant = di->conformant_run;");
+               $self->pidl_code("tvbuff_t *subtvb;");
+               $self->pidl_code("");
+               # We need to be able to dissect the length of the context in every case
+               # and conformant run skips the dissections of scalars ...
+               $self->pidl_code("if (!conformant) {");
+               $self->indent;
+               $self->pidl_code("guint32 saved_flags = di->call_data->flags;");
+               $self->pidl_code("offset = dissect_ndr_uint$num_bits(tvb, offset, pinfo, tree, di, drep, $hf2, &size);");
+               # This is a subcontext, there is normally no such thing as
+               # 64 bit NDR is subcontext so we clear the flag so that we can
+               # continue to dissect handmarshalled stuff with pidl
+               $self->pidl_code("di->call_data->flags &= ~DCERPC_IS_NDR64;");
+
+               $self->pidl_code("subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);");
+               if ($param ne 0) {
+                       $self->pidl_code("$myname\_(subtvb, 0, pinfo, tree, di, drep, $param);");
+               } else {
+                       $self->pidl_code("$myname\_(subtvb, 0, pinfo, tree, di, drep);");
+               }
+               $self->pidl_code("offset += (int)size;");
+               $self->pidl_code("di->call_data->flags = saved_flags;");
+               $self->deindent;
+               $self->pidl_code("}");
        } elsif ($_->{TYPE} eq "SUBCONTEXT") {
                my $varswitch;
                if (has_property($e, "switch_is")) {