keys array, but no keys subtree and no value
[wireshark-sm.git] / epan / dissectors / pidl / drsuapi / drsuapi.cnf
blob554764f9d39c3c2c1fd22d5983a844387768577e
1 # Conformance file for drsuapi
3 MANUAL drsuapi_dissect_element_DsReplicaObjectIdentifier_sid
4 MANUAL drsuapi_dissect_element_DsReplicaAttribute_attid
5 MANUAL drsuapi_dissect_element_DsAttributeValue_blob_
6 MANUAL drsuapi_dissect_struct_DsReplicaAttribute
7 MANUAL drsuapi_dissect_struct_DsReplicaObject
8 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey3_value
9 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey3_value_
10 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey4_value
11 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey4_value_
12 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_keys
13 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_old_keys
14 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys
15 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_
16 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys
17 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_
18 MANUAL drsuapi_dissect_struct_package_PrimaryKerberosKey3
19 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_keys
20 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_service_keys
21 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_old_keys
22 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_older_keys
23 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys
24 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_
25 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys
26 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_
27 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys
28 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_
29 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys
30 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_
31 MANUAL drsuapi_dissect_struct_package_PrimaryKerberosKey4
32 MANUAL drsuapi_dissect_element_package_PrimaryKerberosBlob_version
33 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_name_len
34 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_data_len
35 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_name
36 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_data
37 MANUAL drsuapi_dissect_struct_supplementalCredentialsPackage
38 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix_
39 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages
40 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_packages
41 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_
42 MANUAL drsuapi_dissect_struct_supplementalCredentialsSubBlob
43 MANUAL drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size
44 MANUAL drsuapi_dissect_element_supplementalCredentialsBlob_sub
45 MANUAL drsuapi_dissect_struct_supplementalCredentialsBlob
47 CODE START
49   #include <wsutil/wsgcrypt.h>
50   #include <epan/expert.h>
51   #include <epan/strutil.h>
52   #define KERBEROS_METZE 1
53   #include "packet-kerberos.h"
55 static int
56 drsuapi_dissect_element_DsReplicaObjectIdentifier_sid(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
58         /*manual*/
59         dcerpc_ptr_stack *ptr = di->ptr_stack;
60         int start_offset = offset;
61         guint32 rid = 0;
63         di->hf_index = hf_drsuapi_drsuapi_DsReplicaObjectIdentifier_sid;
65         offset = dissect_ndr_nt_SID28(tvb, offset, pinfo, tree, di, drep);
66         if (ptr == NULL) {
67                 return offset;
68         }
70         if (offset > start_offset) {
71                 dissect_ndr_uint32(tvb, start_offset + 24, pinfo, tree, di, drep, -1, &rid);
72         }
74         ptr->private_data.val64 = rid;
75         if (tree == NULL) return offset;
77       proto_tree_add_debug_text(tree,
78                         "METZE frame:%d drsuapi_dissect_element_DsReplicaObjectIdentifier_sid RID:%d auth_info->session_key=%s",
79                         pinfo->fd->num, rid,
80                         di->auth_session_key != NULL ?
81                         di->auth_session_key->id_str : "NO");
82         return offset;
85 static int
86 drsuapi_dissect_element_DsReplicaAttribute_attid(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
88         /*manual*/
89         dcerpc_ptr_stack *ptr = di->ptr_stack;
90         guint32 rid = 0;
91         guint32 attid = 0;
92         offset = drsuapi_dissect_enum_DsAttributeId(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsReplicaAttribute_attid, &attid);
93         if (ptr == NULL) {
94                 return offset;
95         }
96         if (ptr->parent == NULL) {
97                 return offset;
98         }
99         rid = ptr->parent->private_data.val64;
100         ptr->private_data.val64 = attid;
101         if (tree == NULL) return offset;
102       proto_tree_add_debug_text(tree,
103                         "METZE frame:%d drsuapi_dissect_element_DsReplicaAttribute_attid RID:%d ATTID:0x%08X auth_info->session_key=%s",
104                         pinfo->fd->num,
105                         rid, attid,
106                         di->auth_session_key != NULL ?
107                         di->auth_session_key->id_str : "NO");
109         return offset;
112 static int
113 drsuapi_dissect_element_package_PrimaryKerberosBlob_version(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *version)
115         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosBlob_version, 0, version);
117         return offset;
120 static int
121 drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_keys)
123         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_keys, 0, num_keys);
125         return offset;
128 static int
129 drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_old_keys)
131         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_old_keys, 0, num_old_keys);
133         return offset;
136 static int
137 drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_keys)
139         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
142 static int
143 drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_keys)
145         guint32 i;
147         for (i=0; i < *num_keys; i++) {
148                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_keys, 0);
149         }
151         return offset;
154 static int
155 drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_old_keys)
157         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
160 static int
161 drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_old_keys)
163         guint32 i;
165         for (i=0; i < *num_old_keys; i++) {
166                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_old_keys, 0);
167         }
169         return offset;
173 drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)
175         guint32 value_len = 0;
176         proto_item *item = NULL;
177         proto_tree *tree = NULL;
178         int old_offset;
179         guint32 keytype;
180         guint32 value_ofs;
182         ALIGN_TO_4_BYTES;
184         old_offset = offset;
186         if (parent_tree) {
187                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
188                 tree = proto_item_add_subtree(item, ett_drsuapi_package_PrimaryKerberosKey3);
189         }
191         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved1(tvb, offset, pinfo, tree, di, drep);
193         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved2(tvb, offset, pinfo, tree, di, drep);
195         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved3(tvb, offset, pinfo, tree, di, drep);
197         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_keytype(tvb, offset, pinfo, tree, di, drep);
198         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_keytype, 0, &keytype);
200         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
201         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_len, 0, &value_len);
203         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_ofs(tvb, offset, pinfo, tree, di, drep);
204         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_ofs, 0, &value_ofs);
206         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value(tvb, offset, pinfo, tree, di, drep, &value_len);
208         proto_item_set_len(item, offset-old_offset);
211         if (di->call_data->flags & DCERPC_IS_NDR64) {
212                 ALIGN_TO_4_BYTES;
213         }
215         return offset;
218 static int
219 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_keys)
221         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_keys, 0, num_keys);
223         return offset;
226 static int
227 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_service_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_service_keys)
229         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_service_keys, 0, num_service_keys);
231         return offset;
234 static int
235 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_old_keys)
237         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_old_keys, 0, num_old_keys);
239         return offset;
242 static int
243 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_older_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_older_keys)
245         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_older_keys, 0, num_older_keys);
247         return offset;
250 static int
251 drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_keys)
253         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
256 static int
257 drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_keys)
259         guint32 i;
261         for (i=0; i < *num_keys; i++) {
262                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_keys, 0);
263         }
265         return offset;
268 static int
269 drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_service_keys)
271         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_(tvb, offset, pinfo, tree, di, drep, num_service_keys);
274 static int
275 drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_service_keys)
277         guint32 i;
279         for (i=0; i < *num_service_keys; i++) {
280                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_service_keys, 0);
281         }
283         return offset;
286 static int
287 drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_old_keys)
289         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
292 static int
293 drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_old_keys)
295         guint32 i;
297         for (i=0; i < *num_old_keys; i++) {
298                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_old_keys, 0);
299         }
301         return offset;
304 static int
305 drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_older_keys)
307         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_(tvb, offset, pinfo, tree, di, drep, num_older_keys);
310 static int
311 drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_older_keys)
313         guint32 i;
315         for (i=0; i < *num_older_keys; i++) {
316                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_older_keys, 0);
317         }
319         return offset;
323 drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)
325         guint32 value_len = 0;
326         proto_item *item = NULL;
327         proto_tree *tree = NULL;
328         int old_offset;
329         guint32 keytype;
330         guint32 value_ofs;
332         ALIGN_TO_4_BYTES;
334         old_offset = offset;
336         if (parent_tree) {
337                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
338                 tree = proto_item_add_subtree(item, ett_drsuapi_package_PrimaryKerberosKey4);
339         }
341         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved1(tvb, offset, pinfo, tree, di, drep);
343         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved2(tvb, offset, pinfo, tree, di, drep);
345         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved3(tvb, offset, pinfo, tree, di, drep);
347         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_iteration_count(tvb, offset, pinfo, tree, di, drep);
349         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_keytype(tvb, offset, pinfo, tree, di, drep);
350         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_keytype, 0, &keytype);
352         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
353         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_len, 0, &value_len);
355         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_ofs(tvb, offset, pinfo, tree, di, drep);
356         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_ofs, 0, &value_ofs);
358         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value(tvb, offset, pinfo, tree, di, drep, &value_len);
360         return offset;
362 static int
363 drsuapi_dissect_package_PrimaryKerberosBlob(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
365         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
366         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
367         static dcerpc_call_value call_data = { 0, };
369         /* fake whatever state the dcerpc runtime support needs */
370         di.conformant_run=0;
371         /* we need di->call_data->flags.NDR64 == 0 */
372         di.call_data=&call_data;
373         //init_ndr_pointer_list(&di);
374         di.ptr_stack = parent_di->ptr_stack;
375         return drsuapi_dissect_struct_package_PrimaryKerberosBlob(tvb, 0, pinfo, parent_tree, &di, drep,
376                                 hf_drsuapi_pkb_PrimaryKerberosBlob, 0);
379 typedef int (*package_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
381 static gboolean
382 drsuapi_GByteArray_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_)
384         GByteArray *bytes = (GByteArray *)user_data;
385         g_byte_array_free(bytes, TRUE);
386         /* unregister this callback */
387         return FALSE;
390 static int
391 drsuapi_dissect_element_supplementalCredentialsPackage_name_len(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *name_len)
393         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_name_len, 0, name_len);
395         return offset;
398 static int
399 drsuapi_dissect_element_supplementalCredentialsPackage_data_len(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *data_len)
401         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_data_len, 0, data_len);
403         return offset;
406 drsuapi_dissect_struct_supplementalCredentialsPackage(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)
408         proto_item *item = NULL;
409         proto_tree *tree = NULL;
410         int old_offset;
411         guint16 name_len = 0;
412         const char *name = NULL;
413         guint16 data_len = 0;
415         ALIGN_TO_2_BYTES;
417         old_offset = offset;
419         if (parent_tree) {
420                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
421                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsPackage);
422         }
424         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name_len(tvb, offset, pinfo, tree, di, drep, &name_len);
425         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data_len(tvb, offset, pinfo, tree, di, drep, &data_len);
426         offset = drsuapi_dissect_element_supplementalCredentialsPackage_reserved(tvb, offset, pinfo, tree, di, drep);
427 if (0) {
428  #if 0
429         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name(tvb, offset, pinfo, tree, di, drep, &name_len);
430  #endif
431 } else {
432         const guint8 *_name = NULL;
433         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_name,
434                                        tvb, offset, name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
435                                        wmem_packet_scope(), &_name);
436         name = (const char *)_name;
437         proto_item_append_text(item, ": %s", name);
438         offset += name_len;
440 if (0) {
441  #if 0
442         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data(tvb, offset, pinfo, tree, di, drep, &data_len);
443  #endif
444 } else {
445         const guint8 *_hexdata = NULL;
446         const char *hexdata = NULL;
447         tvbuff_t *tvbdata = NULL;
448         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_data,
449                                        tvb, offset, data_len, ENC_ASCII,
450                                        wmem_packet_scope(), &_hexdata);
451         hexdata = (const char *)_hexdata;
452         if (hexdata != NULL) {
453                 GByteArray *bytes = NULL;
455                 /* Convert key to raw bytes */
456                 bytes = g_byte_array_new();
457                 if (bytes != NULL) {
458                         gboolean res;
460                         wmem_register_callback(pinfo->pool, drsuapi_GByteArray_destroy_cb, bytes);
462                         res = hex_str_to_bytes(hexdata, bytes, FALSE);
463                         if (res) {
464                                 tvbdata = tvb_new_child_real_data(tvb,
465                                                                   bytes->data,
466                                                                   bytes->len,
467                                                                   bytes->len);
468                         }
469                 }
470         }
472         if (tvbdata != NULL) {
473                 struct {
474                         const char *name;
475                         package_dissector_fn_t fn;
476                 } packages[] = {
477                 {
478                         .name = "Primary:Kerberos-Newer-Keys",
479                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
480                 },{
481                         .name = "Primary:Kerberos",
482                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
483                 },{
484                         .name = NULL,
485                 }
486                 };
487                 size_t i = 0;
489                 for (i=0; packages[i].name != NULL; i++) {
490                         int cmp;
492                         cmp = strcmp(packages[i].name, name);
493                         if (cmp == 0) {
494                                 break;
495                         }
496                 }
498                 add_new_data_source(pinfo, tvbdata, name);
500                 if (packages[i].fn != NULL) {
501                         packages[i].fn(tvbdata, pinfo, tree, di);
502                 }
503         }
505         offset += data_len;
508         proto_item_set_len(item, offset-old_offset);
511         if (di->call_data->flags & DCERPC_IS_NDR64) {
512                 ALIGN_TO_2_BYTES;
513         }
515         return offset;
517 static int
518 drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
520         offset += 2; //PIDL_dissect_uint16(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_prefix, 0);
522         return offset;
525 static int
526 drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_packages)
528         dcerpc_ptr_stack *num_packages_ptr = di->ptr_stack;
530         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_num_packages, 0, num_packages);
531         if (num_packages_ptr != NULL) {
532                 num_packages_ptr->private_data.val64 = *num_packages;
533         }
535         return offset;
538 static int
539 drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_packages)
541         guint16 i;
543         for (i=0; i<*num_packages; i++) {
544                 offset = drsuapi_dissect_struct_supplementalCredentialsPackage(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_supplementalCredentialsSubBlob_packages,0);
545         }
547         return offset;
550 static int
551 drsuapi_dissect_element_supplementalCredentialsSubBlob_packages(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *num_packages)
553         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_(tvb,offset,pinfo,tree,di,drep,num_packages);
555         return offset;
559 drsuapi_dissect_struct_supplementalCredentialsSubBlob(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)
561         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
562         dcerpc_ptr_stack *num_packages_ptr = NULL;
563         proto_item *item = NULL;
564         proto_tree *tree = NULL;
565         int old_offset;
566         guint16 num_packages;
568         ALIGN_TO_3_BYTES;
570         old_offset = offset;
572         if (parent_tree) {
573                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
574                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsSubBlob);
575         }
577         num_packages_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
578         di->ptr_stack = num_packages_ptr;
580         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix(tvb, offset, pinfo, tree, di, drep);
582         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_signature(tvb, offset, pinfo, tree, di, drep);
584         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
586         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
588         di->ptr_stack = saved_ptr;
590         proto_item_set_len(item, offset-old_offset);
593         if (di->call_data->flags & DCERPC_IS_NDR64) {
594                 ALIGN_TO_3_BYTES;
595         }
597         return offset;
600 static int
601 drsuapi_dissect_element_supplementalCredentialsBlob_sub(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
603         int conformant = di->conformant_run;
604         tvbuff_t *subtvb;
606         if (!conformant) {
607                 guint32 saved_flags = di->call_data->flags;
608                 dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
609                 guint32 size = 0;
610                 if (ndr_size_ptr != NULL) {
611                         size = ndr_size_ptr->private_data.val64;
612                 }
613                 di->call_data->flags &= ~DCERPC_IS_NDR64;
614                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);
615                 drsuapi_dissect_element_supplementalCredentialsBlob_sub_(subtvb, 0, pinfo, tree, di, drep);
616                 offset += (int)size;
617                 di->call_data->flags = saved_flags;
618         }
620         return offset;
623 static int
624 drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
626         dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
627         guint32 ndr_size = 0;
629         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsBlob___ndr_size, 0, &ndr_size);
630         if (ndr_size_ptr != NULL) {
631                 ndr_size_ptr->private_data.val64 = ndr_size;
632         }
634         return offset;
638 drsuapi_dissect_struct_supplementalCredentialsBlob(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)
640         /*manual*/
641         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
642         dcerpc_ptr_stack *ndr_size_ptr = NULL;
643         proto_item *item = NULL;
644         proto_tree *tree = NULL;
645         int old_offset;
647         ALIGN_TO_4_BYTES;
649         old_offset = offset;
651         if (parent_tree) {
652                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
653                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsBlob);
654         }
656         ndr_size_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
657         di->ptr_stack = ndr_size_ptr;
659         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown1(tvb, offset, pinfo, tree, di, drep);
661         offset = drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size(tvb, offset, pinfo, tree, di, drep);
663         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown2(tvb, offset, pinfo, tree, di, drep);
665         offset = drsuapi_dissect_element_supplementalCredentialsBlob_sub(tvb, offset, pinfo, tree, di, drep);
667         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown3(tvb, offset, pinfo, tree, di, drep);
669         di->ptr_stack = saved_ptr;
671         proto_item_set_len(item, offset-old_offset);
674         if (di->call_data->flags & DCERPC_IS_NDR64) {
675                 ALIGN_TO_4_BYTES;
676         }
678         return offset;
680 static int
681 drsuapi_dissect_supplementalCredentials(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
683         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
684         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
685         static dcerpc_call_value call_data = { 0, };
687         /* fake whatever state the dcerpc runtime support needs */
688         di.conformant_run=0;
689         /* we need di->call_data->flags.NDR64 == 0 */
690         di.call_data=&call_data;
691         //init_ndr_pointer_list(&di);
692         di.ptr_stack = parent_di->ptr_stack;
693         return drsuapi_dissect_struct_supplementalCredentialsBlob(tvb, 0, pinfo, parent_tree, &di, drep,
694                                 hf_drsuapi_sch_supplementalCredentials, 0);
697 typedef int (*attr_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
699 static int
700 drsuapi_dissect_element_DsAttributeValue_blob_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
702         /*manual*/
703         dcerpc_ptr_stack *ptr = di->ptr_stack;
704         guint32 rid = 0;
705         guint32 attid = 0;
706         int start_offset = offset;
707         int length;
708         guint8 _confounder[16] = { 0, };
709         guint8 *confounder;
710         guint8 decryption_key[HASH_MD5_LENGTH] = { 0, };
711         gcry_cipher_hd_t rc4_handle = NULL;
712         gcry_buffer_t iov[2] = { {0, },};
713         gcry_error_t err;
714         guint8 *buf = NULL;
715         int buf_len;
716         tvbuff_t *plain_tvb = NULL;
717         gboolean rid_crypt = FALSE;
718         attr_dissector_fn_t attr_dissector_fn = NULL;
720         offset = dissect_ndr_datablob(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsAttributeValue_blob, 0);
721         if (ptr == NULL) {
722                 return offset;
723         }
724         if (ptr->parent == NULL) {
725                 return offset;
726         }
728         rid = ptr->parent->private_data.val64;
729         attid = ptr->private_data.val64;
731         switch (attid) {
732         case DRSUAPI_ATTID_dBCSPwd:
733         case DRSUAPI_ATTID_unicodePwd:
734         case DRSUAPI_ATTID_ntPwdHistory:
735         case DRSUAPI_ATTID_lmPwdHistory:
736                 rid_crypt = TRUE;
737                 break;
738         case DRSUAPI_ATTID_supplementalCredentials:
739                 attr_dissector_fn = drsuapi_dissect_supplementalCredentials;
740                 break;
741         case DRSUAPI_ATTID_priorValue:
742         case DRSUAPI_ATTID_currentValue:
743         case DRSUAPI_ATTID_trustAuthOutgoing:
744         case DRSUAPI_ATTID_trustAuthIncoming:
745         case DRSUAPI_ATTID_initialAuthOutgoing:
746         case DRSUAPI_ATTID_initialAuthIncoming:
747                 break;
748         default:
749                 return offset;
750         }
752         length = offset - start_offset;
754         if (length < 24) {
755                 return offset;
756         }
757         start_offset += 4;
758         length -= 4;
760         proto_tree_add_text_internal(tree, tvb, start_offset, length,
761                         "METZE rid_crypt:%s RID:%d ATTID:0x%08X length=%d session_key=%s",
762                         rid_crypt ? "YES" : "NO",
763                         rid, attid,
764                         length,
765                         di->auth_session_key != NULL ?
766                         di->auth_session_key->id_str : "NO");
768         if (di->auth_session_key == NULL) {
769                 return offset;
770         }
772         if (!tvb_bytes_exist(tvb, start_offset, length)) {
773                 return offset;
774         }
776         confounder = tvb_memcpy(tvb, _confounder, start_offset, 16);
777         buf_len = length - 16;
778         buf = tvb_memdup(pinfo->pool, tvb, start_offset + 16, buf_len);
779         if (buf == NULL) {
780                 return offset;
781         }
783         iov[0].len = di->auth_session_key->keylength;
784         iov[0].data = di->auth_session_key->keyvalue;
785         iov[1].len = 16;
786         iov[1].data = confounder;
788         err = gcry_md_hash_buffers(GCRY_MD_MD5, 0, decryption_key, iov, 2);
789         if (err != 0) {
790                 ws_warning("GCRY: gcry_md_hash_buffers(GCRY_MD_MD5) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
791                 return offset;
792         }
794         err = gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
795         if (err != 0) {
796                 ws_warning("GCRY: gcry_cipher_open(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
797                 return offset;
798         }
799         err = gcry_cipher_setkey(rc4_handle, decryption_key, HASH_MD5_LENGTH);
800         if (err != 0) {
801                 ws_warning("GCRY: gcry_cipher_setkey(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
802                 gcry_cipher_close(rc4_handle);
803                 return offset;
804         }
806         err = gcry_cipher_decrypt(rc4_handle, buf, buf_len, NULL, 0);
807         if (err != 0) {
808                 ws_warning("GCRY: gcry_cipher_decrypt(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
809                 gcry_cipher_close(rc4_handle);
810                 return offset;
811         }
812         gcry_cipher_close(rc4_handle);
814         if (rid_crypt) {
815                 return offset;
816         }
818         plain_tvb = tvb_new_child_real_data(tvb, buf + 4, buf_len - 4, buf_len - 4);
820         add_new_data_source(pinfo, plain_tvb, "DRSUAPI Decrypted Attribute Value");
822         if (attr_dissector_fn == NULL) {
823                 return offset;
824         }
826         attr_dissector_fn(plain_tvb, pinfo, tree, di);
828         return offset;
832 drsuapi_dissect_struct_DsReplicaAttribute(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)
834         /*manual*/
835         dcerpc_ptr_stack *rid_ptr = di->ptr_stack;
836         proto_item *item = NULL;
837         proto_tree *tree = NULL;
838         int old_offset;
840         ALIGN_TO_5_BYTES;
842         old_offset = offset;
844         if (parent_tree) {
845                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
846                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaAttribute);
847         }
849         if (rid_ptr != NULL) {
850                 dcerpc_ptr_stack *attid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
851                 if (attid_ptr != NULL) {
852                         attid_ptr->parent = rid_ptr;
853                 }
854                 di->ptr_stack = attid_ptr;
855         }
857         offset = drsuapi_dissect_element_DsReplicaAttribute_attid(tvb, offset, pinfo, tree, di, drep);
859         offset = drsuapi_dissect_element_DsReplicaAttribute_value_ctr(tvb, offset, pinfo, tree, di, drep);
861         di->ptr_stack = rid_ptr;
863         proto_item_set_len(item, offset-old_offset);
866         if (di->call_data->flags & DCERPC_IS_NDR64) {
867                 ALIGN_TO_5_BYTES;
868         }
870         return offset;
874 drsuapi_dissect_struct_DsReplicaObject(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)
876         /*manual*/
877         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
878         dcerpc_ptr_stack *rid_ptr = NULL;
879         proto_item *item = NULL;
880         proto_tree *tree = NULL;
881         int old_offset;
883         ALIGN_TO_5_BYTES;
885         old_offset = offset;
887         if (parent_tree) {
888                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
889                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaObject);
890         }
892         rid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
893         di->ptr_stack = rid_ptr;
895         offset = drsuapi_dissect_element_DsReplicaObject_identifier(tvb, offset, pinfo, tree, di, drep);
897         offset = drsuapi_dissect_element_DsReplicaObject_flags(tvb, offset, pinfo, tree, di, drep);
899         offset = drsuapi_dissect_element_DsReplicaObject_attribute_ctr(tvb, offset, pinfo, tree, di, drep);
901         di->ptr_stack = saved_ptr;
903         proto_item_set_len(item, offset-old_offset);
906         if (di->call_data->flags & DCERPC_IS_NDR64) {
907                 ALIGN_TO_5_BYTES;
908         }
910         return offset;
912 CODE END