epan/dissectors/pidl/drsuapi/drsuapi.cnf init/free_ndr_pointer_list
[wireshark-sm.git] / epan / dissectors / pidl / drsuapi / drsuapi.cnf
blob47d893008dad6b6ec0d22b1a781277dfe0bd2494
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 HF_FIELD hf_drsuapi_String_name "String" "drsuapi.lsa.string" FT_STRING BASE_NONE NULL 0 "" "" ""
65 MANUAL drsuapi_dissect_element_lsa_String_string_
66 NOEMIT drsuapi_dissect_element_lsa_String_string__
68 HF_FIELD hf_DsReplicaObjectIdentifier_dn "DN" "drsuapi.objectidentifier.dn" FT_STRING BASE_NONE NULL 0 "" "" ""
69 MANUAL drsuapi_dissect_element_DsReplicaObjectIdentifier_dn
70 NOEMIT drsuapi_dissect_element_DsReplicaObjectIdentifier_dn_
72 CODE START
74   #include <wsutil/wsgcrypt.h>
75   #include <epan/expert.h>
76   #include <epan/strutil.h>
77   #define KERBEROS_METZE 1
78   #include "packet-kerberos.h"
80 static int
81 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_)
83         /*manual*/
84         dcerpc_ptr_stack *ptr = di->ptr_stack;
85         int start_offset = offset;
86         guint32 rid = 0;
88         di->hf_index = hf_drsuapi_drsuapi_DsReplicaObjectIdentifier_sid;
90         offset = dissect_ndr_nt_SID28(tvb, offset, pinfo, tree, di, drep);
91         if (ptr == NULL) {
92                 return offset;
93         }
95         if (offset > start_offset) {
96                 dissect_ndr_uint32(tvb, start_offset + 24, pinfo, tree, di, drep, -1, &rid);
97         }
99         ptr->private_data.val64 = rid;
100         if (tree == NULL) return offset;
102 if (0) {
103       proto_tree_add_debug_text(tree,
104                         "METZE frame:%d drsuapi_dissect_element_DsReplicaObjectIdentifier_sid RID:%d auth_info->session_key=%s",
105                         pinfo->fd->num, rid,
106                         di->auth_session_key != NULL ?
107                         di->auth_session_key->id_str : "NO");
109         return offset;
112 static int
113 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_)
115         /*manual*/
116         dcerpc_ptr_stack *ptr = di->ptr_stack;
117         guint32 rid = 0;
118         guint32 attid = 0;
119         offset = drsuapi_dissect_enum_DsAttributeId(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsReplicaAttribute_attid, &attid);
120         if (ptr == NULL) {
121                 return offset;
122         }
123         if (ptr->parent == NULL) {
124                 return offset;
125         }
126         rid = ptr->parent->private_data.val64;
127         ptr->private_data.val64 = attid;
128         if (tree == NULL) return offset;
129 if (0) {
130       proto_tree_add_debug_text(tree,
131                         "METZE frame:%d drsuapi_dissect_element_DsReplicaAttribute_attid RID:%d ATTID:0x%08X auth_info->session_key=%s",
132                         pinfo->fd->num,
133                         rid, attid,
134                         di->auth_session_key != NULL ?
135                         di->auth_session_key->id_str : "NO");
137         return offset;
140 static int
141 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)
143         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosBlob_version, 0, version);
145         return offset;
148 static int
149 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)
151         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_keys, 0, num_keys);
153         return offset;
156 static int
157 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)
159         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_old_keys, 0, num_old_keys);
161         return offset;
164 static int
165 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)
167         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
170 static int
171 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)
173         guint32 i;
175         for (i=0; i < *num_keys; i++) {
176                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_keys, 0);
177         }
179         return offset;
182 static int
183 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)
185         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
188 static int
189 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)
191         guint32 i;
193         for (i=0; i < *num_old_keys; i++) {
194                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_old_keys, 0);
195         }
197         return offset;
200 static int
201 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)
203         return drsuapi_dissect_element_package_PrimaryKerberosKey3_value_(tvb, offset, pinfo, tree, di, drep, value_len);
206 static int
207 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)
209         tvbuff_t *subtvb = tvb_new_subset_length(tvb, offset, *value_len);
211         offset += dissect_ndr_datablob(subtvb, 0, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value, 1);
213         return offset;
217 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_)
219         guint32 value_len = 0;
220         proto_item *item = NULL;
221         proto_tree *tree = NULL;
222         int old_offset;
223         guint32 keytype;
224         guint32 value_ofs;
226         ALIGN_TO_4_BYTES;
228         old_offset = offset;
230         if (parent_tree) {
231                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
232                 tree = proto_item_add_subtree(item, ett_drsuapi_package_PrimaryKerberosKey3);
233         }
235         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved1(tvb, offset, pinfo, tree, di, drep);
237         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved2(tvb, offset, pinfo, tree, di, drep);
239         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved3(tvb, offset, pinfo, tree, di, drep);
241         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_keytype(tvb, offset, pinfo, tree, di, drep);
242         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_keytype, 0, &keytype);
244         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
245         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_len, 0, &value_len);
247         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_ofs(tvb, offset, pinfo, tree, di, drep);
248         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_ofs, 0, &value_ofs);
250         if (value_ofs != 0 && tvb_bytes_exist(tvb, value_ofs, value_len)) {
251                 drsuapi_dissect_element_package_PrimaryKerberosKey3_value(tvb, value_ofs, pinfo, tree, di, drep, &value_len);
252         }
254         proto_item_set_len(item, offset-old_offset);
257         if (di->call_data->flags & DCERPC_IS_NDR64) {
258                 ALIGN_TO_4_BYTES;
259         }
261         return offset;
264 static int
265 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)
267         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_keys, 0, num_keys);
269         return offset;
272 static int
273 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)
275         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_service_keys, 0, num_service_keys);
277         return offset;
280 static int
281 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)
283         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_old_keys, 0, num_old_keys);
285         return offset;
288 static int
289 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)
291         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_older_keys, 0, num_older_keys);
293         return offset;
296 static int
297 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)
299         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
302 static int
303 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)
305         guint32 i;
307         for (i=0; i < *num_keys; i++) {
308                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_keys, 0);
309         }
311         return offset;
314 static int
315 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)
317         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_(tvb, offset, pinfo, tree, di, drep, num_service_keys);
320 static int
321 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)
323         guint32 i;
325         for (i=0; i < *num_service_keys; i++) {
326                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_service_keys, 0);
327         }
329         return offset;
332 static int
333 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)
335         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
338 static int
339 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)
341         guint32 i;
343         for (i=0; i < *num_old_keys; i++) {
344                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_old_keys, 0);
345         }
347         return offset;
350 static int
351 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)
353         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_(tvb, offset, pinfo, tree, di, drep, num_older_keys);
356 static int
357 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)
359         guint32 i;
361         for (i=0; i < *num_older_keys; i++) {
362                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_older_keys, 0);
363         }
365         return offset;
368 static int
369 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)
371         return drsuapi_dissect_element_package_PrimaryKerberosKey4_value_(tvb, offset, pinfo, tree, di, drep, value_len);
374 static int
375 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)
377         tvbuff_t *subtvb = tvb_new_subset_length(tvb, offset, *value_len);
378         dcerpc_ptr_stack *keytype_ptr = di->ptr_stack;
379         guint32 rid = 0;
380         int keytype = 0;
381         int keylength = *value_len;
382         guint8 keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
383         char origin[128] = {0, };
385         offset += dissect_ndr_datablob(subtvb, 0, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value, 1);
386         if (keytype_ptr == NULL) {
387                 return offset;
388         }
389         if (keytype_ptr->parent == NULL) {
390                 return offset;
391         }
393         rid = keytype_ptr->parent->private_data.val64;
394         keytype = keytype_ptr->private_data.val64;
395         tvb_memcpy(subtvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
396         snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.PrimaryKerberosKey4", rid);
398         kerberos_inject_longterm_key(pinfo, tree, NULL, subtvb,
399                                      keytype, keylength, keyvalue,
400                                      origin);
402         return offset;
406 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_)
408         guint32 value_len = 0;
409         proto_item *item = NULL;
410         proto_tree *tree = NULL;
411         int old_offset;
412         guint32 keytype;
413         guint32 value_ofs;
415         ALIGN_TO_4_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_package_PrimaryKerberosKey4);
422         }
424         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved1(tvb, offset, pinfo, tree, di, drep);
426         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved2(tvb, offset, pinfo, tree, di, drep);
428         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved3(tvb, offset, pinfo, tree, di, drep);
430         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_iteration_count(tvb, offset, pinfo, tree, di, drep);
432         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_keytype(tvb, offset, pinfo, tree, di, drep);
433         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_keytype, 0, &keytype);
435         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
436         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_len, 0, &value_len);
438         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_ofs(tvb, offset, pinfo, tree, di, drep);
439         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_ofs, 0, &value_ofs);
441         if (value_ofs != 0 && tvb_bytes_exist(tvb, value_ofs, value_len)) {
442                 dcerpc_ptr_stack *rid_ptr = di->ptr_stack;
443                 dcerpc_ptr_stack *keytype_ptr = NULL;
445                 if (rid_ptr != NULL) {
446                         keytype_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
447                 }
449                 if (keytype_ptr != NULL) {
450                         keytype_ptr->parent = rid_ptr;
451                         keytype_ptr->private_data.val64 = keytype;
452                 }
453                 di->ptr_stack = keytype_ptr;
454                 drsuapi_dissect_element_package_PrimaryKerberosKey4_value(tvb, value_ofs, pinfo, tree, di, drep, &value_len);
455                 di->ptr_stack = rid_ptr;
456         }
458         proto_item_set_len(item, offset-old_offset);
460         if (di->call_data->flags & DCERPC_IS_NDR64) {
461                 ALIGN_TO_4_BYTES;
462         }
464         return offset;
466 static int
467 drsuapi_dissect_package_PrimaryKerberosBlob(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
469         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
470         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
471         static dcerpc_call_value call_data = { 0, };
472         int offset;
474         /* fake whatever state the dcerpc runtime support needs */
475         di.conformant_run=0;
476         /* we need di->call_data->flags.NDR64 == 0 */
477         di.call_data=&call_data;
478         init_ndr_pointer_list(&di);
479         di.ptr_stack = parent_di->ptr_stack;
480         offset = drsuapi_dissect_struct_package_PrimaryKerberosBlob(tvb, 0, pinfo, parent_tree, &di, drep,
481                                 hf_drsuapi_pkb_PrimaryKerberosBlob, 0);
482         free_ndr_pointer_list(&di);
483         return offset;
486 typedef int (*package_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
488 static gboolean
489 drsuapi_GByteArray_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_)
491         GByteArray *bytes = (GByteArray *)user_data;
492         g_byte_array_free(bytes, TRUE);
493         /* unregister this callback */
494         return FALSE;
497 static int
498 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)
500         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_name_len, 0, name_len);
502         return offset;
505 static int
506 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)
508         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_data_len, 0, data_len);
510         return offset;
513 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_)
515         proto_item *item = NULL;
516         proto_tree *tree = NULL;
517         int old_offset;
518         guint16 name_len = 0;
519         const char *name = NULL;
520         guint16 data_len = 0;
522         ALIGN_TO_2_BYTES;
524         old_offset = offset;
526         if (parent_tree) {
527                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
528                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsPackage);
529         }
531         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name_len(tvb, offset, pinfo, tree, di, drep, &name_len);
532         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data_len(tvb, offset, pinfo, tree, di, drep, &data_len);
533         offset = drsuapi_dissect_element_supplementalCredentialsPackage_reserved(tvb, offset, pinfo, tree, di, drep);
534 if (0) {
535  #if 0
536         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name(tvb, offset, pinfo, tree, di, drep, &name_len);
537  #endif
538 } else {
539         const guint8 *_name = NULL;
540         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_name,
541                                        tvb, offset, name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
542                                        wmem_packet_scope(), &_name);
543         name = (const char *)_name;
544         proto_item_append_text(item, ": %s", name);
545         offset += name_len;
547 if (0) {
548  #if 0
549         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data(tvb, offset, pinfo, tree, di, drep, &data_len);
550  #endif
551 } else {
552         const guint8 *_hexdata = NULL;
553         const char *hexdata = NULL;
554         tvbuff_t *tvbdata = NULL;
555         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_data,
556                                        tvb, offset, data_len, ENC_ASCII,
557                                        wmem_packet_scope(), &_hexdata);
558         hexdata = (const char *)_hexdata;
559         if (hexdata != NULL) {
560                 GByteArray *bytes = NULL;
562                 /* Convert key to raw bytes */
563                 bytes = g_byte_array_new();
564                 if (bytes != NULL) {
565                         gboolean res;
567                         wmem_register_callback(pinfo->pool, drsuapi_GByteArray_destroy_cb, bytes);
569                         res = hex_str_to_bytes(hexdata, bytes, FALSE);
570                         if (res) {
571                                 tvbdata = tvb_new_child_real_data(tvb,
572                                                                   bytes->data,
573                                                                   bytes->len,
574                                                                   bytes->len);
575                         }
576                 }
577         }
579         if (tvbdata != NULL) {
580                 struct {
581                         const char *name;
582                         package_dissector_fn_t fn;
583                 } packages[] = {
584                 {
585                         .name = "Primary:Kerberos-Newer-Keys",
586                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
587                 },{
588                         .name = "Primary:Kerberos",
589                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
590                 },{
591                         .name = NULL,
592                 }
593                 };
594                 size_t i = 0;
596                 for (i=0; packages[i].name != NULL; i++) {
597                         int cmp;
599                         cmp = strcmp(packages[i].name, name);
600                         if (cmp == 0) {
601                                 break;
602                         }
603                 }
605                 add_new_data_source(pinfo, tvbdata, name);
606                 proto_tree_add_text_internal(tree, tvbdata, 0, -1, "%s", name);
608                 if (packages[i].fn != NULL) {
609                         packages[i].fn(tvbdata, pinfo, tree, di);
610                 }
611         }
613         offset += data_len;
616         proto_item_set_len(item, offset-old_offset);
619         if (di->call_data->flags & DCERPC_IS_NDR64) {
620                 ALIGN_TO_2_BYTES;
621         }
623         return offset;
625 static int
626 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_)
628         offset += 2; //PIDL_dissect_uint16(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_prefix, 0);
630         return offset;
633 static int
634 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)
636         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_num_packages, 0, num_packages);
638         return offset;
641 static int
642 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)
644         guint16 i;
646         for (i=0; i<*num_packages; i++) {
647                 offset = drsuapi_dissect_struct_supplementalCredentialsPackage(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_supplementalCredentialsSubBlob_packages,0);
648         }
650         return offset;
653 static int
654 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)
656         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_(tvb,offset,pinfo,tree,di,drep,num_packages);
658         return offset;
662 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_)
664         proto_item *item = NULL;
665         proto_tree *tree = NULL;
666         int old_offset;
667         guint16 num_packages;
669         ALIGN_TO_3_BYTES;
671         old_offset = offset;
673         if (parent_tree) {
674                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
675                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsSubBlob);
676         }
678         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix(tvb, offset, pinfo, tree, di, drep);
680         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_signature(tvb, offset, pinfo, tree, di, drep);
682         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
684         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
686         proto_item_set_len(item, offset-old_offset);
689         if (di->call_data->flags & DCERPC_IS_NDR64) {
690                 ALIGN_TO_3_BYTES;
691         }
693         return offset;
696 static int
697 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_)
699         int conformant = di->conformant_run;
700         tvbuff_t *subtvb;
702         if (!conformant) {
703                 guint32 saved_flags = di->call_data->flags;
704                 dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
705                 guint32 size = 0;
706                 if (ndr_size_ptr != NULL) {
707                         size = ndr_size_ptr->private_data.val64;
708                         di->ptr_stack = ndr_size_ptr->parent;
709                 }
710                 di->call_data->flags &= ~DCERPC_IS_NDR64;
711                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);
712                 drsuapi_dissect_element_supplementalCredentialsBlob_sub_(subtvb, 0, pinfo, tree, di, drep);
713                 offset += (int)size;
714                 di->call_data->flags = saved_flags;
715                 di->ptr_stack = ndr_size_ptr;
716         }
718         return offset;
721 static int
722 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_)
724         dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
725         guint32 ndr_size = 0;
727         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsBlob___ndr_size, 0, &ndr_size);
728         if (ndr_size_ptr != NULL) {
729                 ndr_size_ptr->private_data.val64 = ndr_size;
730         }
732         return offset;
736 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_)
738         /*manual*/
739         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
740         dcerpc_ptr_stack *ndr_size_ptr = NULL;
741         proto_item *item = NULL;
742         proto_tree *tree = NULL;
743         int old_offset;
745         ALIGN_TO_4_BYTES;
747         old_offset = offset;
749         if (parent_tree) {
750                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
751                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsBlob);
752         }
754         ndr_size_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
755         if (ndr_size_ptr != NULL) {
756                 ndr_size_ptr->parent = saved_ptr;
757         }
758         di->ptr_stack = ndr_size_ptr;
760         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown1(tvb, offset, pinfo, tree, di, drep);
762         offset = drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size(tvb, offset, pinfo, tree, di, drep);
764         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown2(tvb, offset, pinfo, tree, di, drep);
766         offset = drsuapi_dissect_element_supplementalCredentialsBlob_sub(tvb, offset, pinfo, tree, di, drep);
768         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown3(tvb, offset, pinfo, tree, di, drep);
770         di->ptr_stack = saved_ptr;
772         proto_item_set_len(item, offset-old_offset);
775         if (di->call_data->flags & DCERPC_IS_NDR64) {
776                 ALIGN_TO_4_BYTES;
777         }
779         return offset;
781 static int
782 drsuapi_dissect_supplementalCredentials(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
784         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
785         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
786         static dcerpc_call_value call_data = { 0, };
787         int offset;
789         /* fake whatever state the dcerpc runtime support needs */
790         di.conformant_run=0;
791         /* we need di->call_data->flags.NDR64 == 0 */
792         di.call_data=&call_data;
793         init_ndr_pointer_list(&di);
794         di.ptr_stack = parent_di->ptr_stack;
795         offset = drsuapi_dissect_struct_supplementalCredentialsBlob(tvb, 0, pinfo, parent_tree, &di, drep,
796                                 hf_drsuapi_sch_supplementalCredentials, 0);
797         free_ndr_pointer_list(&di);
798         return offset;
801 static int
802 drsuapi_dissect_unicodePwd(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
804         int offset = 0;
805         dcerpc_ptr_stack *ptr = parent_di->ptr_stack;
806         guint32 rid = 0;
807         int keytype = 23;
808         int keylength = 16;
809         tvbuff_t *keytvb = tvb_new_subset_length(tvb, offset, keylength);
810         guint8 keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
811         char origin[128] = {0, };
813         if (ptr != NULL) {
814                 rid = ptr->private_data.val64;
815         }
817         tvb_memcpy(keytvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
818         snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.unicodePwd", rid);
820         kerberos_inject_longterm_key(pinfo, parent_tree, NULL, keytvb,
821                                      keytype, keylength, keyvalue,
822                                      origin);
823         offset += 16;
825         return offset;
828 static int
829 drsuapi_dissect_ntPwdHistory(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
831         dcerpc_ptr_stack *ptr = parent_di->ptr_stack;
832         guint32 rid = 0;
833         guint num_hashes = tvb_reported_length(tvb)/16;
834         guint idx;
835         int offset = 0;
837         if (ptr != NULL) {
838                 rid = ptr->private_data.val64;
839         }
841         for (idx = 0; idx < num_hashes; idx++) {
842                 int keytype = 23;
843                 int keylength = 16;
844                 tvbuff_t *keytvb = tvb_new_subset_length(tvb, offset, keylength);
845                 guint8 keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
846                 char origin[128] = {0, };
848                 tvb_memcpy(keytvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
849                 snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.ntPwdHistory[%u]", rid, idx);
851                 kerberos_inject_longterm_key(pinfo, parent_tree, NULL, keytvb,
852                                              keytype, keylength, keyvalue,
853                                              origin);
854                 offset += 16;
855         }
857         return offset;
860 typedef int (*attr_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
862 static int
863 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_)
865         /*manual*/
866         dcerpc_ptr_stack *ptr = di->ptr_stack;
867         guint32 rid = 0;
868         guint32 attid = 0;
869         int start_offset = offset;
870         int length;
871         guint8 _confounder[16] = { 0, };
872         guint8 *confounder;
873         guint8 decryption_key[HASH_MD5_LENGTH] = { 0, };
874         gcry_cipher_hd_t rc4_handle = NULL;
875         gcry_buffer_t iov[2] = { {0, },};
876         gcry_error_t err;
877         guint8 *buf = NULL;
878         int buf_len;
879         guint8 *payload_buf = NULL;
880         int payload_len = 0;
881         tvbuff_t *payload_tvb = NULL;
882         gboolean rid_crypt = FALSE;
883         const char *attr_name = NULL;
884         attr_dissector_fn_t attr_dissector_fn = NULL;
885         char source_name[64] = { 0,};
887         offset = dissect_ndr_datablob(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsAttributeValue_blob, 0);
888         if (ptr == NULL) {
889                 return offset;
890         }
891         if (ptr->parent == NULL) {
892                 return offset;
893         }
895 // TODO check dissect_ndr_lm_nt_hash_cb...
896         rid = ptr->parent->private_data.val64;
897         attid = ptr->private_data.val64;
899         switch (attid) {
900         case DRSUAPI_ATTID_dBCSPwd:
901                 attr_name = "dBCSPwd";
902                 rid_crypt = TRUE;
903                 break;
904         case DRSUAPI_ATTID_unicodePwd:
905                 attr_name = "unicodePwd";
906                 attr_dissector_fn = drsuapi_dissect_unicodePwd;
907                 rid_crypt = TRUE;
908                 break;
909         case DRSUAPI_ATTID_ntPwdHistory:
910                 attr_name = "ntPwdHistory";
911                 attr_dissector_fn = drsuapi_dissect_ntPwdHistory;
912                 rid_crypt = TRUE;
913                 break;
914         case DRSUAPI_ATTID_lmPwdHistory:
915                 attr_name = "lmPwdHistory";
916                 rid_crypt = TRUE;
917                 break;
918         case DRSUAPI_ATTID_supplementalCredentials:
919                 attr_name = "supplementalCredentials";
920                 attr_dissector_fn = drsuapi_dissect_supplementalCredentials;
921                 break;
922         case DRSUAPI_ATTID_priorValue:
923                 attr_name = "priorValue";
924                 break;
925         case DRSUAPI_ATTID_currentValue:
926                 attr_name = "currentValue";
927                 break;
928         case DRSUAPI_ATTID_trustAuthOutgoing:
929                 attr_name = "trustAuthOutgoing";
930                 break;
931         case DRSUAPI_ATTID_trustAuthIncoming:
932                 attr_name = "trustAuthIncoming";
933                 break;
934         case DRSUAPI_ATTID_initialAuthOutgoing:
935                 attr_name = "initialAuthOutgoing";
936                 break;
937         case DRSUAPI_ATTID_initialAuthIncoming:
938                 attr_name = "initialAuthIncoming";
939                 break;
940         default:
941                 return offset;
942         }
944         length = offset - start_offset;
946         if (length < 24) {
947                 return offset;
948         }
949         start_offset += 4;
950         length -= 4;
952 if (0) {
953         proto_tree_add_text_internal(tree, tvb, start_offset, length,
954                         "METZE rid_crypt:%s RID:%d ATTID:0x%08X ATTR[%s] length=%d session_key=%s",
955                         rid_crypt ? "YES" : "NO",
956                         rid, attid, attr_name,
957                         length,
958                         di->auth_session_key != NULL ?
959                         di->auth_session_key->id_str : "NO");
962         if (di->auth_session_key == NULL) {
963                 return offset;
964         }
966         if (!tvb_bytes_exist(tvb, start_offset, length)) {
967                 return offset;
968         }
970         confounder = tvb_memcpy(tvb, _confounder, start_offset, 16);
971         buf_len = length - 16;
972         buf = tvb_memdup(pinfo->pool, tvb, start_offset + 16, buf_len);
973         if (buf == NULL) {
974                 return offset;
975         }
977         iov[0].len = di->auth_session_key->keylength;
978         iov[0].data = di->auth_session_key->keyvalue;
979         iov[1].len = 16;
980         iov[1].data = confounder;
982         err = gcry_md_hash_buffers(GCRY_MD_MD5, 0, decryption_key, iov, 2);
983         if (err != 0) {
984                 ws_warning("GCRY: gcry_md_hash_buffers(GCRY_MD_MD5) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
985                 return offset;
986         }
988         err = gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
989         if (err != 0) {
990                 ws_warning("GCRY: gcry_cipher_open(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
991                 return offset;
992         }
993         err = gcry_cipher_setkey(rc4_handle, decryption_key, HASH_MD5_LENGTH);
994         if (err != 0) {
995                 ws_warning("GCRY: gcry_cipher_setkey(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
996                 gcry_cipher_close(rc4_handle);
997                 return offset;
998         }
1000         err = gcry_cipher_decrypt(rc4_handle, buf, buf_len, NULL, 0);
1001         if (err != 0) {
1002                 ws_warning("GCRY: gcry_cipher_decrypt(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1003                 gcry_cipher_close(rc4_handle);
1004                 return offset;
1005         }
1006         gcry_cipher_close(rc4_handle);
1008         payload_buf = buf + 4;
1009         payload_len = buf_len - 4;
1011         if (rid_crypt && rid != 0) {
1012                 guint8 rk[14];
1013                 guint8 ri = 0;
1014                 guint8 *hb = payload_buf;
1015                 guint32 hl = payload_len;
1016                 guint32 hi;
1018                 /*
1019                  * We have a payload contains one or more
1020                  * NT Hashes (16 bytes each).
1021                  */
1022                 if ((hl % 16) != 0) {
1023                         return offset;
1024                 }
1026                 /*
1027                  * We build a 112 bit key based on the RID
1028                  *
1029                  * With that we need to decrypt each NT Hash (16 byte)
1030                  *
1031                  * DES is based on 8 byte blocks, which mean
1032                  * we can use the first 7 bytes (56Bit) of the key to
1033                  * decrypt the first 8 bytes of the NT Hash and
1034                  * the last 7 bytes (also 56Bit) of the key to
1035                  * decrypt the 2nd 8 bytes of the NT Hash.
1036                  */
1038                 rk[0] = rk[4] = rk[8] = rk[12] = (guint8)(rid & 0xFF);
1039                 rk[1] = rk[5] = rk[9] = rk[13] = (guint8)((rid >> 8) & 0xFF);
1040                 rk[2] = rk[6] = rk[10]         = (guint8)((rid >> 16) & 0xFF);
1041                 rk[3] = rk[7] = rk[11]         = (guint8)((rid >> 24) & 0xFF);
1043                 /* loop in 8 byte steps and toggle the key index between 0 and 7 */
1044                 for (hi=0, ri = 0; hi < hl; hi += 8, ri = ri == 0 ? 7 : 0) {
1045                         guint8 *h64 = &hb[hi];
1046                         guint8 *rk56 = &rk[ri];
1047                         guint8 tmp64[8];
1048                         memcpy(tmp64, h64, 8);
1049                         decrypt_des_ecb(h64, tmp64, rk56);
1050                 }
1051         }
1053         payload_tvb = tvb_new_child_real_data(tvb, payload_buf, payload_len, payload_len);
1055         snprintf(source_name, sizeof(source_name)-1, "DRSUAPI Decrypted %s RID=%u", attr_name, rid);
1056         add_new_data_source(pinfo, payload_tvb, source_name);
1057         proto_tree_add_text_internal(tree, payload_tvb, 0, payload_len, "%s", source_name);
1059         if (attr_dissector_fn == NULL) {
1060                 return offset;
1061         }
1063         di->ptr_stack = ptr->parent;
1064         attr_dissector_fn(payload_tvb, pinfo, tree, di);
1065         di->ptr_stack = ptr;
1067         return offset;
1071 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_)
1073         /*manual*/
1074         dcerpc_ptr_stack *rid_ptr = di->ptr_stack;
1075         proto_item *item = NULL;
1076         proto_tree *tree = NULL;
1077         int old_offset;
1079         ALIGN_TO_5_BYTES;
1081         old_offset = offset;
1083         if (parent_tree) {
1084                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1085                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaAttribute);
1086         }
1088         if (rid_ptr != NULL) {
1089                 dcerpc_ptr_stack *attid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
1090                 if (attid_ptr != NULL) {
1091                         attid_ptr->parent = rid_ptr;
1092                 }
1093                 di->ptr_stack = attid_ptr;
1094         }
1096         offset = drsuapi_dissect_element_DsReplicaAttribute_attid(tvb, offset, pinfo, tree, di, drep);
1098         offset = drsuapi_dissect_element_DsReplicaAttribute_value_ctr(tvb, offset, pinfo, tree, di, drep);
1100         di->ptr_stack = rid_ptr;
1102         proto_item_set_len(item, offset-old_offset);
1105         if (di->call_data->flags & DCERPC_IS_NDR64) {
1106                 ALIGN_TO_5_BYTES;
1107         }
1109         return offset;
1113 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_)
1115         /*manual*/
1116         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
1117         dcerpc_ptr_stack *rid_ptr = NULL;
1118         proto_item *item = NULL;
1119         proto_tree *tree = NULL;
1120         int old_offset;
1122         ALIGN_TO_5_BYTES;
1124         old_offset = offset;
1126         if (parent_tree) {
1127                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1128                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaObject);
1129         }
1131         rid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
1132         di->ptr_stack = rid_ptr;
1134         offset = drsuapi_dissect_element_DsReplicaObject_identifier(tvb, offset, pinfo, tree, di, drep);
1136         offset = drsuapi_dissect_element_DsReplicaObject_flags(tvb, offset, pinfo, tree, di, drep);
1138         offset = drsuapi_dissect_element_DsReplicaObject_attribute_ctr(tvb, offset, pinfo, tree, di, drep);
1140         di->ptr_stack = saved_ptr;
1142         proto_item_set_len(item, offset-old_offset);
1145         if (di->call_data->flags & DCERPC_IS_NDR64) {
1146                 ALIGN_TO_5_BYTES;
1147         }
1149         return offset;
1152 static int
1153 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_)
1155         offset = drsuapi_dissect_struct_DsReplicaObjectListItem(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsReplicaObjectListItem_next_object,0);
1157         return offset;
1160 static int
1161 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_)
1163         offset = drsuapi_dissect_struct_DsReplicaObjectListItemEx(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsReplicaObjectListItemEx_next_object,0);
1165         return offset;
1168 static int
1169 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_)
1171         offset = drsuapi_dissect_struct_DsAddEntry_AttrErrListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsAddEntry_AttrErrListItem_V1_next,0);
1173         return offset;
1176 static int
1177 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_)
1179         offset = drsuapi_dissect_struct_DsaAddressListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsaAddressListItem_V1_next,0);
1181         return offset;
1184 static int
1185 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_)
1187         offset = drsuapi_dissect_struct_DsAddEntry_RefErrListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsAddEntry_RefErrListItem_V1_next,0);
1189         return offset;
1192 static int
1193 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_)
1195         char *data;
1197         offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep, sizeof(guint16), hf_drsuapi_String_name, FALSE, &data);
1198         proto_item_append_text(tree, ": %s", data);
1200         return offset;
1203 static int
1204 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_)
1206         char *data;
1208         offset = dissect_ndr_cstring(tvb, offset, pinfo, tree, di, drep, sizeof(guint16), hf_DsReplicaObjectIdentifier_dn, FALSE, &data);
1209         proto_item_append_text(tree, ": %s", data);
1211         return offset;
1214 /* IDL: struct { */
1215 /* IDL:         [range(1,10000)] uint32 length; */
1216 /* IDL:         [size_is(length)] uint8 data[*]; */
1217 /* IDL: } */
1219 static int
1220 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_)
1222         offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsBindInfoCtr_length, 0);
1224         return offset;
1227 static int
1228 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_);
1230 static int
1231 drsuapi_dissect_element_DsBindInfoCtr_data_(tvbuff_t *tvb, int offset, int length, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1233         offset = drsuapi_dissect_DsBindInfo(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsBindInfoCtr_info, length);
1235         return offset;
1238 static int
1239 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_)
1241         offset = dissect_ndr_ucarray_block(tvb, offset, pinfo, tree, di, drep, drsuapi_dissect_element_DsBindInfoCtr_data_);
1243         return offset;
1247 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_)
1249         proto_item *item = NULL;
1250         proto_tree *tree = NULL;
1251         int old_offset;
1253         ALIGN_TO_4_BYTES;
1255         old_offset = offset;
1257         if (parent_tree) {
1258                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1259                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsBindInfoCtr);
1260         }
1262         offset = drsuapi_dissect_element_DsBindInfoCtr_length_(tvb, offset, pinfo, tree, di, drep);
1264         offset = drsuapi_dissect_element_DsBindInfoCtr_data(tvb, offset, pinfo, tree, di, drep);
1267         proto_item_set_len(item, offset-old_offset);
1269         if (di->call_data->flags & DCERPC_IS_NDR64) {
1270                 ALIGN_TO_4_BYTES;
1271         }
1273         return offset;
1276 static int
1277 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_)
1279         proto_item *item = NULL;
1280         proto_tree *tree = NULL;
1281         int old_offset;
1282         guint32 length = param;
1284         old_offset = offset;
1285         if (parent_tree) {
1286                 tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_drsuapi_drsuapi_DsBindInfo, &item, "drsuapi_DsBindInfo");
1287         }
1289         if (length >= 52) {
1290                 drsuapi_dissect_struct_DsBindInfo52(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info52,0);
1291         } else if (length >= 48) {
1292                 drsuapi_dissect_struct_DsBindInfo48(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info48,0);
1293         } else if (length >= 32) {
1294                 drsuapi_dissect_struct_DsBindInfo32(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info32,0);
1295         } else if (length >= 28) {
1296                 drsuapi_dissect_struct_DsBindInfo28(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info28,0);
1297         } else if (length >= 24) {
1298                 drsuapi_dissect_struct_DsBindInfo24(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info24,0);
1299         }
1300         offset += length;
1301         proto_item_set_len(item, offset-old_offset);
1303         return offset;
1305 CODE END