TODO drsuapi compressed
[wireshark-sm.git] / epan / dissectors / pidl / drsuapi / drsuapi.cnf
blob0fefb810d72db5595241d2a4cdfb2213dc24d99a
1 # Conformance file for drsuapi
3 MANUAL drsuapi_dissect_struct_DsBindInfoCtr
5 NOEMIT drsuapi_dissect_element_DsBindInfoCtr_length
7 MANUAL drsuapi_dissect_DsBindInfo
8 NOEMIT drsuapi_dissect_element_DsBindInfo_info24
9 NOEMIT drsuapi_dissect_element_DsBindInfo_info28
10 NOEMIT drsuapi_dissect_element_DsBindInfo_info32
11 NOEMIT drsuapi_dissect_element_DsBindInfo_info48
12 NOEMIT drsuapi_dissect_element_DsBindInfo_info52
13 NOEMIT drsuapi_dissect_element_DsBindInfo_Fallback
15 MANUAL drsuapi_dissect_element_DsReplicaObjectIdentifier_sid
16 MANUAL drsuapi_dissect_element_DsReplicaAttribute_attid
17 MANUAL drsuapi_dissect_element_DsAttributeValue_blob_
18 MANUAL drsuapi_dissect_struct_DsReplicaAttribute
19 MANUAL drsuapi_dissect_struct_DsReplicaObject
20 MANUAL drsuapi_dissect_element_DsReplicaObjectListItem_next_object_
21 MANUAL drsuapi_dissect_element_DsReplicaObjectListItemEx_next_object_
22 MANUAL drsuapi_dissect_element_DsAddEntry_AttrErrListItem_V1_next_
23 MANUAL drsuapi_dissect_element_DsaAddressListItem_V1_next_
24 MANUAL drsuapi_dissect_element_DsAddEntry_RefErrListItem_V1_next_
25 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_keys
26 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_old_keys
27 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys
28 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_
29 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys
30 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_
31 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey3_value
32 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey3_value_
33 MANUAL drsuapi_dissect_struct_package_PrimaryKerberosKey3
34 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_keys
35 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_service_keys
36 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_old_keys
37 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_older_keys
38 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys
39 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_
40 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys
41 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_
42 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys
43 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_
44 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys
45 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_
46 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey4_value
47 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey4_value_
48 MANUAL drsuapi_dissect_struct_package_PrimaryKerberosKey4
49 MANUAL drsuapi_dissect_element_package_PrimaryKerberosBlob_version
50 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_name_len
51 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_data_len
52 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_name
53 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_data
54 MANUAL drsuapi_dissect_struct_supplementalCredentialsPackage
55 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix_
56 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages
57 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_packages
58 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_
59 MANUAL drsuapi_dissect_struct_supplementalCredentialsSubBlob
60 MANUAL drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size
61 MANUAL drsuapi_dissect_element_supplementalCredentialsBlob_sub
62 MANUAL drsuapi_dissect_struct_supplementalCredentialsBlob
64 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1
65 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1_
66 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr6TS_ctr6
67 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr6TS_ctr6_
68 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9
69 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9_
71 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr7_level
72 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr7_level
73 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr7_type
74 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr7_type
75 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr7_ctr
76 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr7_ctr
77 MANUAL drsuapi_dissect_struct_DsGetNCChangesCtr7
79 HF_FIELD hf_drsuapi_String_name "String" "drsuapi.lsa.string" FT_STRING BASE_NONE NULL 0 "" "" ""
80 MANUAL drsuapi_dissect_element_lsa_String_string_
81 NOEMIT drsuapi_dissect_element_lsa_String_string__
83 HF_FIELD hf_DsReplicaObjectIdentifier_dn "DN" "drsuapi.objectidentifier.dn" FT_STRING BASE_NONE NULL 0 "" "" ""
84 MANUAL drsuapi_dissect_element_DsReplicaObjectIdentifier_dn
85 NOEMIT drsuapi_dissect_element_DsReplicaObjectIdentifier_dn_
87 CODE START
89   #include <wsutil/wsgcrypt.h>
90   #include <epan/expert.h>
91   #include <epan/strutil.h>
92   #define KERBEROS_METZE 1
93   #include "packet-kerberos.h"
95 static int
96 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_)
98         /*manual*/
99         dcerpc_ptr_stack *ptr = di->ptr_stack;
100         int start_offset = offset;
101         guint32 rid = 0;
103         di->hf_index = hf_drsuapi_drsuapi_DsReplicaObjectIdentifier_sid;
105         offset = dissect_ndr_nt_SID28(tvb, offset, pinfo, tree, di, drep);
106         if (ptr == NULL) {
107                 return offset;
108         }
110         if (offset > start_offset) {
111                 dissect_ndr_uint32(tvb, start_offset + 24, pinfo, tree, di, drep, -1, &rid);
112         }
114         ptr->private_data.val64 = rid;
115         if (tree == NULL) return offset;
117 if (0) {
118       proto_tree_add_debug_text(tree,
119                         "METZE frame:%d drsuapi_dissect_element_DsReplicaObjectIdentifier_sid RID:%d auth_info->session_key=%s",
120                         pinfo->fd->num, rid,
121                         di->auth_session_key != NULL ?
122                         di->auth_session_key->id_str : "NO");
124         return offset;
127 static int
128 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_)
130         /*manual*/
131         dcerpc_ptr_stack *ptr = di->ptr_stack;
132         guint32 rid = 0;
133         guint32 attid = 0;
134         offset = drsuapi_dissect_enum_DsAttributeId(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsReplicaAttribute_attid, &attid);
135         if (ptr == NULL) {
136                 return offset;
137         }
138         if (ptr->parent == NULL) {
139                 return offset;
140         }
141         rid = ptr->parent->private_data.val64;
142         ptr->private_data.val64 = attid;
143         if (tree == NULL) return offset;
144 if (0) {
145       proto_tree_add_debug_text(tree,
146                         "METZE frame:%d drsuapi_dissect_element_DsReplicaAttribute_attid RID:%d ATTID:0x%08X auth_info->session_key=%s",
147                         pinfo->fd->num,
148                         rid, attid,
149                         di->auth_session_key != NULL ?
150                         di->auth_session_key->id_str : "NO");
152         return offset;
155 static int
156 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)
158         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosBlob_version, 0, version);
160         return offset;
163 static int
164 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)
166         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_keys, 0, num_keys);
168         return offset;
171 static int
172 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)
174         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_old_keys, 0, num_old_keys);
176         return offset;
179 static int
180 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)
182         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
185 static int
186 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)
188         guint32 i;
190         for (i=0; i < *num_keys; i++) {
191                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_keys, 0);
192         }
194         return offset;
197 static int
198 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)
200         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
203 static int
204 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)
206         guint32 i;
208         for (i=0; i < *num_old_keys; i++) {
209                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_old_keys, 0);
210         }
212         return offset;
215 static int
216 drsuapi_dissect_element_package_PrimaryKerberosKey3_value(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint32 *value_len)
218         return drsuapi_dissect_element_package_PrimaryKerberosKey3_value_(tvb, offset, pinfo, tree, di, drep, value_len);
221 static int
222 drsuapi_dissect_element_package_PrimaryKerberosKey3_value_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint32 *value_len)
224         tvbuff_t *subtvb = tvb_new_subset_length(tvb, offset, *value_len);
226         offset += dissect_ndr_datablob(subtvb, 0, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value, 1);
228         return offset;
232 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_)
234         guint32 value_len = 0;
235         proto_item *item = NULL;
236         proto_tree *tree = NULL;
237         int old_offset;
238         guint32 keytype;
239         guint32 value_ofs;
241         ALIGN_TO_4_BYTES;
243         old_offset = offset;
245         if (parent_tree) {
246                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
247                 tree = proto_item_add_subtree(item, ett_drsuapi_package_PrimaryKerberosKey3);
248         }
250         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved1(tvb, offset, pinfo, tree, di, drep);
252         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved2(tvb, offset, pinfo, tree, di, drep);
254         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved3(tvb, offset, pinfo, tree, di, drep);
256         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_keytype(tvb, offset, pinfo, tree, di, drep);
257         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_keytype, 0, &keytype);
259         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
260         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_len, 0, &value_len);
262         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_ofs(tvb, offset, pinfo, tree, di, drep);
263         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_ofs, 0, &value_ofs);
265         if (value_ofs != 0 && tvb_bytes_exist(tvb, value_ofs, value_len)) {
266                 drsuapi_dissect_element_package_PrimaryKerberosKey3_value(tvb, value_ofs, pinfo, tree, di, drep, &value_len);
267         }
269         proto_item_set_len(item, offset-old_offset);
272         if (di->call_data->flags & DCERPC_IS_NDR64) {
273                 ALIGN_TO_4_BYTES;
274         }
276         return offset;
279 static int
280 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)
282         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_keys, 0, num_keys);
284         return offset;
287 static int
288 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)
290         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_service_keys, 0, num_service_keys);
292         return offset;
295 static int
296 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)
298         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_old_keys, 0, num_old_keys);
300         return offset;
303 static int
304 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)
306         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_older_keys, 0, num_older_keys);
308         return offset;
311 static int
312 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)
314         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
317 static int
318 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)
320         guint32 i;
322         for (i=0; i < *num_keys; i++) {
323                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_keys, 0);
324         }
326         return offset;
329 static int
330 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)
332         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_(tvb, offset, pinfo, tree, di, drep, num_service_keys);
335 static int
336 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)
338         guint32 i;
340         for (i=0; i < *num_service_keys; i++) {
341                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_service_keys, 0);
342         }
344         return offset;
347 static int
348 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)
350         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
353 static int
354 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)
356         guint32 i;
358         for (i=0; i < *num_old_keys; i++) {
359                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_old_keys, 0);
360         }
362         return offset;
365 static int
366 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)
368         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_(tvb, offset, pinfo, tree, di, drep, num_older_keys);
371 static int
372 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)
374         guint32 i;
376         for (i=0; i < *num_older_keys; i++) {
377                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_older_keys, 0);
378         }
380         return offset;
383 static int
384 drsuapi_dissect_element_package_PrimaryKerberosKey4_value(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint32 *value_len)
386         return drsuapi_dissect_element_package_PrimaryKerberosKey4_value_(tvb, offset, pinfo, tree, di, drep, value_len);
389 static int
390 drsuapi_dissect_element_package_PrimaryKerberosKey4_value_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint32 *value_len)
392         tvbuff_t *subtvb = tvb_new_subset_length(tvb, offset, *value_len);
393         dcerpc_ptr_stack *keytype_ptr = di->ptr_stack;
394         guint32 rid = 0;
395         int keytype = 0;
396         int keylength = *value_len;
397         guint8 keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
398         char origin[128] = {0, };
400         offset += dissect_ndr_datablob(subtvb, 0, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value, 1);
401         if (keytype_ptr == NULL) {
402                 return offset;
403         }
404         if (keytype_ptr->parent == NULL) {
405                 return offset;
406         }
408         rid = keytype_ptr->parent->private_data.val64;
409         keytype = keytype_ptr->private_data.val64;
410         tvb_memcpy(subtvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
411         snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.PrimaryKerberosKey4", rid);
413         kerberos_inject_longterm_key(pinfo, tree, NULL, subtvb,
414                                      keytype, keylength, keyvalue,
415                                      origin);
417         return offset;
421 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_)
423         guint32 value_len = 0;
424         proto_item *item = NULL;
425         proto_tree *tree = NULL;
426         int old_offset;
427         guint32 keytype;
428         guint32 value_ofs;
430         ALIGN_TO_4_BYTES;
432         old_offset = offset;
434         if (parent_tree) {
435                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
436                 tree = proto_item_add_subtree(item, ett_drsuapi_package_PrimaryKerberosKey4);
437         }
439         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved1(tvb, offset, pinfo, tree, di, drep);
441         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved2(tvb, offset, pinfo, tree, di, drep);
443         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved3(tvb, offset, pinfo, tree, di, drep);
445         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_iteration_count(tvb, offset, pinfo, tree, di, drep);
447         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_keytype(tvb, offset, pinfo, tree, di, drep);
448         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_keytype, 0, &keytype);
450         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
451         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_len, 0, &value_len);
453         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_ofs(tvb, offset, pinfo, tree, di, drep);
454         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_ofs, 0, &value_ofs);
456         if (value_ofs != 0 && tvb_bytes_exist(tvb, value_ofs, value_len)) {
457                 dcerpc_ptr_stack *rid_ptr = di->ptr_stack;
458                 dcerpc_ptr_stack *keytype_ptr = NULL;
460                 if (rid_ptr != NULL) {
461                         keytype_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
462                 }
464                 if (keytype_ptr != NULL) {
465                         keytype_ptr->parent = rid_ptr;
466                         keytype_ptr->private_data.val64 = keytype;
467                 }
468                 di->ptr_stack = keytype_ptr;
469                 drsuapi_dissect_element_package_PrimaryKerberosKey4_value(tvb, value_ofs, pinfo, tree, di, drep, &value_len);
470                 di->ptr_stack = rid_ptr;
471         }
473         proto_item_set_len(item, offset-old_offset);
475         if (di->call_data->flags & DCERPC_IS_NDR64) {
476                 ALIGN_TO_4_BYTES;
477         }
479         return offset;
481 static int
482 drsuapi_dissect_package_PrimaryKerberosBlob(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
484         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
485         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
486         static dcerpc_call_value call_data = { 0, };
487         int offset;
489         /* fake whatever state the dcerpc runtime support needs */
490         di.conformant_run=0;
491         /* we need di->call_data->flags.NDR64 == 0 */
492         di.call_data=&call_data;
493         init_ndr_pointer_list(&di);
494         di.ptr_stack = parent_di->ptr_stack;
495         offset = drsuapi_dissect_struct_package_PrimaryKerberosBlob(tvb, 0, pinfo, parent_tree, &di, drep,
496                                 hf_drsuapi_pkb_PrimaryKerberosBlob, 0);
497         free_ndr_pointer_list(&di);
498         return offset;
501 typedef int (*package_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
503 static gboolean
504 drsuapi_GByteArray_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_)
506         GByteArray *bytes = (GByteArray *)user_data;
507         g_byte_array_free(bytes, TRUE);
508         /* unregister this callback */
509         return FALSE;
512 static int
513 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)
515         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_name_len, 0, name_len);
517         return offset;
520 static int
521 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)
523         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_data_len, 0, data_len);
525         return offset;
528 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_)
530         proto_item *item = NULL;
531         proto_tree *tree = NULL;
532         int old_offset;
533         guint16 name_len = 0;
534         const char *name = NULL;
535         guint16 data_len = 0;
537         ALIGN_TO_2_BYTES;
539         old_offset = offset;
541         if (parent_tree) {
542                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
543                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsPackage);
544         }
546         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name_len(tvb, offset, pinfo, tree, di, drep, &name_len);
547         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data_len(tvb, offset, pinfo, tree, di, drep, &data_len);
548         offset = drsuapi_dissect_element_supplementalCredentialsPackage_reserved(tvb, offset, pinfo, tree, di, drep);
549 if (0) {
550  #if 0
551         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name(tvb, offset, pinfo, tree, di, drep, &name_len);
552  #endif
553 } else {
554         const guint8 *_name = NULL;
555         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_name,
556                                        tvb, offset, name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
557                                        wmem_packet_scope(), &_name);
558         name = (const char *)_name;
559         proto_item_append_text(item, ": %s", name);
560         offset += name_len;
562 if (0) {
563  #if 0
564         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data(tvb, offset, pinfo, tree, di, drep, &data_len);
565  #endif
566 } else {
567         const guint8 *_hexdata = NULL;
568         const char *hexdata = NULL;
569         tvbuff_t *tvbdata = NULL;
570         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_data,
571                                        tvb, offset, data_len, ENC_ASCII,
572                                        wmem_packet_scope(), &_hexdata);
573         hexdata = (const char *)_hexdata;
574         if (hexdata != NULL) {
575                 GByteArray *bytes = NULL;
577                 /* Convert key to raw bytes */
578                 bytes = g_byte_array_new();
579                 if (bytes != NULL) {
580                         gboolean res;
582                         wmem_register_callback(pinfo->pool, drsuapi_GByteArray_destroy_cb, bytes);
584                         res = hex_str_to_bytes(hexdata, bytes, FALSE);
585                         if (res) {
586                                 tvbdata = tvb_new_child_real_data(tvb,
587                                                                   bytes->data,
588                                                                   bytes->len,
589                                                                   bytes->len);
590                         }
591                 }
592         }
594         if (tvbdata != NULL) {
595                 struct {
596                         const char *name;
597                         package_dissector_fn_t fn;
598                 } packages[] = {
599                 {
600                         .name = "Primary:Kerberos-Newer-Keys",
601                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
602                 },{
603                         .name = "Primary:Kerberos",
604                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
605                 },{
606                         .name = NULL,
607                 }
608                 };
609                 size_t i = 0;
611                 for (i=0; packages[i].name != NULL; i++) {
612                         int cmp;
614                         cmp = strcmp(packages[i].name, name);
615                         if (cmp == 0) {
616                                 break;
617                         }
618                 }
620                 add_new_data_source(pinfo, tvbdata, name);
621                 proto_tree_add_text_internal(tree, tvbdata, 0, -1, "%s", name);
623                 if (packages[i].fn != NULL) {
624                         packages[i].fn(tvbdata, pinfo, tree, di);
625                 }
626         }
628         offset += data_len;
631         proto_item_set_len(item, offset-old_offset);
634         if (di->call_data->flags & DCERPC_IS_NDR64) {
635                 ALIGN_TO_2_BYTES;
636         }
638         return offset;
640 static int
641 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_)
643         offset += 2; //PIDL_dissect_uint16(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_prefix, 0);
645         return offset;
648 static int
649 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)
651         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_num_packages, 0, num_packages);
653         return offset;
656 static int
657 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)
659         guint16 i;
661         for (i=0; i<*num_packages; i++) {
662                 offset = drsuapi_dissect_struct_supplementalCredentialsPackage(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_supplementalCredentialsSubBlob_packages,0);
663         }
665         return offset;
668 static int
669 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)
671         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_(tvb,offset,pinfo,tree,di,drep,num_packages);
673         return offset;
677 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_)
679         proto_item *item = NULL;
680         proto_tree *tree = NULL;
681         int old_offset;
682         guint16 num_packages;
684         ALIGN_TO_3_BYTES;
686         old_offset = offset;
688         if (parent_tree) {
689                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
690                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsSubBlob);
691         }
693         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix(tvb, offset, pinfo, tree, di, drep);
695         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_signature(tvb, offset, pinfo, tree, di, drep);
697         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
699         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
701         proto_item_set_len(item, offset-old_offset);
704         if (di->call_data->flags & DCERPC_IS_NDR64) {
705                 ALIGN_TO_3_BYTES;
706         }
708         return offset;
711 static int
712 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_)
714         int conformant = di->conformant_run;
715         tvbuff_t *subtvb;
717         if (!conformant) {
718                 guint32 saved_flags = di->call_data->flags;
719                 dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
720                 guint32 size = 0;
721                 if (ndr_size_ptr != NULL) {
722                         size = ndr_size_ptr->private_data.val64;
723                         di->ptr_stack = ndr_size_ptr->parent;
724                 }
725                 di->call_data->flags &= ~DCERPC_IS_NDR64;
726                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);
727                 drsuapi_dissect_element_supplementalCredentialsBlob_sub_(subtvb, 0, pinfo, tree, di, drep);
728                 offset += (int)size;
729                 di->call_data->flags = saved_flags;
730                 di->ptr_stack = ndr_size_ptr;
731         }
733         return offset;
736 static int
737 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_)
739         dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
740         guint32 ndr_size = 0;
742         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsBlob___ndr_size, 0, &ndr_size);
743         if (ndr_size_ptr != NULL) {
744                 ndr_size_ptr->private_data.val64 = ndr_size;
745         }
747         return offset;
751 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_)
753         /*manual*/
754         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
755         dcerpc_ptr_stack *ndr_size_ptr = NULL;
756         proto_item *item = NULL;
757         proto_tree *tree = NULL;
758         int old_offset;
760         ALIGN_TO_4_BYTES;
762         old_offset = offset;
764         if (parent_tree) {
765                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
766                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsBlob);
767         }
769         ndr_size_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
770         if (ndr_size_ptr != NULL) {
771                 ndr_size_ptr->parent = saved_ptr;
772         }
773         di->ptr_stack = ndr_size_ptr;
775         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown1(tvb, offset, pinfo, tree, di, drep);
777         offset = drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size(tvb, offset, pinfo, tree, di, drep);
779         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown2(tvb, offset, pinfo, tree, di, drep);
781         offset = drsuapi_dissect_element_supplementalCredentialsBlob_sub(tvb, offset, pinfo, tree, di, drep);
783         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown3(tvb, offset, pinfo, tree, di, drep);
785         di->ptr_stack = saved_ptr;
787         proto_item_set_len(item, offset-old_offset);
790         if (di->call_data->flags & DCERPC_IS_NDR64) {
791                 ALIGN_TO_4_BYTES;
792         }
794         return offset;
796 static int
797 drsuapi_dissect_supplementalCredentials(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
799         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
800         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
801         static dcerpc_call_value call_data = { 0, };
802         int offset;
804         /* fake whatever state the dcerpc runtime support needs */
805         di.conformant_run=0;
806         /* we need di->call_data->flags.NDR64 == 0 */
807         di.call_data=&call_data;
808         init_ndr_pointer_list(&di);
809         di.ptr_stack = parent_di->ptr_stack;
810         offset = drsuapi_dissect_struct_supplementalCredentialsBlob(tvb, 0, pinfo, parent_tree, &di, drep,
811                                 hf_drsuapi_sch_supplementalCredentials, 0);
812         free_ndr_pointer_list(&di);
813         return offset;
816 static int
817 drsuapi_dissect_unicodePwd(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
819         int offset = 0;
820         dcerpc_ptr_stack *ptr = parent_di->ptr_stack;
821         guint32 rid = 0;
822         int keytype = 23;
823         int keylength = 16;
824         tvbuff_t *keytvb = tvb_new_subset_length(tvb, offset, keylength);
825         guint8 keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
826         char origin[128] = {0, };
828         if (ptr != NULL) {
829                 rid = ptr->private_data.val64;
830         }
832         tvb_memcpy(keytvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
833         snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.unicodePwd", rid);
835         kerberos_inject_longterm_key(pinfo, parent_tree, NULL, keytvb,
836                                      keytype, keylength, keyvalue,
837                                      origin);
838         offset += 16;
840         return offset;
843 static int
844 drsuapi_dissect_ntPwdHistory(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
846         dcerpc_ptr_stack *ptr = parent_di->ptr_stack;
847         guint32 rid = 0;
848         guint num_hashes = tvb_reported_length(tvb)/16;
849         guint idx;
850         int offset = 0;
852         if (ptr != NULL) {
853                 rid = ptr->private_data.val64;
854         }
856         for (idx = 0; idx < num_hashes; idx++) {
857                 int keytype = 23;
858                 int keylength = 16;
859                 tvbuff_t *keytvb = tvb_new_subset_length(tvb, offset, keylength);
860                 guint8 keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
861                 char origin[128] = {0, };
863                 tvb_memcpy(keytvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
864                 snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.ntPwdHistory[%u]", rid, idx);
866                 kerberos_inject_longterm_key(pinfo, parent_tree, NULL, keytvb,
867                                              keytype, keylength, keyvalue,
868                                              origin);
869                 offset += 16;
870         }
872         return offset;
875 typedef int (*attr_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
877 static int
878 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_)
880         /*manual*/
881         dcerpc_ptr_stack *ptr = di->ptr_stack;
882         guint32 rid = 0;
883         guint32 attid = 0;
884         int start_offset = offset;
885         int length;
886         guint8 _confounder[16] = { 0, };
887         guint8 *confounder;
888         guint8 decryption_key[HASH_MD5_LENGTH] = { 0, };
889         gcry_cipher_hd_t rc4_handle = NULL;
890         gcry_buffer_t iov[2] = { {0, },};
891         gcry_error_t err;
892         guint8 *buf = NULL;
893         int buf_len;
894         guint8 *payload_buf = NULL;
895         int payload_len = 0;
896         tvbuff_t *payload_tvb = NULL;
897         gboolean rid_crypt = FALSE;
898         const char *attr_name = NULL;
899         attr_dissector_fn_t attr_dissector_fn = NULL;
900         char source_name[64] = { 0,};
902         offset = dissect_ndr_datablob(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsAttributeValue_blob, 0);
903         if (ptr == NULL) {
904                 return offset;
905         }
906         if (ptr->parent == NULL) {
907                 return offset;
908         }
910 // TODO check dissect_ndr_lm_nt_hash_cb...
911         rid = ptr->parent->private_data.val64;
912         attid = ptr->private_data.val64;
914         switch (attid) {
915         case DRSUAPI_ATTID_dBCSPwd:
916                 attr_name = "dBCSPwd";
917                 rid_crypt = TRUE;
918                 break;
919         case DRSUAPI_ATTID_unicodePwd:
920                 attr_name = "unicodePwd";
921                 attr_dissector_fn = drsuapi_dissect_unicodePwd;
922                 rid_crypt = TRUE;
923                 break;
924         case DRSUAPI_ATTID_ntPwdHistory:
925                 attr_name = "ntPwdHistory";
926                 attr_dissector_fn = drsuapi_dissect_ntPwdHistory;
927                 rid_crypt = TRUE;
928                 break;
929         case DRSUAPI_ATTID_lmPwdHistory:
930                 attr_name = "lmPwdHistory";
931                 rid_crypt = TRUE;
932                 break;
933         case DRSUAPI_ATTID_supplementalCredentials:
934                 attr_name = "supplementalCredentials";
935                 attr_dissector_fn = drsuapi_dissect_supplementalCredentials;
936                 break;
937         case DRSUAPI_ATTID_priorValue:
938                 attr_name = "priorValue";
939                 break;
940         case DRSUAPI_ATTID_currentValue:
941                 attr_name = "currentValue";
942                 break;
943         case DRSUAPI_ATTID_trustAuthOutgoing:
944                 attr_name = "trustAuthOutgoing";
945                 break;
946         case DRSUAPI_ATTID_trustAuthIncoming:
947                 attr_name = "trustAuthIncoming";
948                 break;
949         case DRSUAPI_ATTID_initialAuthOutgoing:
950                 attr_name = "initialAuthOutgoing";
951                 break;
952         case DRSUAPI_ATTID_initialAuthIncoming:
953                 attr_name = "initialAuthIncoming";
954                 break;
955         default:
956                 return offset;
957         }
959         length = offset - start_offset;
961         if (length < 24) {
962                 return offset;
963         }
964         start_offset += 4;
965         length -= 4;
967 if (0) {
968         proto_tree_add_text_internal(tree, tvb, start_offset, length,
969                         "METZE rid_crypt:%s RID:%d ATTID:0x%08X ATTR[%s] length=%d session_key=%s",
970                         rid_crypt ? "YES" : "NO",
971                         rid, attid, attr_name,
972                         length,
973                         di->auth_session_key != NULL ?
974                         di->auth_session_key->id_str : "NO");
977         if (di->auth_session_key == NULL) {
978                 return offset;
979         }
981         if (!tvb_bytes_exist(tvb, start_offset, length)) {
982                 return offset;
983         }
985         confounder = tvb_memcpy(tvb, _confounder, start_offset, 16);
986         buf_len = length - 16;
987         buf = tvb_memdup(pinfo->pool, tvb, start_offset + 16, buf_len);
988         if (buf == NULL) {
989                 return offset;
990         }
992         iov[0].len = di->auth_session_key->keylength;
993         iov[0].data = di->auth_session_key->keyvalue;
994         iov[1].len = 16;
995         iov[1].data = confounder;
997         err = gcry_md_hash_buffers(GCRY_MD_MD5, 0, decryption_key, iov, 2);
998         if (err != 0) {
999                 ws_warning("GCRY: gcry_md_hash_buffers(GCRY_MD_MD5) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1000                 return offset;
1001         }
1003         err = gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
1004         if (err != 0) {
1005                 ws_warning("GCRY: gcry_cipher_open(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1006                 return offset;
1007         }
1008         err = gcry_cipher_setkey(rc4_handle, decryption_key, HASH_MD5_LENGTH);
1009         if (err != 0) {
1010                 ws_warning("GCRY: gcry_cipher_setkey(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1011                 gcry_cipher_close(rc4_handle);
1012                 return offset;
1013         }
1015         err = gcry_cipher_decrypt(rc4_handle, buf, buf_len, NULL, 0);
1016         if (err != 0) {
1017                 ws_warning("GCRY: gcry_cipher_decrypt(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1018                 gcry_cipher_close(rc4_handle);
1019                 return offset;
1020         }
1021         gcry_cipher_close(rc4_handle);
1023         payload_buf = buf + 4;
1024         payload_len = buf_len - 4;
1026         if (rid_crypt && rid != 0) {
1027                 guint8 rk[14];
1028                 guint8 ri = 0;
1029                 guint8 *hb = payload_buf;
1030                 guint32 hl = payload_len;
1031                 guint32 hi;
1033                 /*
1034                  * We have a payload contains one or more
1035                  * NT Hashes (16 bytes each).
1036                  */
1037                 if ((hl % 16) != 0) {
1038                         return offset;
1039                 }
1041                 /*
1042                  * We build a 112 bit key based on the RID
1043                  *
1044                  * With that we need to decrypt each NT Hash (16 byte)
1045                  *
1046                  * DES is based on 8 byte blocks, which mean
1047                  * we can use the first 7 bytes (56Bit) of the key to
1048                  * decrypt the first 8 bytes of the NT Hash and
1049                  * the last 7 bytes (also 56Bit) of the key to
1050                  * decrypt the 2nd 8 bytes of the NT Hash.
1051                  */
1053                 rk[0] = rk[4] = rk[8] = rk[12] = (guint8)(rid & 0xFF);
1054                 rk[1] = rk[5] = rk[9] = rk[13] = (guint8)((rid >> 8) & 0xFF);
1055                 rk[2] = rk[6] = rk[10]         = (guint8)((rid >> 16) & 0xFF);
1056                 rk[3] = rk[7] = rk[11]         = (guint8)((rid >> 24) & 0xFF);
1058                 /* loop in 8 byte steps and toggle the key index between 0 and 7 */
1059                 for (hi=0, ri = 0; hi < hl; hi += 8, ri = ri == 0 ? 7 : 0) {
1060                         guint8 *h64 = &hb[hi];
1061                         guint8 *rk56 = &rk[ri];
1062                         guint8 tmp64[8];
1063                         memcpy(tmp64, h64, 8);
1064                         decrypt_des_ecb(h64, tmp64, rk56);
1065                 }
1066         }
1068         payload_tvb = tvb_new_child_real_data(tvb, payload_buf, payload_len, payload_len);
1070         snprintf(source_name, sizeof(source_name)-1, "DRSUAPI Decrypted %s RID=%u", attr_name, rid);
1071         add_new_data_source(pinfo, payload_tvb, source_name);
1072         proto_tree_add_text_internal(tree, payload_tvb, 0, payload_len, "%s", source_name);
1074         if (attr_dissector_fn == NULL) {
1075                 return offset;
1076         }
1078         di->ptr_stack = ptr->parent;
1079         attr_dissector_fn(payload_tvb, pinfo, tree, di);
1080         di->ptr_stack = ptr;
1082         return offset;
1086 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_)
1088         /*manual*/
1089         dcerpc_ptr_stack *rid_ptr = di->ptr_stack;
1090         proto_item *item = NULL;
1091         proto_tree *tree = NULL;
1092         int old_offset;
1094         ALIGN_TO_5_BYTES;
1096         old_offset = offset;
1098         if (parent_tree) {
1099                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1100                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaAttribute);
1101         }
1103         if (rid_ptr != NULL) {
1104                 dcerpc_ptr_stack *attid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
1105                 if (attid_ptr != NULL) {
1106                         attid_ptr->parent = rid_ptr;
1107                 }
1108                 di->ptr_stack = attid_ptr;
1109         }
1111         offset = drsuapi_dissect_element_DsReplicaAttribute_attid(tvb, offset, pinfo, tree, di, drep);
1113         offset = drsuapi_dissect_element_DsReplicaAttribute_value_ctr(tvb, offset, pinfo, tree, di, drep);
1115         di->ptr_stack = rid_ptr;
1117         proto_item_set_len(item, offset-old_offset);
1120         if (di->call_data->flags & DCERPC_IS_NDR64) {
1121                 ALIGN_TO_5_BYTES;
1122         }
1124         return offset;
1128 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_)
1130         /*manual*/
1131         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
1132         dcerpc_ptr_stack *rid_ptr = NULL;
1133         proto_item *item = NULL;
1134         proto_tree *tree = NULL;
1135         int old_offset;
1137         ALIGN_TO_5_BYTES;
1139         old_offset = offset;
1141         if (parent_tree) {
1142                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1143                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaObject);
1144         }
1146         rid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
1147         di->ptr_stack = rid_ptr;
1149         offset = drsuapi_dissect_element_DsReplicaObject_identifier(tvb, offset, pinfo, tree, di, drep);
1151         offset = drsuapi_dissect_element_DsReplicaObject_flags(tvb, offset, pinfo, tree, di, drep);
1153         offset = drsuapi_dissect_element_DsReplicaObject_attribute_ctr(tvb, offset, pinfo, tree, di, drep);
1155         di->ptr_stack = saved_ptr;
1157         proto_item_set_len(item, offset-old_offset);
1160         if (di->call_data->flags & DCERPC_IS_NDR64) {
1161                 ALIGN_TO_5_BYTES;
1162         }
1164         return offset;
1167 static int
1168 drsuapi_dissect_element_DsReplicaObjectListItem_next_object_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1170         offset = drsuapi_dissect_struct_DsReplicaObjectListItem(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsReplicaObjectListItem_next_object,0);
1172         return offset;
1175 static int
1176 drsuapi_dissect_element_DsReplicaObjectListItemEx_next_object_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1178         offset = drsuapi_dissect_struct_DsReplicaObjectListItemEx(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsReplicaObjectListItemEx_next_object,0);
1180         return offset;
1183 static int
1184 drsuapi_dissect_element_DsAddEntry_AttrErrListItem_V1_next_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1186         offset = drsuapi_dissect_struct_DsAddEntry_AttrErrListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsAddEntry_AttrErrListItem_V1_next,0);
1188         return offset;
1191 static int
1192 drsuapi_dissect_element_DsaAddressListItem_V1_next_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1194         offset = drsuapi_dissect_struct_DsaAddressListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsaAddressListItem_V1_next,0);
1196         return offset;
1199 static int
1200 drsuapi_dissect_element_DsAddEntry_RefErrListItem_V1_next_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1202         offset = drsuapi_dissect_struct_DsAddEntry_RefErrListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsAddEntry_RefErrListItem_V1_next,0);
1204         return offset;
1207 static int
1208 drsuapi_dissect_element_lsa_String_string_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di, guint8 *drep _U_)
1210         char *data;
1212         offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep, sizeof(guint16), hf_drsuapi_String_name, FALSE, &data);
1213         proto_item_append_text(tree, ": %s", data);
1215         return offset;
1218 static int
1219 drsuapi_dissect_element_DsReplicaObjectIdentifier_dn(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, struct ndr_generic_array *nga)
1221         char *data = NULL;
1223         offset = dissect_ndr_generic_array_string(tvb, offset, pinfo, tree, di, drep,
1224                                                   sizeof(guint16), hf_DsReplicaObjectIdentifier_dn,
1225                                                   FALSE, nga, &data);
1226         proto_item_append_text(tree, ": %s", data);
1228         return offset;
1231 /* IDL: struct { */
1232 /* IDL:         [range(1,10000)] uint32 length; */
1233 /* IDL:         [size_is(length)] uint8 data[*]; */
1234 /* IDL: } */
1236 static int
1237 drsuapi_dissect_element_DsBindInfoCtr_length_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1239         offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsBindInfoCtr_length, 0);
1241         return offset;
1244 static int
1245 drsuapi_dissect_DsBindInfo(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_);
1247 static int
1248 drsuapi_dissect_element_DsBindInfoCtr_data_(tvbuff_t *tvb, int offset, int length, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1250         offset = drsuapi_dissect_DsBindInfo(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsBindInfoCtr_info, length);
1252         return offset;
1255 static int
1256 drsuapi_dissect_element_DsBindInfoCtr_data(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1258         offset = dissect_ndr_ucarray_block(tvb, offset, pinfo, tree, di, drep, drsuapi_dissect_element_DsBindInfoCtr_data_);
1260         return offset;
1264 drsuapi_dissect_struct_DsBindInfoCtr(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_)
1266         proto_item *item = NULL;
1267         proto_tree *tree = NULL;
1268         int old_offset;
1270         ALIGN_TO_4_BYTES;
1272         old_offset = offset;
1274         if (parent_tree) {
1275                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1276                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsBindInfoCtr);
1277         }
1279         offset = drsuapi_dissect_element_DsBindInfoCtr_length_(tvb, offset, pinfo, tree, di, drep);
1281         offset = drsuapi_dissect_element_DsBindInfoCtr_data(tvb, offset, pinfo, tree, di, drep);
1284         proto_item_set_len(item, offset-old_offset);
1286         if (di->call_data->flags & DCERPC_IS_NDR64) {
1287                 ALIGN_TO_4_BYTES;
1288         }
1290         return offset;
1293 static int
1294 drsuapi_dissect_DsBindInfo(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_)
1296         proto_item *item = NULL;
1297         proto_tree *tree = NULL;
1298         int old_offset;
1299         guint32 length = param;
1301         old_offset = offset;
1302         if (parent_tree) {
1303                 tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_drsuapi_drsuapi_DsBindInfo, &item, "drsuapi_DsBindInfo");
1304         }
1306         if (length >= 52) {
1307                 drsuapi_dissect_struct_DsBindInfo52(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info52,0);
1308         } else if (length >= 48) {
1309                 drsuapi_dissect_struct_DsBindInfo48(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info48,0);
1310         } else if (length >= 32) {
1311                 drsuapi_dissect_struct_DsBindInfo32(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info32,0);
1312         } else if (length >= 28) {
1313                 drsuapi_dissect_struct_DsBindInfo28(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info28,0);
1314         } else if (length >= 24) {
1315                 drsuapi_dissect_struct_DsBindInfo24(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info24,0);
1316         }
1317         offset += length;
1318         proto_item_set_len(item, offset-old_offset);
1320         return offset;
1323 static int
1324 drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1327         guint64 size;
1328         int conformant = di->conformant_run;
1329         tvbuff_t *subtvb = NULL;
1331         if (!conformant) {
1332                 guint32 saved_flags = di->call_data->flags;
1333                 offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr1TS_ctr1_, &size);
1334                 di->call_data->flags &= ~DCERPC_IS_NDR64;
1335                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);
1336                 drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1_(subtvb, 0, pinfo, tree, di, drep);
1337                 offset += (int)size;
1338                 di->call_data->flags = saved_flags;
1339         }
1341         return offset;
1344 static int
1345 drsuapi_dissect_element_DsGetNCChangesCtr6TS_ctr6(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1348         guint64 size;
1349         int conformant = di->conformant_run;
1350         tvbuff_t *subtvb;
1352         if (!conformant) {
1353                 guint32 saved_flags = di->call_data->flags;
1354                 offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr6TS_ctr6_, &size);
1355                 di->call_data->flags &= ~DCERPC_IS_NDR64;
1356                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);
1357                 drsuapi_dissect_element_DsGetNCChangesCtr6TS_ctr6_(subtvb, 0, pinfo, tree, di, drep);
1358                 offset += (int)size;
1359                 di->call_data->flags = saved_flags;
1360         }
1362         return offset;
1365 static int
1366 drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)
1369         guint64 size;
1370         int conformant = di->conformant_run;
1371         tvbuff_t *subtvb;
1373         if (!conformant) {
1374                 guint32 saved_flags = di->call_data->flags;
1375                 offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr6TS_ctr6_, &size);
1376                 di->call_data->flags &= ~DCERPC_IS_NDR64;
1377                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);
1378                 drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9_(subtvb, 0, pinfo, tree, di, drep);
1379                 offset += (int)size;
1380                 di->call_data->flags = saved_flags;
1381         }
1383         return offset;
1386 static int
1387 drsuapi_dissect_DsGetNCChangesCompressedCtr(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_);
1389 static int
1390 drsuapi_dissect_element_DsGetNCChangesCtr7_level(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint32 *level)
1392         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr7_level, 0, level);
1394         return offset;
1397 static int
1398 drsuapi_dissect_element_DsGetNCChangesCtr7_type(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint16 *type)
1400         offset = drsuapi_dissect_enum_DsGetNCChangesCompressionType(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr7_type, type);
1402         return offset;
1405 static int
1406 drsuapi_dissect_element_DsGetNCChangesCtr7_ctr(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, guint32 level _U_)
1408         offset = drsuapi_dissect_DsGetNCChangesCompressedCtr(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr7_ctr, level);
1410         return offset;
1414 drsuapi_dissect_struct_DsGetNCChangesCtr7(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_)
1416         guint32 level;
1417         guint16 type;
1418         guint32 ctr_level;
1419         proto_item *item = NULL;
1420         proto_tree *tree = NULL;
1421         int old_offset;
1423         ALIGN_TO_5_BYTES;
1425         old_offset = offset;
1427         if (parent_tree) {
1428                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1429                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsGetNCChangesCtr7);
1430         }
1432         offset = drsuapi_dissect_element_DsGetNCChangesCtr7_level(tvb, offset, pinfo, tree, di, drep, &level);
1434         offset = drsuapi_dissect_element_DsGetNCChangesCtr7_type(tvb, offset, pinfo, tree, di, drep, &type);
1436         ctr_level = (level & 0xFFFF) | (((guint32)type)<<16);
1438         offset = drsuapi_dissect_element_DsGetNCChangesCtr7_ctr(tvb, offset, pinfo, tree, di, drep, ctr_level);
1441         proto_item_set_len(item, offset-old_offset);
1444         if (di->call_data->flags & DCERPC_IS_NDR64) {
1445                 ALIGN_TO_5_BYTES;
1446         }
1448         return offset;
1450 CODE END