Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ncp-sss.c
blob445c6926968d49754ca81bb37e6e2df21847c7b3
1 /* packet-ncp-sss.c
2 * Routines for Novell SecretStore Services
3 * Greg Morris <gmorris@novell.com>
4 * Copyright (c) Novell, Inc. 2002-2003
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include "packet-ncp-int.h"
17 #include "packet-ncp-sss.h"
19 void proto_register_sss(void);
21 static int ett_sss;
23 static int proto_sss;
24 static int hf_sss_buffer_size;
25 static int hf_sss_ping_version;
26 static int hf_sss_flags;
27 static int hf_sss_context;
28 static int hf_sss_frag_handle;
29 static int hf_sss_length;
30 static int hf_sss_verb;
31 static int hf_sss_user;
32 static int hf_sss_secret;
33 static int hf_sss_sss_version;
34 static int hf_sss_return_code;
35 static int hf_sss_enc_cred;
36 static int hf_sss_enc_data;
37 static int hf_sss_bit1;
38 static int hf_sss_bit2;
39 static int hf_sss_bit3;
40 static int hf_sss_bit4;
41 static int hf_sss_bit5;
42 static int hf_sss_bit6;
43 static int hf_sss_bit7;
44 static int hf_sss_bit8;
45 static int hf_sss_bit9;
46 static int hf_sss_bit10;
47 static int hf_sss_bit11;
48 static int hf_sss_bit12;
49 static int hf_sss_bit13;
50 static int hf_sss_bit14;
51 static int hf_sss_bit15;
52 static int hf_sss_bit16;
53 static int hf_sss_bit17;
54 static int hf_sss_bit18;
55 static int hf_sss_bit19;
56 static int hf_sss_bit20;
57 static int hf_sss_bit21;
58 static int hf_sss_bit22;
59 static int hf_sss_bit23;
60 static int hf_sss_bit24;
61 static int hf_sss_bit25;
62 static int hf_sss_bit26;
63 static int hf_sss_bit27;
64 static int hf_sss_bit28;
65 static int hf_sss_bit29;
66 static int hf_sss_bit30;
67 static int hf_sss_bit31;
68 static int hf_sss_bit32;
70 static expert_field ei_return_code;
72 static const value_string sss_func_enum[] = {
73 { 0x00000001, "Ping Server" },
74 { 0x00000002, "Fragment" },
75 { 0x00000003, "Write App Secrets" },
76 { 0x00000004, "Add Secret ID" },
77 { 0x00000005, "Remove Secret ID" },
78 { 0x00000006, "Remove SecretStore" },
79 { 0x00000007, "Enumerate Secret IDs" },
80 { 0x00000008, "Unlock Store" },
81 { 0x00000009, "Set Master Password" },
82 { 0x0000000a, "Get Service Information" },
83 { 0, NULL }
86 static const value_string sss_errors_enum[] = {
87 { 0xFFFFFCE0, "(-800) Target object could not be found" },
88 { 0xFFFFFCDF, "(-801) NICI operations have failed" },
89 { 0xFFFFFCDE, "(-802) The Secret ID is not in the user secret store" },
90 { 0xFFFFFCDD, "(-803) Some internal operating system services have not been available" },
91 { 0xFFFFFCDC, "(-804) Access to the target Secret Store has been denied" },
92 { 0xFFFFFCDB, "(-805) NDS internal NDS services have not been available" },
93 { 0xFFFFFCDA, "(-806) Secret has not been initialized with a write" },
94 { 0xFFFFFCD9, "(-807) Size of the buffer is not in a nominal range between minimum and maximum" },
95 { 0xFFFFFCD8, "(-808) Client and server components are not of the compatible versions" },
96 { 0xFFFFFCD7, "(-809) Secret Store data on the server has been corrupted" },
97 { 0xFFFFFCD6, "(-810) Secret ID already exists in the SecretStore" },
98 { 0xFFFFFCD5, "(-811) User NDS password has been changed by the administrator" },
99 { 0xFFFFFCD4, "(-812) Target NDS user object not found" },
100 { 0xFFFFFCD3, "(-813) Target NDS user object does not have a Secret Store" },
101 { 0xFFFFFCD2, "(-814) Secret Store is not on the network" },
102 { 0xFFFFFCD1, "(-815) Length of the Secret ID buffer exceeds the limit" },
103 { 0xFFFFFCD0, "(-816) Length of the enumeration buffer is too short" },
104 { 0xFFFFFCCF, "(-817) User not authenticated" },
105 { 0xFFFFFCCE, "(-818) Not supported operations" },
106 { 0xFFFFFCCD, "(-819) Typed in NDS password not valid" },
107 { 0xFFFFFCCC, "(-820) Session keys of the client and server NICI are out of sync" },
108 { 0xFFFFFCCB, "(-821) Requested service not yet supported" },
109 { 0xFFFFFCCA, "(-822) NDS authentication type not supported" },
110 { 0xFFFFFCC9, "(-823) Unicode text conversion operation failed" },
111 { 0xFFFFFCC8, "(-824) Connection to server is lost" },
112 { 0xFFFFFCC7, "(-825) Cryptographic operation failed" },
113 { 0xFFFFFCC6, "(-826) Opening a connection to the server failed" },
114 { 0xFFFFFCC5, "(-827) Access to server connection failed" },
115 { 0xFFFFFCC4, "(-828) Size of the enumeration buffer exceeds the limit" },
116 { 0xFFFFFCC3, "(-829) Size of the Secret buffer exceeds the limit" },
117 { 0xFFFFFCC2, "(-830) Length of the Secret ID should be greater than zero" },
118 { 0xFFFFFCC1, "(-831) Protocol data corrupted on the wire" },
119 { 0xFFFFFCC0, "(-832) Enhanced protection's password validation failed. Access to the secret denied" },
120 { 0xFFFFFCBF, "(-833) Schema is not extended to support SecretStore on the target tree" },
121 { 0xFFFFFCBE, "(-834) One of the optional service attributes is not instantiated" },
122 { 0xFFFFFCBD, "(-835) Server has been upgraded and the users SecretStore should be updated" },
123 { 0xFFFFFCBC, "(-836) Master password could not be verified to read or unlock the secrets" },
124 { 0xFFFFFCBB, "(-837) Master password has not been set on the SecretStore" },
125 { 0xFFFFFCBA, "(-838) Ability to use master password has been disabled" },
126 { 0xFFFFFCB9, "(-839) Not a writeable replica of NDS" },
127 { 0xFFFFFCB8, "(-840) The API was unable to find a value for an attribute in the Directory" },
128 { 0xFFFFFCB7, "(-841) A parameter passed to the API has not been properly initialized" },
129 { 0xFFFFFCB6, "(-842) The connection to SecretStore requires SSL to be secure" },
130 { 0xFFFFFCB5, "(-843) The client could not locate a server that supports the policy override required by the caller" },
131 { 0xFFFFFCB4, "(-844) Attempt to unlock SecretStore failed because the store is not locked" },
132 { 0xFFFFFCB3, "(-845) NDS Replica on the server that holds SecretStore is out of sync with the replica ring" },
133 { 0xFFFFFC88, "(-888) Feature not yet implemented" },
134 { 0xFFFFFC7D, "(-899) Products BETA life has expired" },
135 { 0, NULL }
139 static void
140 process_flags(proto_tree *sss_tree, tvbuff_t *tvb, uint32_t foffset)
142 char flags_str[1024];
143 const char *sep;
144 proto_item *tinew;
145 proto_tree *flags_tree;
146 uint32_t i;
147 uint32_t bvalue = 0;
148 uint32_t flags = 0;
150 bvalue = 0x00000001;
151 flags_str[0]='\0';
152 sep="";
153 flags = tvb_get_ntohl(tvb, foffset);
154 for (i = 0 ; i < 256; i++) {
155 if (flags & bvalue) {
156 (void) g_strlcat(flags_str, sep, 1024);
157 switch(bvalue) {
158 case 0x00000001:
159 (void) g_strlcat(flags_str, "Enhanced Protection", 1024);
160 break;
161 case 0x00000002:
162 (void) g_strlcat(flags_str, "Create ID", 1024);
163 break;
164 case 0x00000004:
165 (void) g_strlcat(flags_str, "Remove Lock", 1024);
166 break;
167 case 0x00000008:
168 (void) g_strlcat(flags_str, "Repair", 1024);
169 break;
170 case 0x00000010:
171 (void) g_strlcat(flags_str, "Unicode", 1024);
172 break;
173 case 0x00000020:
174 (void) g_strlcat(flags_str, "EP Master Password Used", 1024);
175 break;
176 case 0x00000040:
177 (void) g_strlcat(flags_str, "EP Password Used", 1024);
178 break;
179 case 0x00000080:
180 (void) g_strlcat(flags_str, "Set Tree Name", 1024);
181 break;
182 case 0x00000100:
183 (void) g_strlcat(flags_str, "Get Context", 1024);
184 break;
185 case 0x00000200:
186 (void) g_strlcat(flags_str, "Destroy Context", 1024);
187 break;
188 case 0x00000400:
189 (void) g_strlcat(flags_str, "Not Defined", 1024);
190 break;
191 case 0x00000800:
192 (void) g_strlcat(flags_str, "Not Defined", 1024);
193 break;
194 case 0x00001000:
195 (void) g_strlcat(flags_str, "EP Lock", 1024);
196 break;
197 case 0x00002000:
198 (void) g_strlcat(flags_str, "Not Initialized", 1024);
199 break;
200 case 0x00004000:
201 (void) g_strlcat(flags_str, "Enhanced Protection", 1024);
202 break;
203 case 0x00008000:
204 (void) g_strlcat(flags_str, "Store Not Synced", 1024);
205 break;
206 case 0x00010000:
207 (void) g_strlcat(flags_str, "Admin Last Modified", 1024);
208 break;
209 case 0x00020000:
210 (void) g_strlcat(flags_str, "EP Password Present", 1024);
211 break;
212 case 0x00040000:
213 (void) g_strlcat(flags_str, "EP Master Password Present", 1024);
214 break;
215 case 0x00080000:
216 (void) g_strlcat(flags_str, "MP Disabled", 1024);
217 break;
218 case 0x00100000:
219 (void) g_strlcat(flags_str, "Not Defined", 1024);
220 break;
221 case 0x00200000:
222 (void) g_strlcat(flags_str, "Not Defined", 1024);
223 break;
224 case 0x00400000:
225 (void) g_strlcat(flags_str, "Not Defined", 1024);
226 break;
227 case 0x00800000:
228 (void) g_strlcat(flags_str, "Not Defined", 1024);
229 break;
230 case 0x01000000:
231 (void) g_strlcat(flags_str, "Not Defined", 1024);
232 break;
233 case 0x02000000:
234 (void) g_strlcat(flags_str, "Not Defined", 1024);
235 break;
236 case 0x04000000:
237 (void) g_strlcat(flags_str, "Not Defined", 1024);
238 break;
239 case 0x08000000:
240 (void) g_strlcat(flags_str, "Not Defined", 1024);
241 break;
242 case 0x10000000:
243 (void) g_strlcat(flags_str, "Not Defined", 1024);
244 break;
245 case 0x20000000:
246 (void) g_strlcat(flags_str, "Not Defined", 1024);
247 break;
248 case 0x40000000:
249 (void) g_strlcat(flags_str, "Not Defined", 1024);
250 break;
251 case 0x80000000:
252 (void) g_strlcat(flags_str, "Not Defined", 1024);
253 break;
254 default:
255 break;
257 sep = ", ";
259 bvalue = bvalue*2;
262 tinew = proto_tree_add_uint(sss_tree, hf_sss_flags, tvb, foffset, 4, flags);
263 flags_tree = proto_item_add_subtree(tinew, ett_nds);
265 bvalue = 0x00000001;
267 for (i = 0 ; i < 256; i++ ) {
268 if (flags & bvalue) {
269 switch(bvalue) {
270 case 0x00000001:
271 proto_tree_add_item(flags_tree, hf_sss_bit1, tvb, foffset, 4, ENC_BIG_ENDIAN);
272 break;
273 case 0x00000002:
274 proto_tree_add_item(flags_tree, hf_sss_bit2, tvb, foffset, 4, ENC_BIG_ENDIAN);
275 break;
276 case 0x00000004:
277 proto_tree_add_item(flags_tree, hf_sss_bit3, tvb, foffset, 4, ENC_BIG_ENDIAN);
278 break;
279 case 0x00000008:
280 proto_tree_add_item(flags_tree, hf_sss_bit4, tvb, foffset, 4, ENC_BIG_ENDIAN);
281 break;
282 case 0x00000010:
283 proto_tree_add_item(flags_tree, hf_sss_bit5, tvb, foffset, 4, ENC_BIG_ENDIAN);
284 break;
285 case 0x00000020:
286 proto_tree_add_item(flags_tree, hf_sss_bit6, tvb, foffset, 4, ENC_BIG_ENDIAN);
287 break;
288 case 0x00000040:
289 proto_tree_add_item(flags_tree, hf_sss_bit7, tvb, foffset, 4, ENC_BIG_ENDIAN);
290 break;
291 case 0x00000080:
292 proto_tree_add_item(flags_tree, hf_sss_bit8, tvb, foffset, 4, ENC_BIG_ENDIAN);
293 break;
294 case 0x00000100:
295 proto_tree_add_item(flags_tree, hf_sss_bit9, tvb, foffset, 4, ENC_BIG_ENDIAN);
296 break;
297 case 0x00000200:
298 proto_tree_add_item(flags_tree, hf_sss_bit10, tvb, foffset, 4, ENC_BIG_ENDIAN);
299 break;
300 case 0x00000400:
301 proto_tree_add_item(flags_tree, hf_sss_bit11, tvb, foffset, 4, ENC_BIG_ENDIAN);
302 break;
303 case 0x00000800:
304 proto_tree_add_item(flags_tree, hf_sss_bit12, tvb, foffset, 4, ENC_BIG_ENDIAN);
305 break;
306 case 0x00001000:
307 proto_tree_add_item(flags_tree, hf_sss_bit13, tvb, foffset, 4, ENC_BIG_ENDIAN);
308 break;
309 case 0x00002000:
310 proto_tree_add_item(flags_tree, hf_sss_bit14, tvb, foffset, 4, ENC_BIG_ENDIAN);
311 break;
312 case 0x00004000:
313 proto_tree_add_item(flags_tree, hf_sss_bit15, tvb, foffset, 4, ENC_BIG_ENDIAN);
314 break;
315 case 0x00008000:
316 proto_tree_add_item(flags_tree, hf_sss_bit16, tvb, foffset, 4, ENC_BIG_ENDIAN);
317 break;
318 case 0x00010000:
319 proto_tree_add_item(flags_tree, hf_sss_bit17, tvb, foffset, 4, ENC_BIG_ENDIAN);
320 break;
321 case 0x00020000:
322 proto_tree_add_item(flags_tree, hf_sss_bit18, tvb, foffset, 4, ENC_BIG_ENDIAN);
323 break;
324 case 0x00040000:
325 proto_tree_add_item(flags_tree, hf_sss_bit19, tvb, foffset, 4, ENC_BIG_ENDIAN);
326 break;
327 case 0x00080000:
328 proto_tree_add_item(flags_tree, hf_sss_bit20, tvb, foffset, 4, ENC_BIG_ENDIAN);
329 break;
330 case 0x00100000:
331 proto_tree_add_item(flags_tree, hf_sss_bit21, tvb, foffset, 4, ENC_BIG_ENDIAN);
332 break;
333 case 0x00200000:
334 proto_tree_add_item(flags_tree, hf_sss_bit22, tvb, foffset, 4, ENC_BIG_ENDIAN);
335 break;
336 case 0x00400000:
337 proto_tree_add_item(flags_tree, hf_sss_bit23, tvb, foffset, 4, ENC_BIG_ENDIAN);
338 break;
339 case 0x00800000:
340 proto_tree_add_item(flags_tree, hf_sss_bit24, tvb, foffset, 4, ENC_BIG_ENDIAN);
341 break;
342 case 0x01000000:
343 proto_tree_add_item(flags_tree, hf_sss_bit25, tvb, foffset, 4, ENC_BIG_ENDIAN);
344 break;
345 case 0x02000000:
346 proto_tree_add_item(flags_tree, hf_sss_bit26, tvb, foffset, 4, ENC_BIG_ENDIAN);
347 break;
348 case 0x04000000:
349 proto_tree_add_item(flags_tree, hf_sss_bit27, tvb, foffset, 4, ENC_BIG_ENDIAN);
350 break;
351 case 0x08000000:
352 proto_tree_add_item(flags_tree, hf_sss_bit28, tvb, foffset, 4, ENC_BIG_ENDIAN);
353 break;
354 case 0x10000000:
355 proto_tree_add_item(flags_tree, hf_sss_bit29, tvb, foffset, 4, ENC_BIG_ENDIAN);
356 break;
357 case 0x20000000:
358 proto_tree_add_item(flags_tree, hf_sss_bit30, tvb, foffset, 4, ENC_BIG_ENDIAN);
359 break;
360 case 0x40000000:
361 proto_tree_add_item(flags_tree, hf_sss_bit31, tvb, foffset, 4, ENC_BIG_ENDIAN);
362 break;
363 case 0x80000000:
364 proto_tree_add_item(flags_tree, hf_sss_bit32, tvb, foffset, 4, ENC_BIG_ENDIAN);
365 break;
366 default:
367 break;
370 bvalue = bvalue*2;
372 return;
375 /* Find the delimiter, '*'.
376 * Returns the number of bytes from foffset to the delimiter or 0 if not
377 * found within 256 bytes from foffset */
378 static int
379 find_delimiter(tvbuff_t *tvb, int foffset)
381 int offset;
383 offset = tvb_find_uint8(tvb, foffset, 256, '*');
384 if (offset >= foffset) {
385 return offset - foffset;
387 return 0;
390 static int
391 sss_string(tvbuff_t* tvb, int hfinfo, proto_tree *sss_tree, int offset, bool little, uint32_t length)
393 int foffset = offset;
394 uint32_t str_length;
395 char buffer[1024];
396 size_t i = 0;
397 uint8_t c_char;
398 int length_remaining;
400 if (length==0) {
401 if (little) {
402 str_length = tvb_get_letohl(tvb, foffset);
403 } else {
404 str_length = tvb_get_ntohl(tvb, foffset);
406 foffset += 4;
407 } else {
408 str_length = length;
410 length_remaining = tvb_captured_length_remaining(tvb, foffset);
411 if (length_remaining <= 0) {
412 return foffset;
414 if (str_length > (unsigned)length_remaining || str_length > (sizeof(buffer)-1)) {
415 proto_tree_add_string(sss_tree, hfinfo, tvb, foffset,
416 length_remaining + 4, "<String too long to process>");
417 foffset += length_remaining;
418 return foffset;
420 if (str_length == 0) {
421 proto_tree_add_string(sss_tree, hfinfo, tvb, offset, 4, "<Not Specified>");
422 return foffset;
424 while (i < str_length) {
425 c_char = tvb_get_uint8(tvb, foffset);
426 if (g_ascii_isprint(c_char)) {
427 buffer[i++] = c_char;
428 } else {
429 if (c_char) {
430 buffer[i++] = '.';
431 } else {
432 /* Skip NULL-terminators */
433 str_length--;
436 foffset++;
438 buffer[i] = '\0';
440 if (length==0) {
441 if (little) {
442 str_length = tvb_get_letohl(tvb, offset);
443 } else {
444 str_length = tvb_get_ntohl(tvb, offset);
446 offset += 4;
447 } else {
448 str_length = length;
450 proto_tree_add_string(sss_tree, hfinfo, tvb, offset, str_length, buffer);
451 return foffset;
454 void
455 dissect_sss_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, ncp_req_hash_value *request_value)
457 uint8_t /*func,*/ subfunc = 0;
458 uint32_t subverb=0;
459 uint32_t msg_length=0;
460 uint32_t foffset= 0;
461 proto_tree *atree;
462 proto_item *aitem;
465 if (tvb_reported_length_remaining(tvb, foffset)<4) {
466 return;
468 foffset = 6;
469 /*func = tvb_get_uint8(tvb, foffset);*/
470 foffset += 1;
471 subfunc = tvb_get_uint8(tvb, foffset);
472 foffset += 1;
474 /* Fill in the PROTOCOL & INFO columns. */
475 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS");
476 col_add_fstr(pinfo->cinfo, COL_INFO, "C SecretStore - %s", val_to_str(subfunc, sss_func_enum, "Unknown (%d)"));
478 switch (subfunc) {
479 case 1:
480 atree = proto_tree_add_subtree_format(ncp_tree, tvb, foffset, -1, ett_sss, NULL, "Packet Type: %s", val_to_str(subfunc, sss_func_enum, "Unknown (%d)"));
481 proto_tree_add_item(atree, hf_sss_ping_version, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
482 foffset += 4;
483 proto_tree_add_item(atree, hf_sss_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
484 /*foffset += 4;*/
485 break;
486 case 2:
487 proto_tree_add_item(ncp_tree, hf_sss_frag_handle, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
488 if (tvb_get_letohl(tvb, foffset)==0xffffffff) { /* Fragment handle of -1 means no fragment. So process packet */
489 foffset += 4;
490 proto_tree_add_item(ncp_tree, hf_sss_buffer_size, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
491 foffset += 4;
492 proto_tree_add_item(ncp_tree, hf_sss_length, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
493 foffset += 4;
494 foffset += 12; /* Blank Context */
495 subverb = tvb_get_letohl(tvb, foffset);
496 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str(subverb, sss_verb_enum, "Unknown (%d)"));
498 aitem = proto_tree_add_item(ncp_tree, hf_sss_verb, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
499 atree = proto_item_add_subtree(aitem, ett_sss);
500 if (request_value) {
501 request_value->req_nds_flags=subverb;
503 foffset += 4;
504 process_flags(atree, tvb, foffset);
505 foffset += 4;
506 proto_tree_add_item(atree, hf_sss_context, tvb, foffset, 4, ENC_BIG_ENDIAN);
507 foffset += 4;
508 switch (subverb) {
509 case 0:
510 foffset += 4;
511 /*foffset =*/ sss_string(tvb, hf_sss_user, atree, foffset, true, 0);
512 break;
513 case 1:
514 foffset = sss_string(tvb, hf_sss_secret, atree, foffset, true, 0);
515 msg_length = tvb_get_letohl(tvb, foffset);
516 foffset += (msg_length+4); /* Unsure of what this length and parameter are */
517 /* A bad secret of length greater then 256 characters will cause frag
518 packets and then we will see these as malformed packets.
519 So check to make sure we still have data in the packet anytime
520 we read a secret. */
521 if (tvb_reported_length_remaining(tvb, foffset) > 4) {
522 /*foffset =*/ sss_string(tvb, hf_sss_user, atree, foffset, true, 0);
524 break;
525 case 2:
526 foffset += 4;
527 foffset = sss_string(tvb, hf_sss_secret, atree, foffset, true, 0);
528 if (tvb_reported_length_remaining(tvb, foffset) > 4) {
529 msg_length = tvb_get_letohl(tvb, foffset);
530 foffset += 4;
531 if (tvb_captured_length_remaining(tvb, foffset) < (int) msg_length) {
532 proto_tree_add_item(atree, hf_sss_enc_data, tvb, foffset, -1, ENC_NA);
533 } else {
534 proto_tree_add_item(atree, hf_sss_enc_data, tvb, foffset, msg_length, ENC_NA);
537 break;
538 case 3:
539 case 4:
540 foffset = sss_string(tvb, hf_sss_secret, atree, foffset, true, 0);
541 if (tvb_reported_length_remaining(tvb, foffset) > 4) {
542 /*foffset =*/ sss_string(tvb, hf_sss_user, atree, foffset, true, 0);
544 break;
545 case 5:
546 break;
547 case 6:
548 foffset = sss_string(tvb, hf_sss_secret, atree, foffset, true, 0);
549 if (tvb_reported_length_remaining(tvb, foffset) > 4) {
550 /*foffset =*/ sss_string(tvb, hf_sss_user, atree, foffset, true, 0);
552 break;
553 case 7:
554 msg_length = tvb_get_letohl(tvb, foffset);
555 foffset += 4;
556 proto_tree_add_item(atree, hf_sss_enc_cred, tvb, foffset, msg_length, ENC_NA);
557 break;
558 case 8:
559 case 9:
560 default:
561 break;
563 } else {
564 col_set_str(pinfo->cinfo, COL_INFO, "C SecretStore - fragment");
566 /* Fragments don't really carry a subverb so store 0xff as the subverb number */
567 if (request_value) {
568 request_value->req_nds_flags=255;
570 if (tvb_reported_length_remaining(tvb, foffset) > 8) {
571 foffset += 4;
572 proto_tree_add_item(ncp_tree, hf_sss_enc_data, tvb, foffset, -1, ENC_NA);
575 break;
576 case 3:
577 /* No Op */
578 break;
579 default:
580 break;
584 void
585 dissect_sss_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, uint8_t subfunc, ncp_req_hash_value *request_value)
587 uint32_t foffset=0;
588 uint32_t subverb=0;
589 uint32_t msg_length=0;
590 uint32_t return_code=0;
591 uint32_t number_of_items=0;
592 int32_t length_of_string=0;
593 uint32_t i = 0;
594 const char *str;
596 proto_tree *atree;
597 proto_item *expert_item;
599 foffset = 8;
600 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS");
601 if (tvb_captured_length_remaining(tvb, foffset)<4) {
602 return;
604 atree = proto_tree_add_subtree_format(ncp_tree, tvb, foffset, -1, ett_sss, NULL, "Function: %s", val_to_str_const(subfunc, sss_func_enum, "Unknown"));
605 switch (subfunc) {
606 case 1:
607 proto_tree_add_item(atree, hf_sss_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
608 foffset += 4;
609 proto_tree_add_item(atree, hf_sss_sss_version, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
610 /*foffset += 4;*/
611 break;
612 case 2:
613 if (request_value) {
614 subverb = request_value->req_nds_flags;
615 str = try_val_to_str(subverb, sss_verb_enum);
616 if (str) {
617 proto_tree_add_uint(atree, hf_sss_verb, tvb, foffset, -1, subverb);
620 proto_tree_add_item(atree, hf_sss_length, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
621 msg_length = tvb_get_letohl(tvb, foffset);
622 foffset += 4;
623 proto_tree_add_item(atree, hf_sss_frag_handle, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
624 foffset += 4;
625 msg_length -= 4;
626 if ((tvb_get_letohl(tvb, foffset-4)==0xffffffff) && (msg_length > 4)) {
627 foffset += 4;
628 return_code = tvb_get_letohl(tvb, foffset);
629 str = try_val_to_str(return_code, sss_errors_enum);
630 if (str) {
631 expert_item = proto_tree_add_item(atree, hf_sss_return_code, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
632 expert_add_info_format(pinfo, expert_item, &ei_return_code, "SSS Error: %s", str);
633 col_add_fstr(pinfo->cinfo, COL_INFO, "R Error - %s", val_to_str(return_code, sss_errors_enum, "Unknown (%d)"));
634 /*foffset+=4;*/
635 } else {
636 proto_tree_add_uint_format_value(atree, hf_sss_return_code, tvb, foffset, 4, 0, "Success (0x00000000)");
637 if (tvb_reported_length_remaining(tvb, foffset) > 8) {
638 foffset += 4;
639 if (request_value && subverb == 6) {
640 foffset += 4;
641 number_of_items = tvb_get_letohl(tvb, foffset);
642 foffset += 8;
643 for (i=0; i<number_of_items; i++) {
644 length_of_string = find_delimiter(tvb, foffset);
645 if (length_of_string > tvb_reported_length_remaining(tvb, foffset)) {
646 return;
648 foffset = sss_string(tvb, hf_sss_secret, atree, foffset, true, length_of_string);
649 if (tvb_reported_length_remaining(tvb, foffset) < 8) {
650 return;
652 foffset++;
654 } else {
655 proto_tree_add_item(atree, hf_sss_enc_data, tvb, foffset, tvb_captured_length_remaining(tvb, foffset), ENC_NA);
659 } else {
660 proto_tree_add_uint_format_value(atree, hf_sss_return_code, tvb, foffset, 4, 0, "Success (0x00000000)");
661 if (tvb_reported_length_remaining(tvb, foffset) > 8) {
662 foffset += 4;
663 proto_tree_add_item(atree, hf_sss_enc_data, tvb, foffset, tvb_captured_length_remaining(tvb, foffset), ENC_NA);
666 break;
667 case 3:
668 break;
669 default:
670 break;
674 void
675 proto_register_sss(void)
677 static hf_register_info hf_sss[] = {
678 { &hf_sss_buffer_size,
679 { "Buffer Size", "sss.buffer", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
681 { &hf_sss_ping_version,
682 { "Ping Version", "sss.ping_version", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
684 { &hf_sss_flags,
685 { "Flags", "sss.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
687 { &hf_sss_context,
688 { "Context", "sss.context", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
690 { &hf_sss_frag_handle,
691 { "Fragment Handle", "sss.frag_handle", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
693 { &hf_sss_length,
694 { "Length", "sss.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
696 { &hf_sss_verb,
697 { "Verb", "sss.verb", FT_UINT32, BASE_HEX, VALS(sss_verb_enum), 0x0, NULL, HFILL }},
699 { &hf_sss_user,
700 { "User", "sss.user", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
702 { &hf_sss_secret,
703 { "Secret ID", "sss.secret", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
705 { &hf_sss_sss_version,
706 { "SecretStore Protocol Version", "sss.version", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
708 { &hf_sss_return_code,
709 { "Return Code", "sss.return_code", FT_UINT32, BASE_HEX, VALS(sss_errors_enum), 0x0, NULL, HFILL }},
711 { &hf_sss_enc_cred,
712 { "Encrypted Credential", "sss.enc_cred", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
714 { &hf_sss_enc_data,
715 { "Encrypted Data", "sss.enc_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
717 { &hf_sss_bit1,
718 { "Enhanced Protection", "sss.bit1", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL }},
720 { &hf_sss_bit2,
721 { "Create ID", "sss.bit2", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL }},
723 { &hf_sss_bit3,
724 { "Remove Lock", "sss.bit3", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL }},
726 { &hf_sss_bit4,
727 { "Repair", "sss.bit4", FT_BOOLEAN, 32, NULL, 0x00000008, NULL, HFILL }},
729 { &hf_sss_bit5,
730 { "Unicode", "sss.bit5", FT_BOOLEAN, 32, NULL, 0x00000010, NULL, HFILL }},
732 { &hf_sss_bit6,
733 { "EP Master Password Used", "sss.bit6", FT_BOOLEAN, 32, NULL, 0x00000020, NULL, HFILL }},
735 { &hf_sss_bit7,
736 { "EP Password Used", "sss.bit7", FT_BOOLEAN, 32, NULL, 0x00000040, NULL, HFILL }},
738 { &hf_sss_bit8,
739 { "Set Tree Name", "sss.bit8", FT_BOOLEAN, 32, NULL, 0x00000080, NULL, HFILL }},
741 { &hf_sss_bit9,
742 { "Get Context", "sss.bit9", FT_BOOLEAN, 32, NULL, 0x00000100, NULL, HFILL }},
744 { &hf_sss_bit10,
745 { "Destroy Context", "sss.bit10", FT_BOOLEAN, 32, NULL, 0x00000200, NULL, HFILL }},
747 { &hf_sss_bit11,
748 { "Not Defined", "sss.bit11", FT_BOOLEAN, 32, NULL, 0x00000400, NULL, HFILL }},
750 { &hf_sss_bit12,
751 { "Not Defined", "sss.bit12", FT_BOOLEAN, 32, NULL, 0x00000800, NULL, HFILL }},
753 { &hf_sss_bit13,
754 { "Not Defined", "sss.bit13", FT_BOOLEAN, 32, NULL, 0x00001000, NULL, HFILL }},
756 { &hf_sss_bit14,
757 { "Not Defined", "sss.bit14", FT_BOOLEAN, 32, NULL, 0x00002000, NULL, HFILL }},
759 { &hf_sss_bit15,
760 { "Not Defined", "sss.bit15", FT_BOOLEAN, 32, NULL, 0x00004000, NULL, HFILL }},
762 { &hf_sss_bit16,
763 { "Not Defined", "sss.bit16", FT_BOOLEAN, 32, NULL, 0x00008000, NULL, HFILL }},
765 { &hf_sss_bit17,
766 { "EP Lock", "sss.bit17", FT_BOOLEAN, 32, NULL, 0x00010000, NULL, HFILL }},
768 { &hf_sss_bit18,
769 { "Not Initialized", "sss.bit18", FT_BOOLEAN, 32, NULL, 0x00020000, NULL, HFILL }},
771 { &hf_sss_bit19,
772 { "Enhanced Protection", "sss.bit19", FT_BOOLEAN, 32, NULL, 0x00040000, NULL, HFILL }},
774 { &hf_sss_bit20,
775 { "Store Not Synced", "sss.bit20", FT_BOOLEAN, 32, NULL, 0x00080000, NULL, HFILL }},
777 { &hf_sss_bit21,
778 { "Admin Last Modified", "sss.bit21", FT_BOOLEAN, 32, NULL, 0x00100000, NULL, HFILL }},
780 { &hf_sss_bit22,
781 { "EP Password Present", "sss.bit22", FT_BOOLEAN, 32, NULL, 0x00200000, NULL, HFILL }},
783 { &hf_sss_bit23,
784 { "EP Master Password Present", "sss.bit23", FT_BOOLEAN, 32, NULL, 0x00400000, NULL, HFILL }},
786 { &hf_sss_bit24,
787 { "MP Disabled", "sss.bit24", FT_BOOLEAN, 32, NULL, 0x00800000, NULL, HFILL }},
789 { &hf_sss_bit25,
790 { "Not Defined", "sss.bit25", FT_BOOLEAN, 32, NULL, 0x01000000, NULL, HFILL }},
792 { &hf_sss_bit26,
793 { "Not Defined", "sss.bit26", FT_BOOLEAN, 32, NULL, 0x02000000, NULL, HFILL }},
795 { &hf_sss_bit27,
796 { "Not Defined", "sss.bit27", FT_BOOLEAN, 32, NULL, 0x04000000, NULL, HFILL }},
798 { &hf_sss_bit28,
799 { "Not Defined", "sss.bit28", FT_BOOLEAN, 32, NULL, 0x08000000, NULL, HFILL }},
801 { &hf_sss_bit29,
802 { "Not Defined", "sss.bit29", FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL }},
804 { &hf_sss_bit30,
805 { "Not Defined", "sss.bit30", FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL }},
807 { &hf_sss_bit31,
808 { "Not Defined", "sss.bit31", FT_BOOLEAN, 32, NULL, 0x40000000, NULL, HFILL }},
810 { &hf_sss_bit32,
811 { "Not Defined", "sss.bit32", FT_BOOLEAN, 32, NULL, 0x80000000, NULL, HFILL }}
814 static int *ett[] = {
815 &ett_sss
818 static ei_register_info ei[] = {
819 { &ei_return_code, { "sss.return_code.expert", PI_RESPONSE_CODE, PI_NOTE, "SSS Error", EXPFILL }}
822 expert_module_t* expert_sss;
823 /*module_t *sss_module;*/
825 proto_sss = proto_register_protocol("Novell SecretStore Services", "SSS", "sss");
826 proto_register_field_array(proto_sss, hf_sss, array_length(hf_sss));
827 proto_register_subtree_array(ett, array_length(ett));
828 expert_sss = expert_register_protocol(proto_sss);
829 expert_register_field_array(expert_sss, ei, array_length(ei));
833 * Editor modelines - https://www.wireshark.org/tools/modelines.html
835 * Local variables:
836 * c-basic-offset: 4
837 * tab-width: 8
838 * indent-tabs-mode: nil
839 * End:
841 * vi: set shiftwidth=4 tabstop=8 expandtab:
842 * :indentSize=4:tabSize=8:noTabs=true: