964e3b21439bcc52d6220d554fe8dc32495a5828
[obnox/wireshark/wip.git] / epan / dissectors / packet-ncp-sss.c
1 /* packet-ncp-sss.c
2  * Routines for Novell SecretStore Services
3  * Greg Morris <gmorris@novell.com>
4  * Copyright (c) Novell, Inc. 2002-2003
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <string.h>
32 #include <glib.h>
33 #include <epan/packet.h>
34 #include <epan/strutil.h>
35 #include "packet-ncp-int.h"
36 #include "packet-ncp-sss.h"
37
38 static guint32 subverb=0;
39
40 static gint ett_sss = -1;
41
42 static int proto_sss = -1;
43 static int hf_buffer_size = -1;
44 static int hf_ping_version = -1;
45 static int hf_flags = -1;
46 static int hf_context = -1;
47 static int hf_frag_handle = -1;
48 static int hf_length = -1;
49 static int hf_verb = -1;
50 static int hf_user = -1;
51 static int hf_secret = -1;
52 static int hf_sss_version = -1;
53 static int hf_return_code = -1;
54 static int hf_enc_cred = -1;
55 static int hf_enc_data = -1;
56 static int hfbit1 = -1;
57 static int hfbit2 = -1;
58 static int hfbit3 = -1;
59 static int hfbit4 = -1;
60 static int hfbit5 = -1;
61 static int hfbit6 = -1;
62 static int hfbit7 = -1;
63 static int hfbit8 = -1;
64 static int hfbit9 = -1;
65 static int hfbit10 = -1;
66 static int hfbit11 = -1;
67 static int hfbit12 = -1;
68 static int hfbit13 = -1;
69 static int hfbit14 = -1;
70 static int hfbit15 = -1;
71 static int hfbit16 = -1;
72 static int hfbit17 = -1;
73 static int hfbit18 = -1;
74 static int hfbit19 = -1;
75 static int hfbit20 = -1;
76 static int hfbit21 = -1;
77 static int hfbit22 = -1;
78 static int hfbit23 = -1;
79 static int hfbit24 = -1;
80 static int hfbit25 = -1;
81 static int hfbit26 = -1;
82 static int hfbit27 = -1;
83 static int hfbit28 = -1;
84 static int hfbit29 = -1;
85 static int hfbit30 = -1;
86 static int hfbit31 = -1;
87 static int hfbit32 = -1;
88
89 static const value_string sss_func_enum[] = {
90     { 0x00000001, "Ping Server" },
91     { 0x00000002, "Fragment" },
92     { 0x00000003, "Write App Secrets" },
93     { 0x00000004, "Add Secret ID" },
94     { 0x00000005, "Remove Secret ID" },
95     { 0x00000006, "Remove SecretStore" },
96     { 0x00000007, "Enumerate Secret IDs" },
97     { 0x00000008, "Unlock Store" },
98     { 0x00000009, "Set Master Password" },
99     { 0x0000000a, "Get Service Information" },
100     { 0,          NULL }
101 };
102
103
104 static const value_string sss_verb_enum[] = {
105     { 0x00000000, "Query Server" },
106     { 0x00000001, "Read App Secrets" },
107     { 0x00000002, "Write App Secrets" },
108     { 0x00000003, "Add Secret ID" },
109     { 0x00000004, "Remove Secret ID" },
110     { 0x00000005, "Remove SecretStore" },
111     { 0x00000006, "Enumerate Secret IDs" },
112     { 0x00000007, "Unlock Store" },
113     { 0x00000008, "Set Master Password" },
114     { 0x00000009, "Get Service Information" },
115     { 0x000000ff, "Fragment"},
116     { 0,          NULL }
117 };
118
119 static const value_string sss_subverb_enum[] _U_ = {
120     { 0, "Fragmented Ping" },
121     { 2, "Client Put Data" },
122     { 4, "Client Get Data" },
123     { 6, "Client Get User NDS Credentials" },
124     { 8, "Login Store Management" },
125     { 10, "Writable Object Check" },
126     { 1242, "Message Handler" },
127     { 0,          NULL }
128 };
129
130 static const value_string sss_msgverb_enum[] _U_ = {
131     { 1, "Echo Data" },
132     { 3, "Start Session" },
133     { 5, "Client Write Data" },
134     { 7, "Client Read Data" },
135     { 9, "End Session" },
136     { 0,          NULL }
137 };
138
139 static const value_string sss_attribute_enum[] _U_ = {
140     { 1, "User Name" },
141     { 2, "Tree Name" },
142     { 4, "Clearance" },
143     { 11, "Login Sequence" },
144     { 0,          NULL }
145 };
146
147 static const value_string sss_lsmverb_enum[] _U_ = {
148     { 1, "Put Login Configuration" },
149     { 2, "Get Login Configuration" },
150     { 4, "Delete Login Configuration" },
151     { 5, "Put Login Secret" },
152     { 6, "Delete Login Secret" },
153     { 0,          NULL }
154 };
155
156 static const value_string sss_errors_enum[] = {
157     { 0xFFFFFCE0, "(-800) Target object could not be found" },
158     { 0xFFFFFCDF, "(-801) NICI operations have failed" },
159     { 0xFFFFFCDE, "(-802) The Secret ID is not in the user secret store" },
160     { 0xFFFFFCDD, "(-803) Some internal operating system services have not been available" },
161     { 0xFFFFFCDC, "(-804) Access to the target Secret Store has been denied" },
162     { 0xFFFFFCDB, "(-805) NDS internal NDS services have not been available" },
163     { 0xFFFFFCDA, "(-806) Secret has not been initialized with a write" },
164     { 0xFFFFFCD9, "(-807) Size of the buffer is not in a nominal range between minimum and maximum" },
165     { 0xFFFFFCD8, "(-808) Client and server components are not of the compatible versions" },
166     { 0xFFFFFCD7, "(-809) Secret Store data on the server has been corrupted" },
167     { 0xFFFFFCD6, "(-810) Secret ID already exists in the SecretStore" },
168     { 0xFFFFFCD5, "(-811) User NDS password has been changed by the administrator" },
169     { 0xFFFFFCD4, "(-812) Target NDS user object not found" },
170     { 0xFFFFFCD3, "(-813) Target NDS user object does not have a Secret Store" },
171     { 0xFFFFFCD2, "(-814) Secret Store is not on the network" },
172     { 0xFFFFFCD1, "(-815) Length of the Secret ID buffer exceeds the limit" },
173     { 0xFFFFFCD0, "(-816) Length of the enumeration buffer is too short" },
174     { 0xFFFFFCCF, "(-817) User not authenticated" },
175     { 0xFFFFFCCE, "(-818) Not supported operations" },
176     { 0xFFFFFCCD, "(-819) Typed in NDS password not valid" },
177     { 0xFFFFFCCC, "(-820) Session keys of the client and server NICI are out of sync" },
178     { 0xFFFFFCCB, "(-821) Requested service not yet supported" },
179     { 0xFFFFFCCA, "(-822) NDS authentication type not supported" },
180     { 0xFFFFFCC9, "(-823) Unicode text conversion operation failed" },
181     { 0xFFFFFCC8, "(-824) Connection to server is lost" },
182     { 0xFFFFFCC7, "(-825) Cryptographic operation failed" },
183     { 0xFFFFFCC6, "(-826) Opening a connection to the server failed" },
184     { 0xFFFFFCC5, "(-827) Access to server connection failed" },
185     { 0xFFFFFCC4, "(-828) Size of the enumeration buffer exceeds the limit" },
186     { 0xFFFFFCC3, "(-829) Size of the Secret buffer exceeds the limit" },
187     { 0xFFFFFCC2, "(-830) Length of the Secret ID should be greater than zero" },
188     { 0xFFFFFCC1, "(-831) Protocol data corrupted on the wire" },
189     { 0xFFFFFCC0, "(-832) Enhanced protection's password validation failed. Access to the secret denied" },
190     { 0xFFFFFCBF, "(-833) Schema is not extended to support SecretStore on the target tree" },
191     { 0xFFFFFCBE, "(-834) One of the optional service attributes is not instantiated" },
192     { 0xFFFFFCBD, "(-835) Server has been upgraded and the users SecretStore should be updated" },
193     { 0xFFFFFCBC, "(-836) Master password could not be verified to read or unlock the secrets" },
194     { 0xFFFFFCBB, "(-837) Master password has not been set on the SecretStore" },
195     { 0xFFFFFCBA, "(-838) Ability to use master password has been disabled" },
196     { 0xFFFFFCB9, "(-839) Not a writeable replica of NDS" },
197     { 0xFFFFFCB8, "(-840) The API was unable to find a value for an attribute in the Directory" },
198     { 0xFFFFFCB7, "(-841) A parameter passed to the API has not been properly initialized" },
199     { 0xFFFFFCB6, "(-842) The connection to SecretStore requires SSL to be secure" },
200     { 0xFFFFFCB5, "(-843) The client could not locate a server that supports the policy override required by the caller" },
201     { 0xFFFFFCB4, "(-844) Attempt to unlock SecretStore failed because the store is not locked" },
202     { 0xFFFFFCB3, "(-845) NDS Replica on the server that holds SecretStore is out of sync with the replica ring" },
203     { 0xFFFFFC88, "(-888) Feature not yet implemented" },
204     { 0xFFFFFC7D, "(-899) Products BETA life has expired" },
205     { 0,          NULL }
206 };
207
208
209 static void
210 process_flags(proto_tree *sss_tree, tvbuff_t *tvb, guint32 foffset)
211 {
212     gchar                   flags_str[1024];
213     gchar                   *sep;
214     proto_item                  *tinew;
215     proto_tree                  *flags_tree;
216     guint32                 i;
217     guint32                 bvalue = 0;
218     guint32                 flags = 0;
219
220     bvalue = 0x00000001;
221     flags_str[0]='\0';
222     sep="";
223     flags = tvb_get_ntohl(tvb, foffset);
224     for (i = 0 ; i < 256; i++)
225     {
226         if (flags & bvalue)
227         {
228             g_strlcat(flags_str, sep, 1024);
229             switch(bvalue)
230             {
231                 case 0x00000001:
232                         g_strlcat(flags_str, "Enhanced Protection", 1024);
233                         break;
234                 case 0x00000002:
235                         g_strlcat(flags_str, "Create ID", 1024);
236                         break;
237                 case 0x00000004:
238                         g_strlcat(flags_str, "Remove Lock", 1024);
239                         break;
240                 case 0x00000008:
241                         g_strlcat(flags_str, "Repair", 1024);
242                         break;
243                 case 0x00000010:
244                         g_strlcat(flags_str, "Unicode", 1024);
245                         break;
246                 case 0x00000020:
247                         g_strlcat(flags_str, "EP Master Password Used", 1024);
248                         break;
249                 case 0x00000040:
250                         g_strlcat(flags_str, "EP Password Used", 1024);
251                         break;
252                 case 0x00000080:
253                         g_strlcat(flags_str, "Set Tree Name", 1024);
254                         break;
255                 case 0x00000100:
256                         g_strlcat(flags_str, "Get Context", 1024);
257                         break;
258                 case 0x00000200:
259                         g_strlcat(flags_str, "Destroy Context", 1024);
260                         break;
261                 case 0x00000400:
262                         g_strlcat(flags_str, "Not Defined", 1024);
263                         break;
264                 case 0x00000800:
265                         g_strlcat(flags_str, "Not Defined", 1024);
266                         break;
267                 case 0x00001000:
268                         g_strlcat(flags_str, "EP Lock", 1024);
269                         break;
270                 case 0x00002000:
271                         g_strlcat(flags_str, "Not Initialized", 1024);
272                         break;
273                 case 0x00004000:
274                         g_strlcat(flags_str, "Enhanced Protection", 1024);
275                         break;
276                 case 0x00008000:
277                         g_strlcat(flags_str, "Store Not Synced", 1024);
278                         break;
279                 case 0x00010000:
280                         g_strlcat(flags_str, "Admin Last Modified", 1024);
281                         break;
282                 case 0x00020000:
283                         g_strlcat(flags_str, "EP Password Present", 1024);
284                         break;
285                 case 0x00040000:
286                         g_strlcat(flags_str, "EP Master Password Present", 1024);
287                         break;
288                 case 0x00080000:
289                         g_strlcat(flags_str, "MP Disabled", 1024);
290                         break;
291                 case 0x00100000:
292                         g_strlcat(flags_str, "Not Defined", 1024);
293                         break;
294                 case 0x00200000:
295                         g_strlcat(flags_str, "Not Defined", 1024);
296                         break;
297                 case 0x00400000:
298                         g_strlcat(flags_str, "Not Defined", 1024);
299                         break;
300                 case 0x00800000:
301                         g_strlcat(flags_str, "Not Defined", 1024);
302                         break;
303                 case 0x01000000:
304                         g_strlcat(flags_str, "Not Defined", 1024);
305                         break;
306                 case 0x02000000:
307                         g_strlcat(flags_str, "Not Defined", 1024);
308                         break;
309                 case 0x04000000:
310                         g_strlcat(flags_str, "Not Defined", 1024);
311                         break;
312                 case 0x08000000:
313                         g_strlcat(flags_str, "Not Defined", 1024);
314                         break;
315                 case 0x10000000:
316                         g_strlcat(flags_str, "Not Defined", 1024);
317                         break;
318                 case 0x20000000:
319                         g_strlcat(flags_str, "Not Defined", 1024);
320                         break;
321                 case 0x40000000:
322                         g_strlcat(flags_str, "Not Defined", 1024);
323                         break;
324                 case 0x80000000:
325                         g_strlcat(flags_str, "Not Defined", 1024);
326                         break;
327                 default:
328                         break;
329             }
330             sep = ", ";
331         }
332             bvalue = bvalue*2;
333     }
334
335     tinew = proto_tree_add_uint_format(sss_tree, hf_flags, tvb, foffset, 4, flags, "%s 0x%08x", "Flags:", flags);
336         flags_tree = proto_item_add_subtree(tinew, ett_nds);
337
338     bvalue = 0x00000001;
339
340     for (i = 0 ; i < 256; i++ )
341     {
342         if (flags & bvalue)
343         {
344             switch(bvalue)
345             {
346                 case 0x00000001:
347                         proto_tree_add_item(flags_tree, hfbit1, tvb, foffset, 4, FALSE);
348                         break;
349                 case 0x00000002:
350                     proto_tree_add_item(flags_tree, hfbit2, tvb, foffset, 4, FALSE);
351                         break;
352                 case 0x00000004:
353                     proto_tree_add_item(flags_tree, hfbit3, tvb, foffset, 4, FALSE);
354                         break;
355                 case 0x00000008:
356                         proto_tree_add_item(flags_tree, hfbit4, tvb, foffset, 4, FALSE);
357                         break;
358                 case 0x00000010:
359                         proto_tree_add_item(flags_tree, hfbit5, tvb, foffset, 4, FALSE);
360                         break;
361                 case 0x00000020:
362                         proto_tree_add_item(flags_tree, hfbit6, tvb, foffset, 4, FALSE);
363                         break;
364                 case 0x00000040:
365                         proto_tree_add_item(flags_tree, hfbit7, tvb, foffset, 4, FALSE);
366                         break;
367                 case 0x00000080:
368                         proto_tree_add_item(flags_tree, hfbit8, tvb, foffset, 4, FALSE);
369                         break;
370                 case 0x00000100:
371                         proto_tree_add_item(flags_tree, hfbit9, tvb, foffset, 4, FALSE);
372                         break;
373                 case 0x00000200:
374                         proto_tree_add_item(flags_tree, hfbit10, tvb, foffset, 4, FALSE);
375                         break;
376                 case 0x00000400:
377                         proto_tree_add_item(flags_tree, hfbit11, tvb, foffset, 4, FALSE);
378                         break;
379                 case 0x00000800:
380                         proto_tree_add_item(flags_tree, hfbit12, tvb, foffset, 4, FALSE);
381                         break;
382                 case 0x00001000:
383                         proto_tree_add_item(flags_tree, hfbit13, tvb, foffset, 4, FALSE);
384                         break;
385                 case 0x00002000:
386                         proto_tree_add_item(flags_tree, hfbit14, tvb, foffset, 4, FALSE);
387                         break;
388                 case 0x00004000:
389                         proto_tree_add_item(flags_tree, hfbit15, tvb, foffset, 4, FALSE);
390                         break;
391                 case 0x00008000:
392                         proto_tree_add_item(flags_tree, hfbit16, tvb, foffset, 4, FALSE);
393                         break;
394                 case 0x00010000:
395                         proto_tree_add_item(flags_tree, hfbit17, tvb, foffset, 4, FALSE);
396                         break;
397                 case 0x00020000:
398                         proto_tree_add_item(flags_tree, hfbit18, tvb, foffset, 4, FALSE);
399                         break;
400                 case 0x00040000:
401                         proto_tree_add_item(flags_tree, hfbit19, tvb, foffset, 4, FALSE);
402                         break;
403                 case 0x00080000:
404                         proto_tree_add_item(flags_tree, hfbit20, tvb, foffset, 4, FALSE);
405                         break;
406                 case 0x00100000:
407                         proto_tree_add_item(flags_tree, hfbit21, tvb, foffset, 4, FALSE);
408                         break;
409                 case 0x00200000:
410                         proto_tree_add_item(flags_tree, hfbit22, tvb, foffset, 4, FALSE);
411                         break;
412                 case 0x00400000:
413                         proto_tree_add_item(flags_tree, hfbit23, tvb, foffset, 4, FALSE);
414                         break;
415                 case 0x00800000:
416                         proto_tree_add_item(flags_tree, hfbit24, tvb, foffset, 4, FALSE);
417                         break;
418                 case 0x01000000:
419                         proto_tree_add_item(flags_tree, hfbit25, tvb, foffset, 4, FALSE);
420                         break;
421                 case 0x02000000:
422                         proto_tree_add_item(flags_tree, hfbit26, tvb, foffset, 4, FALSE);
423                         break;
424                 case 0x04000000:
425                         proto_tree_add_item(flags_tree, hfbit27, tvb, foffset, 4, FALSE);
426                         break;
427                 case 0x08000000:
428                         proto_tree_add_item(flags_tree, hfbit28, tvb, foffset, 4, FALSE);
429                         break;
430                 case 0x10000000:
431                         proto_tree_add_item(flags_tree, hfbit29, tvb, foffset, 4, FALSE);
432                         break;
433                 case 0x20000000:
434                         proto_tree_add_item(flags_tree, hfbit30, tvb, foffset, 4, FALSE);
435                         break;
436                 case 0x40000000:
437                         proto_tree_add_item(flags_tree, hfbit31, tvb, foffset, 4, FALSE);
438                         break;
439                 case 0x80000000:
440                         proto_tree_add_item(flags_tree, hfbit32, tvb, foffset, 4, FALSE);
441                         break;
442                 default:
443                         break;
444             }
445         }
446         bvalue = bvalue*2;
447     }
448     return;
449 }
450
451 static int
452 find_delimiter(tvbuff_t *tvb, int foffset)
453 {
454     int i;
455     int length = 0;
456     guint16 c_char;
457
458     for (i=0; i < 256; i++)
459     {
460         c_char = tvb_get_guint8(tvb, foffset);
461         if (c_char == 0x2a || tvb_length_remaining(tvb, foffset)==0)
462         {
463             break;
464         }
465         foffset++;
466         length++;
467     }
468     return length;
469 }
470
471 static int
472 sss_string(tvbuff_t* tvb, int hfinfo, proto_tree *sss_tree, int offset, gboolean little, guint32 length)
473 {
474         int     foffset = offset;
475         guint32 str_length;
476         char    buffer[1024];
477         guint32 i;
478         guint16 c_char;
479         guint32 length_remaining = 0;
480
481         if (length==0)
482         {
483             if (little) {
484                 str_length = tvb_get_letohl(tvb, foffset);
485             }
486             else
487             {
488                 str_length = tvb_get_ntohl(tvb, foffset);
489             }
490             foffset += 4;
491         }
492         else
493         {
494             str_length = length;
495         }
496         length_remaining = tvb_length_remaining(tvb, foffset);
497         if(str_length > (guint)length_remaining || str_length > 1024)
498         {
499                 proto_tree_add_string(sss_tree, hfinfo, tvb, foffset,
500                     length_remaining + 4, "<String too long to process>");
501                 foffset += length_remaining;
502                 return foffset;
503         }
504         if(str_length == 0)
505         {
506             proto_tree_add_string(sss_tree, hfinfo, tvb, offset,
507                 4, "<Not Specified>");
508             return foffset;
509         }
510         for ( i = 0; i < str_length; i++ )
511         {
512                 c_char = tvb_get_guint8(tvb, foffset );
513                 if (c_char<0x20 || c_char>0x7e)
514                 {
515                         if (c_char != 0x00)
516                         {
517                                 c_char = 0x2e;
518                                 buffer[i] = c_char & 0xff;
519                         }
520                         else
521                         {
522                                 i--;
523                                 str_length--;
524                         }
525                 }
526                 else
527                 {
528                         buffer[i] = c_char & 0xff;
529                 }
530                 foffset++;
531                 length_remaining--;
532
533                 if(length_remaining==1)
534                 {
535                         i++;
536                         break;
537                 }
538         }
539         buffer[i] = '\0';
540
541         if (length==0)
542         {
543             if (little) {
544                 str_length = tvb_get_letohl(tvb, offset);
545             }
546             else
547             {
548                 str_length = tvb_get_ntohl(tvb, offset);
549             }
550             offset += 4;
551         }
552         else
553         {
554             str_length = length;
555         }
556         proto_tree_add_string(sss_tree, hfinfo, tvb, offset,
557                 str_length, buffer);
558         return foffset;
559 }
560
561 void
562 dissect_sss_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, ncp_req_hash_value *request_value)
563 {
564         guint8                      func, subfunc = 0;
565     guint32             msg_length=0;
566     guint32             foffset= 0;
567     proto_tree          *atree;
568     proto_item          *aitem;
569
570
571     if (tvb_length_remaining(tvb, foffset)<4) {
572         return;
573     }
574     foffset = 6;
575     func = tvb_get_guint8(tvb, foffset);
576     foffset += 1;
577     subfunc = tvb_get_guint8(tvb, foffset);
578     foffset += 1;
579
580     /* Fill in the PROTOCOL & INFO  columns. */
581     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
582        col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS");
583     }
584     if (check_col(pinfo->cinfo, COL_INFO)) {
585        col_add_fstr(pinfo->cinfo, COL_INFO, "C SecretStore - %s", val_to_str(subfunc, sss_func_enum, "Unknown (%d)"));
586     }
587     switch (subfunc) {
588     case 1:
589         aitem = proto_tree_add_text(ncp_tree, tvb, foffset, tvb_length_remaining(tvb, foffset), "Packet Type: %s", val_to_str(subfunc, sss_func_enum, "Unknown (%d)"));
590         atree = proto_item_add_subtree(aitem, ett_sss);
591         proto_tree_add_item(atree, hf_ping_version, tvb, foffset, 4, TRUE);
592         foffset += 4;
593         proto_tree_add_item(atree, hf_flags, tvb, foffset, 4, TRUE);
594         foffset += 4;
595         break;
596     case 2:
597         proto_tree_add_item(ncp_tree, hf_frag_handle, tvb, foffset, 4, TRUE);
598         if (tvb_get_letohl(tvb, foffset)==0xffffffff) /* Fragment handle of -1 means no fragment. So process packet */
599         {
600             foffset += 4;
601             proto_tree_add_item(ncp_tree, hf_buffer_size, tvb, foffset, 4, TRUE);
602             foffset += 4;
603             proto_tree_add_item(ncp_tree, hf_length, tvb, foffset, 4, TRUE);
604             foffset += 4;
605             foffset += 12; /* Blank Context */
606             subverb = tvb_get_letohl(tvb, foffset);
607             if (check_col(pinfo->cinfo, COL_INFO)) {
608                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str(subverb, sss_verb_enum, "Unknown (%d)"));
609             }
610             aitem = proto_tree_add_item(ncp_tree, hf_verb, tvb, foffset, 4, TRUE);
611             atree = proto_item_add_subtree(aitem, ett_sss);
612             if (request_value) {
613                 request_value->req_nds_flags=subverb;
614             }
615             foffset += 4;
616             process_flags(atree, tvb, foffset);
617             foffset += 4;
618             proto_tree_add_item(atree, hf_context, tvb, foffset, 4, FALSE);
619             foffset += 4;
620             switch (subverb) {
621             case 0:
622                 foffset += 4;
623                 foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
624                 break;
625             case 1:
626                 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
627                 msg_length = tvb_get_letohl(tvb, foffset);
628                 foffset += (msg_length+4);   /* Unsure of what this length and parameter are */
629                 /* A bad secret of length greater then 256 characters will cause frag
630                    packets and then we will see these as malformed packets.
631                    So check to make sure we still have data in the packet anytime
632                    we read a secret. */
633                 if (tvb_length_remaining(tvb, foffset) > 4)
634                 {
635                     foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
636                 }
637                 break;
638             case 2:
639                 foffset += 4;
640                 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
641                 if (tvb_length_remaining(tvb, foffset) > 4)
642                 {
643                     msg_length = tvb_get_letohl(tvb, foffset);
644                     foffset += 4;
645                     if (tvb_length_remaining(tvb, foffset) < (gint) msg_length)
646                     {
647                         proto_tree_add_item(atree, hf_enc_data, tvb, foffset, -1, TRUE);
648                     }
649                     else
650                     {
651                         proto_tree_add_item(atree, hf_enc_data, tvb, foffset, msg_length, TRUE);
652                     }
653                 }
654                 break;
655             case 3:
656             case 4:
657                 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
658                 if (tvb_length_remaining(tvb, foffset) > 4)
659                 {
660                     foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
661                 }
662                 break;
663             case 5:
664                 break;
665             case 6:
666                 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
667                 if (tvb_length_remaining(tvb, foffset) > 4)
668                 {
669                     foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
670                 }
671                 break;
672             case 7:
673                 msg_length = tvb_get_letohl(tvb, foffset);
674                 foffset += 4;
675                 proto_tree_add_item(atree, hf_enc_cred, tvb, foffset, msg_length, FALSE);
676                 break;
677             case 8:
678             case 9:
679             default:
680                 break;
681             }
682
683         }
684         else
685         {
686             if (check_col(pinfo->cinfo, COL_INFO)) {
687                col_set_str(pinfo->cinfo, COL_INFO, "C SecretStore - fragment");
688                proto_tree_add_text(ncp_tree, tvb, foffset, 4, "Fragment");
689             }
690             /* Fragments don't really carry a subverb so store 0xff as the subverb number */
691             if (request_value) {
692                 request_value->req_nds_flags=255;
693             }
694             if (tvb_length_remaining(tvb, foffset) > 8)
695             {
696                 foffset += 4;
697                 proto_tree_add_item(ncp_tree, hf_enc_data, tvb, foffset, tvb_length_remaining(tvb, foffset), TRUE);
698             }
699         }
700         break;
701     case 3:
702         /* No Op */
703         break;
704     default:
705         break;
706     }
707 }
708
709 void
710 dissect_sss_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, guint8 subfunc, ncp_req_hash_value   *request_value)
711 {
712     guint32             foffset=0;
713     guint32             subverb=0;
714     guint8              msgverb=0;
715     guint32             msg_length=0;
716     guint32             return_code=0;
717     guint32             number_of_items=0;
718     gint32              length_of_string=0;
719     guint32             i = 0;
720
721     proto_tree          *atree;
722     proto_item          *aitem;
723     proto_item          *expert_item;
724
725
726     foffset = 8;
727     if (request_value) {
728         subverb = request_value->req_nds_flags;
729         msgverb = request_value->nds_request_verb;
730     }
731     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
732        col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS");
733     }
734     if (tvb_length_remaining(tvb, foffset)<4) {
735         return;
736     }
737     aitem = proto_tree_add_text(ncp_tree, tvb, foffset, tvb_length_remaining(tvb, foffset), "Function: %s", val_to_str(subfunc, sss_func_enum, "val_to_str"));
738     atree = proto_item_add_subtree(aitem, ett_sss);
739     switch (subfunc) {
740     case 1:
741         proto_tree_add_item(atree, hf_flags, tvb, foffset, 4, TRUE);
742         foffset += 4;
743         proto_tree_add_item(atree, hf_sss_version, tvb, foffset, 4, TRUE);
744         foffset += 4;
745         break;
746     case 2:
747         if (match_strval(subverb, sss_verb_enum)) {
748             proto_tree_add_text(atree, tvb, foffset, tvb_length_remaining(tvb, foffset), "Verb: %s", match_strval(subverb, sss_verb_enum));
749         }
750         proto_tree_add_item(atree, hf_length, tvb, foffset, 4, TRUE);
751         msg_length = tvb_get_letohl(tvb, foffset);
752         return_code = tvb_get_ntohl(tvb, foffset+msg_length);
753         foffset += 4;
754         proto_tree_add_item(atree, hf_frag_handle, tvb, foffset, 4, TRUE);
755         foffset += 4;
756         msg_length -= 4;
757         if ((tvb_get_letohl(tvb, foffset-4)==0xffffffff) && (msg_length > 4))
758         {
759             foffset += 4;
760             return_code = tvb_get_letohl(tvb, foffset);
761             if ( match_strval(return_code, sss_errors_enum) != NULL )
762             {
763                 expert_item = proto_tree_add_item(atree, hf_return_code, tvb, foffset, 4, TRUE);
764                 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "SSS Error: %s", match_strval(return_code, sss_errors_enum));
765                 if (check_col(pinfo->cinfo, COL_INFO)) {
766                    col_add_fstr(pinfo->cinfo, COL_INFO, "R Error - %s", val_to_str(return_code, sss_errors_enum, "Unknown (%d)"));
767                 }
768                 foffset+=4;
769             }
770             else
771             {
772                 proto_tree_add_text(atree, tvb, foffset, 4, "Return Code: Success (0x00000000)");
773                 if (tvb_length_remaining(tvb, foffset) > 8) {
774                     foffset += 4;
775                     if (subverb == 6)
776                     {
777                         foffset += 4;
778                         number_of_items = tvb_get_letohl(tvb, foffset);
779                         foffset += 8;
780                         for (i=0; i<number_of_items; i++)
781                         {
782                             length_of_string = find_delimiter(tvb, foffset);
783                             if (length_of_string > tvb_length_remaining(tvb, foffset))
784                             {
785                                 return;
786                             }
787                             foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, length_of_string);
788                             if (tvb_length_remaining(tvb, foffset) < 8)
789                             {
790                                 return;
791                             }
792                             foffset++;
793                         }
794
795                     }
796                     else
797                     {
798                         proto_tree_add_item(atree, hf_enc_data, tvb, foffset, tvb_length_remaining(tvb, foffset), TRUE);
799                     }
800                 }
801             }
802         }
803         else
804         {
805             proto_tree_add_text(atree, tvb, foffset, 4, "Return Code: Success (0x00000000)");
806             if (tvb_length_remaining(tvb, foffset) > 8) {
807                 foffset += 4;
808                 proto_tree_add_item(atree, hf_enc_data, tvb, foffset, tvb_length_remaining(tvb, foffset), TRUE);
809             }
810         }
811         break;
812     case 3:
813         break;
814     default:
815         break;
816     }
817 }
818
819 void
820 proto_register_sss(void)
821 {
822         static hf_register_info hf_sss[] = {
823                 { &hf_buffer_size,
824                 { "Buffer Size",                "sss.buffer", FT_UINT32, BASE_DEC, NULL, 0x0,
825                         NULL, HFILL }},
826
827                 { &hf_ping_version,
828                 { "Ping Version",               "sss.ping_version", FT_UINT32, BASE_HEX, NULL, 0x0,
829                         NULL, HFILL }},
830
831                 { &hf_flags,
832                 { "Flags",              "sss.flags", FT_UINT32, BASE_HEX, NULL, 0x0,
833                         NULL, HFILL }},
834
835                 { &hf_context,
836                 { "Context",            "sss.context", FT_UINT32, BASE_HEX, NULL, 0x0,
837                         NULL, HFILL }},
838
839                 { &hf_frag_handle,
840                 { "Fragment Handle",            "sss.frag_handle", FT_UINT32, BASE_HEX, NULL, 0x0,
841                         NULL, HFILL }},
842
843                 { &hf_length,
844                 { "Length",             "sss.length", FT_UINT32, BASE_DEC, NULL, 0x0,
845                         NULL, HFILL }},
846
847         { &hf_verb,
848         { "Verb",    "sss.verb",
849           FT_UINT32,    BASE_HEX,   VALS(sss_verb_enum),   0x0,
850           NULL, HFILL }},
851
852         { &hf_user,
853         { "User",    "sss.user",
854           FT_STRING,    BASE_NONE,   NULL,   0x0,
855           NULL, HFILL }},
856
857         { &hf_secret,
858         { "Secret ID",    "sss.secret",
859           FT_STRING,    BASE_NONE,   NULL,   0x0,
860           NULL, HFILL }},
861
862                 { &hf_sss_version,
863                 { "SecretStore Protocol Version",               "sss.version", FT_UINT32, BASE_HEX, NULL, 0x0,
864                         NULL, HFILL }},
865
866         { &hf_return_code,
867                 { "Return Code",                "sss.return_code", FT_UINT32, BASE_HEX, VALS(sss_errors_enum), 0x0,
868                         NULL, HFILL }},
869
870         { &hf_enc_cred,
871         { "Encrypted Credential",    "sss.enc_cred",
872           FT_BYTES,    BASE_NONE,   NULL,   0x0,
873           NULL, HFILL }},
874
875         { &hf_enc_data,
876         { "Encrypted Data",    "sss.enc_data",
877           FT_BYTES,    BASE_NONE,   NULL,   0x0,
878           NULL, HFILL }},
879
880         { &hfbit1,
881         { "Enhanced Protection", "ncp.sss_bit1", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL }},
882
883         { &hfbit2,
884         { "Create ID", "ncp.sss_bit2", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL }},
885
886         { &hfbit3,
887         { "Remove Lock", "ncp.sss_bit3", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL }},
888
889         { &hfbit4,
890         { "Repair", "ncp.sss_bit4", FT_BOOLEAN, 32, NULL, 0x00000008, NULL, HFILL }},
891
892         { &hfbit5,
893         { "Unicode", "ncp.sss_bit5", FT_BOOLEAN, 32, NULL, 0x00000010, NULL, HFILL }},
894
895         { &hfbit6,
896         { "EP Master Password Used", "ncp.sss_bit6", FT_BOOLEAN, 32, NULL, 0x00000020, NULL, HFILL }},
897
898         { &hfbit7,
899         { "EP Password Used", "ncp.sss_bit7", FT_BOOLEAN, 32, NULL, 0x00000040, NULL, HFILL }},
900
901         { &hfbit8,
902         { "Set Tree Name", "ncp.sss_bit8", FT_BOOLEAN, 32, NULL, 0x00000080, NULL, HFILL }},
903
904         { &hfbit9,
905         { "Get Context", "ncp.sss_bit9", FT_BOOLEAN, 32, NULL, 0x00000100, NULL, HFILL }},
906
907         { &hfbit10,
908         { "Destroy Context", "ncp.sss_bit10", FT_BOOLEAN, 32, NULL, 0x00000200, NULL, HFILL }},
909
910         { &hfbit11,
911         { "Not Defined", "ncp.sss_bit11", FT_BOOLEAN, 32, NULL, 0x00000400, NULL, HFILL }},
912
913         { &hfbit12,
914         { "Not Defined", "ncp.sss_bit12", FT_BOOLEAN, 32, NULL, 0x00000800, NULL, HFILL }},
915
916         { &hfbit13,
917         { "Not Defined", "ncp.sss_bit13", FT_BOOLEAN, 32, NULL, 0x00001000, NULL, HFILL }},
918
919         { &hfbit14,
920         { "Not Defined", "ncp.sss_bit14", FT_BOOLEAN, 32, NULL, 0x00002000, NULL, HFILL }},
921
922         { &hfbit15,
923         { "Not Defined", "ncp.sss_bit15", FT_BOOLEAN, 32, NULL, 0x00004000, NULL, HFILL }},
924
925         { &hfbit16,
926         { "Not Defined", "ncp.sss_bit16", FT_BOOLEAN, 32, NULL, 0x00008000, NULL, HFILL }},
927
928         { &hfbit17,
929         { "EP Lock", "ncp.sss_bit17", FT_BOOLEAN, 32, NULL, 0x00010000, NULL, HFILL }},
930
931         { &hfbit18,
932         { "Not Initialized", "ncp.sss_bit18", FT_BOOLEAN, 32, NULL, 0x00020000, NULL, HFILL }},
933
934         { &hfbit19,
935         { "Enhanced Protection", "ncp.sss_bit19", FT_BOOLEAN, 32, NULL, 0x00040000, NULL, HFILL }},
936
937         { &hfbit20,
938         { "Store Not Synced", "ncp.sss_bit20", FT_BOOLEAN, 32, NULL, 0x00080000, NULL, HFILL }},
939
940         { &hfbit21,
941         { "Admin Last Modified", "ncp.sss_bit21", FT_BOOLEAN, 32, NULL, 0x00100000, NULL, HFILL }},
942
943         { &hfbit22,
944         { "EP Password Present", "ncp.sss_bit22", FT_BOOLEAN, 32, NULL, 0x00200000, NULL, HFILL }},
945
946         { &hfbit23,
947         { "EP Master Password Present", "ncp.sss_bit23", FT_BOOLEAN, 32, NULL, 0x00400000, NULL, HFILL }},
948
949         { &hfbit24,
950         { "MP Disabled", "ncp.sss_bit24", FT_BOOLEAN, 32, NULL, 0x00800000, NULL, HFILL }},
951
952         { &hfbit25,
953         { "Not Defined", "ncp.sss_bit25", FT_BOOLEAN, 32, NULL, 0x01000000, NULL, HFILL }},
954
955         { &hfbit26,
956         { "Not Defined", "ncp.sss_bit26", FT_BOOLEAN, 32, NULL, 0x02000000, NULL, HFILL }},
957
958         { &hfbit27,
959         { "Not Defined", "ncp.sss_bit27", FT_BOOLEAN, 32, NULL, 0x04000000, NULL, HFILL }},
960
961         { &hfbit28,
962         { "Not Defined", "ncp.sss_bit28", FT_BOOLEAN, 32, NULL, 0x08000000, NULL, HFILL }},
963
964         { &hfbit29,
965         { "Not Defined", "ncp.sss_bit29", FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL }},
966
967         { &hfbit30,
968         { "Not Defined", "ncp.sss_bit30", FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL }},
969
970         { &hfbit31,
971         { "Not Defined", "ncp.sss_bit31", FT_BOOLEAN, 32, NULL, 0x40000000, NULL, HFILL }},
972
973         { &hfbit32,
974         { "Not Defined", "ncp.sss_bit32", FT_BOOLEAN, 32, NULL, 0x80000000, NULL, HFILL }},
975
976     };
977
978         static gint *ett[] = {
979                 &ett_sss,
980         };
981         /*module_t *sss_module;*/
982
983         proto_sss = proto_register_protocol("Novell SecretStore Services", "SSS", "sss");
984         proto_register_field_array(proto_sss, hf_sss, array_length(hf_sss));
985         proto_register_subtree_array(ett, array_length(ett));
986 }