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 * Wireshark - Network traffic analyzer 7 * By Gerald Combs <gerald@wireshark.org> 8 * Copyright 1998 Gerald Combs 9 * 10 * SPDX-License-Identifier: GPL-2.0-or-later 11 */ 12 13 #include "config.h" 14 15 #include <epan/packet.h> 16 #include "packet-ncp-int.h" 17 #include "packet-ncp-sss.h" 18 19 void proto_register_sss(void); 20 21 static gint ett_sss = -1; 22 23 static int proto_sss = -1; 24 static int hf_buffer_size = -1; 25 static int hf_ping_version = -1; 26 static int hf_flags = -1; 27 static int hf_context = -1; 28 static int hf_frag_handle = -1; 29 static int hf_length = -1; 30 static int hf_verb = -1; 31 static int hf_user = -1; 32 static int hf_secret = -1; 33 static int hf_sss_version = -1; 34 static int hf_return_code = -1; 35 static int hf_enc_cred = -1; 36 static int hf_enc_data = -1; 37 static int hfbit1 = -1; 38 static int hfbit2 = -1; 39 static int hfbit3 = -1; 40 static int hfbit4 = -1; 41 static int hfbit5 = -1; 42 static int hfbit6 = -1; 43 static int hfbit7 = -1; 44 static int hfbit8 = -1; 45 static int hfbit9 = -1; 46 static int hfbit10 = -1; 47 static int hfbit11 = -1; 48 static int hfbit12 = -1; 49 static int hfbit13 = -1; 50 static int hfbit14 = -1; 51 static int hfbit15 = -1; 52 static int hfbit16 = -1; 53 static int hfbit17 = -1; 54 static int hfbit18 = -1; 55 static int hfbit19 = -1; 56 static int hfbit20 = -1; 57 static int hfbit21 = -1; 58 static int hfbit22 = -1; 59 static int hfbit23 = -1; 60 static int hfbit24 = -1; 61 static int hfbit25 = -1; 62 static int hfbit26 = -1; 63 static int hfbit27 = -1; 64 static int hfbit28 = -1; 65 static int hfbit29 = -1; 66 static int hfbit30 = -1; 67 static int hfbit31 = -1; 68 static int hfbit32 = -1; 69 70 static expert_field ei_return_code = EI_INIT; 71 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 } 84 }; 85 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 } 136 }; 137 138 139 static void 140 process_flags(proto_tree *sss_tree, tvbuff_t *tvb, guint32 foffset) 141 { 142 gchar flags_str[1024]; 143 const gchar *sep; 144 proto_item *tinew; 145 proto_tree *flags_tree; 146 guint32 i; 147 guint32 bvalue = 0; 148 guint32 flags = 0; 149 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; 256 } 257 sep = ", "; 258 } 259 bvalue = bvalue*2; 260 } 261 262 tinew = proto_tree_add_uint(sss_tree, hf_flags, tvb, foffset, 4, flags); 263 flags_tree = proto_item_add_subtree(tinew, ett_nds); 264 265 bvalue = 0x00000001; 266 267 for (i = 0 ; i < 256; i++ ) { 268 if (flags & bvalue) { 269 switch(bvalue) { 270 case 0x00000001: 271 proto_tree_add_item(flags_tree, hfbit1, tvb, foffset, 4, ENC_BIG_ENDIAN); 272 break; 273 case 0x00000002: 274 proto_tree_add_item(flags_tree, hfbit2, tvb, foffset, 4, ENC_BIG_ENDIAN); 275 break; 276 case 0x00000004: 277 proto_tree_add_item(flags_tree, hfbit3, tvb, foffset, 4, ENC_BIG_ENDIAN); 278 break; 279 case 0x00000008: 280 proto_tree_add_item(flags_tree, hfbit4, tvb, foffset, 4, ENC_BIG_ENDIAN); 281 break; 282 case 0x00000010: 283 proto_tree_add_item(flags_tree, hfbit5, tvb, foffset, 4, ENC_BIG_ENDIAN); 284 break; 285 case 0x00000020: 286 proto_tree_add_item(flags_tree, hfbit6, tvb, foffset, 4, ENC_BIG_ENDIAN); 287 break; 288 case 0x00000040: 289 proto_tree_add_item(flags_tree, hfbit7, tvb, foffset, 4, ENC_BIG_ENDIAN); 290 break; 291 case 0x00000080: 292 proto_tree_add_item(flags_tree, hfbit8, tvb, foffset, 4, ENC_BIG_ENDIAN); 293 break; 294 case 0x00000100: 295 proto_tree_add_item(flags_tree, hfbit9, tvb, foffset, 4, ENC_BIG_ENDIAN); 296 break; 297 case 0x00000200: 298 proto_tree_add_item(flags_tree, hfbit10, tvb, foffset, 4, ENC_BIG_ENDIAN); 299 break; 300 case 0x00000400: 301 proto_tree_add_item(flags_tree, hfbit11, tvb, foffset, 4, ENC_BIG_ENDIAN); 302 break; 303 case 0x00000800: 304 proto_tree_add_item(flags_tree, hfbit12, tvb, foffset, 4, ENC_BIG_ENDIAN); 305 break; 306 case 0x00001000: 307 proto_tree_add_item(flags_tree, hfbit13, tvb, foffset, 4, ENC_BIG_ENDIAN); 308 break; 309 case 0x00002000: 310 proto_tree_add_item(flags_tree, hfbit14, tvb, foffset, 4, ENC_BIG_ENDIAN); 311 break; 312 case 0x00004000: 313 proto_tree_add_item(flags_tree, hfbit15, tvb, foffset, 4, ENC_BIG_ENDIAN); 314 break; 315 case 0x00008000: 316 proto_tree_add_item(flags_tree, hfbit16, tvb, foffset, 4, ENC_BIG_ENDIAN); 317 break; 318 case 0x00010000: 319 proto_tree_add_item(flags_tree, hfbit17, tvb, foffset, 4, ENC_BIG_ENDIAN); 320 break; 321 case 0x00020000: 322 proto_tree_add_item(flags_tree, hfbit18, tvb, foffset, 4, ENC_BIG_ENDIAN); 323 break; 324 case 0x00040000: 325 proto_tree_add_item(flags_tree, hfbit19, tvb, foffset, 4, ENC_BIG_ENDIAN); 326 break; 327 case 0x00080000: 328 proto_tree_add_item(flags_tree, hfbit20, tvb, foffset, 4, ENC_BIG_ENDIAN); 329 break; 330 case 0x00100000: 331 proto_tree_add_item(flags_tree, hfbit21, tvb, foffset, 4, ENC_BIG_ENDIAN); 332 break; 333 case 0x00200000: 334 proto_tree_add_item(flags_tree, hfbit22, tvb, foffset, 4, ENC_BIG_ENDIAN); 335 break; 336 case 0x00400000: 337 proto_tree_add_item(flags_tree, hfbit23, tvb, foffset, 4, ENC_BIG_ENDIAN); 338 break; 339 case 0x00800000: 340 proto_tree_add_item(flags_tree, hfbit24, tvb, foffset, 4, ENC_BIG_ENDIAN); 341 break; 342 case 0x01000000: 343 proto_tree_add_item(flags_tree, hfbit25, tvb, foffset, 4, ENC_BIG_ENDIAN); 344 break; 345 case 0x02000000: 346 proto_tree_add_item(flags_tree, hfbit26, tvb, foffset, 4, ENC_BIG_ENDIAN); 347 break; 348 case 0x04000000: 349 proto_tree_add_item(flags_tree, hfbit27, tvb, foffset, 4, ENC_BIG_ENDIAN); 350 break; 351 case 0x08000000: 352 proto_tree_add_item(flags_tree, hfbit28, tvb, foffset, 4, ENC_BIG_ENDIAN); 353 break; 354 case 0x10000000: 355 proto_tree_add_item(flags_tree, hfbit29, tvb, foffset, 4, ENC_BIG_ENDIAN); 356 break; 357 case 0x20000000: 358 proto_tree_add_item(flags_tree, hfbit30, tvb, foffset, 4, ENC_BIG_ENDIAN); 359 break; 360 case 0x40000000: 361 proto_tree_add_item(flags_tree, hfbit31, tvb, foffset, 4, ENC_BIG_ENDIAN); 362 break; 363 case 0x80000000: 364 proto_tree_add_item(flags_tree, hfbit32, tvb, foffset, 4, ENC_BIG_ENDIAN); 365 break; 366 default: 367 break; 368 } 369 } 370 bvalue = bvalue*2; 371 } 372 return; 373 } 374 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) 380 { 381 int offset; 382 383 offset = tvb_find_guint8(tvb, foffset, 256, '*'); 384 if (offset >= foffset) { 385 return offset - foffset; 386 } 387 return 0; 388 } 389 390 static int 391 sss_string(tvbuff_t* tvb, int hfinfo, proto_tree *sss_tree, int offset, gboolean little, guint32 length) 392 { 393 int foffset = offset; 394 guint32 str_length; 395 char buffer[1024]; 396 guint32 i; 397 guint8 c_char; 398 gint length_remaining; 399 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); 405 } 406 foffset += 4; 407 } else { 408 str_length = length; 409 } 410 length_remaining = tvb_captured_length_remaining(tvb, foffset); 411 if (length_remaining <= 0) { 412 return foffset; 413 } 414 if (str_length > (guint)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; 419 } 420 if (str_length == 0) { 421 proto_tree_add_string(sss_tree, hfinfo, tvb, offset, 4, "<Not Specified>"); 422 return foffset; 423 } 424 for ( i = 0; i < str_length; i++ ) { 425 c_char = tvb_get_guint8(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 i--; 434 str_length--; 435 } 436 } 437 foffset++; 438 } 439 buffer[i] = '\0'; 440 441 if (length==0) { 442 if (little) { 443 str_length = tvb_get_letohl(tvb, offset); 444 } else { 445 str_length = tvb_get_ntohl(tvb, offset); 446 } 447 offset += 4; 448 } else { 449 str_length = length; 450 } 451 proto_tree_add_string(sss_tree, hfinfo, tvb, offset, str_length, buffer); 452 return foffset; 453 } 454 455 void 456 dissect_sss_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, ncp_req_hash_value *request_value) 457 { 458 guint8 /*func,*/ subfunc = 0; 459 guint32 subverb=0; 460 guint32 msg_length=0; 461 guint32 foffset= 0; 462 proto_tree *atree; 463 proto_item *aitem; 464 465 466 if (tvb_reported_length_remaining(tvb, foffset)<4) { 467 return; 468 } 469 foffset = 6; 470 /*func = tvb_get_guint8(tvb, foffset);*/ 471 foffset += 1; 472 subfunc = tvb_get_guint8(tvb, foffset); 473 foffset += 1; 474 475 /* Fill in the PROTOCOL & INFO columns. */ 476 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS"); 477 col_add_fstr(pinfo->cinfo, COL_INFO, "C SecretStore - %s", val_to_str(subfunc, sss_func_enum, "Unknown (%d)")); 478 479 switch (subfunc) { 480 case 1: 481 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)")); 482 proto_tree_add_item(atree, hf_ping_version, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 483 foffset += 4; 484 proto_tree_add_item(atree, hf_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 485 /*foffset += 4;*/ 486 break; 487 case 2: 488 proto_tree_add_item(ncp_tree, hf_frag_handle, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 489 if (tvb_get_letohl(tvb, foffset)==0xffffffff) { /* Fragment handle of -1 means no fragment. So process packet */ 490 foffset += 4; 491 proto_tree_add_item(ncp_tree, hf_buffer_size, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 492 foffset += 4; 493 proto_tree_add_item(ncp_tree, hf_length, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 494 foffset += 4; 495 foffset += 12; /* Blank Context */ 496 subverb = tvb_get_letohl(tvb, foffset); 497 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str(subverb, sss_verb_enum, "Unknown (%d)")); 498 499 aitem = proto_tree_add_item(ncp_tree, hf_verb, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 500 atree = proto_item_add_subtree(aitem, ett_sss); 501 if (request_value) { 502 request_value->req_nds_flags=subverb; 503 } 504 foffset += 4; 505 process_flags(atree, tvb, foffset); 506 foffset += 4; 507 proto_tree_add_item(atree, hf_context, tvb, foffset, 4, ENC_BIG_ENDIAN); 508 foffset += 4; 509 switch (subverb) { 510 case 0: 511 foffset += 4; 512 /*foffset =*/ sss_string(tvb, hf_user, atree, foffset, TRUE, 0); 513 break; 514 case 1: 515 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0); 516 msg_length = tvb_get_letohl(tvb, foffset); 517 foffset += (msg_length+4); /* Unsure of what this length and parameter are */ 518 /* A bad secret of length greater then 256 characters will cause frag 519 packets and then we will see these as malformed packets. 520 So check to make sure we still have data in the packet anytime 521 we read a secret. */ 522 if (tvb_reported_length_remaining(tvb, foffset) > 4) { 523 /*foffset =*/ sss_string(tvb, hf_user, atree, foffset, TRUE, 0); 524 } 525 break; 526 case 2: 527 foffset += 4; 528 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0); 529 if (tvb_reported_length_remaining(tvb, foffset) > 4) { 530 msg_length = tvb_get_letohl(tvb, foffset); 531 foffset += 4; 532 if (tvb_captured_length_remaining(tvb, foffset) < (gint) msg_length) { 533 proto_tree_add_item(atree, hf_enc_data, tvb, foffset, -1, ENC_NA); 534 } else { 535 proto_tree_add_item(atree, hf_enc_data, tvb, foffset, msg_length, ENC_NA); 536 } 537 } 538 break; 539 case 3: 540 case 4: 541 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0); 542 if (tvb_reported_length_remaining(tvb, foffset) > 4) { 543 /*foffset =*/ sss_string(tvb, hf_user, atree, foffset, TRUE, 0); 544 } 545 break; 546 case 5: 547 break; 548 case 6: 549 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0); 550 if (tvb_reported_length_remaining(tvb, foffset) > 4) { 551 /*foffset =*/ sss_string(tvb, hf_user, atree, foffset, TRUE, 0); 552 } 553 break; 554 case 7: 555 msg_length = tvb_get_letohl(tvb, foffset); 556 foffset += 4; 557 proto_tree_add_item(atree, hf_enc_cred, tvb, foffset, msg_length, ENC_NA); 558 break; 559 case 8: 560 case 9: 561 default: 562 break; 563 } 564 } else { 565 col_set_str(pinfo->cinfo, COL_INFO, "C SecretStore - fragment"); 566 567 /* Fragments don't really carry a subverb so store 0xff as the subverb number */ 568 if (request_value) { 569 request_value->req_nds_flags=255; 570 } 571 if (tvb_reported_length_remaining(tvb, foffset) > 8) { 572 foffset += 4; 573 proto_tree_add_item(ncp_tree, hf_enc_data, tvb, foffset, -1, ENC_NA); 574 } 575 } 576 break; 577 case 3: 578 /* No Op */ 579 break; 580 default: 581 break; 582 } 583 } 584 585 void 586 dissect_sss_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, guint8 subfunc, ncp_req_hash_value *request_value) 587 { 588 guint32 foffset=0; 589 guint32 subverb=0; 590 guint32 msg_length=0; 591 guint32 return_code=0; 592 guint32 number_of_items=0; 593 gint32 length_of_string=0; 594 guint32 i = 0; 595 const gchar *str; 596 597 proto_tree *atree; 598 proto_item *expert_item; 599 600 foffset = 8; 601 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS"); 602 if (tvb_captured_length_remaining(tvb, foffset)<4) { 603 return; 604 } 605 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")); 606 switch (subfunc) { 607 case 1: 608 proto_tree_add_item(atree, hf_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 609 foffset += 4; 610 proto_tree_add_item(atree, hf_sss_version, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 611 /*foffset += 4;*/ 612 break; 613 case 2: 614 if (request_value) { 615 subverb = request_value->req_nds_flags; 616 str = try_val_to_str(subverb, sss_verb_enum); 617 if (str) { 618 proto_tree_add_uint(atree, hf_verb, tvb, foffset, -1, subverb); 619 } 620 } 621 proto_tree_add_item(atree, hf_length, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 622 msg_length = tvb_get_letohl(tvb, foffset); 623 foffset += 4; 624 proto_tree_add_item(atree, hf_frag_handle, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 625 foffset += 4; 626 msg_length -= 4; 627 if ((tvb_get_letohl(tvb, foffset-4)==0xffffffff) && (msg_length > 4)) { 628 foffset += 4; 629 return_code = tvb_get_letohl(tvb, foffset); 630 str = try_val_to_str(return_code, sss_errors_enum); 631 if (str) { 632 expert_item = proto_tree_add_item(atree, hf_return_code, tvb, foffset, 4, ENC_LITTLE_ENDIAN); 633 expert_add_info_format(pinfo, expert_item, &ei_return_code, "SSS Error: %s", str); 634 col_add_fstr(pinfo->cinfo, COL_INFO, "R Error - %s", val_to_str(return_code, sss_errors_enum, "Unknown (%d)")); 635 /*foffset+=4;*/ 636 } else { 637 proto_tree_add_uint_format_value(atree, hf_return_code, tvb, foffset, 4, 0, "Success (0x00000000)"); 638 if (tvb_reported_length_remaining(tvb, foffset) > 8) { 639 foffset += 4; 640 if (request_value && subverb == 6) { 641 foffset += 4; 642 number_of_items = tvb_get_letohl(tvb, foffset); 643 foffset += 8; 644 for (i=0; i<number_of_items; i++) { 645 length_of_string = find_delimiter(tvb, foffset); 646 if (length_of_string > tvb_reported_length_remaining(tvb, foffset)) { 647 return; 648 } 649 foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, length_of_string); 650 if (tvb_reported_length_remaining(tvb, foffset) < 8) { 651 return; 652 } 653 foffset++; 654 } 655 } else { 656 proto_tree_add_item(atree, hf_enc_data, tvb, foffset, tvb_captured_length_remaining(tvb, foffset), ENC_NA); 657 } 658 } 659 } 660 } else { 661 proto_tree_add_uint_format_value(atree, hf_return_code, tvb, foffset, 4, 0, "Success (0x00000000)"); 662 if (tvb_reported_length_remaining(tvb, foffset) > 8) { 663 foffset += 4; 664 proto_tree_add_item(atree, hf_enc_data, tvb, foffset, tvb_captured_length_remaining(tvb, foffset), ENC_NA); 665 } 666 } 667 break; 668 case 3: 669 break; 670 default: 671 break; 672 } 673 } 674 675 void 676 proto_register_sss(void) 677 { 678 static hf_register_info hf_sss[] = { 679 { &hf_buffer_size, 680 { "Buffer Size", "sss.buffer", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 681 682 { &hf_ping_version, 683 { "Ping Version", "sss.ping_version", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 684 685 { &hf_flags, 686 { "Flags", "sss.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 687 688 { &hf_context, 689 { "Context", "sss.context", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 690 691 { &hf_frag_handle, 692 { "Fragment Handle", "sss.frag_handle", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 693 694 { &hf_length, 695 { "Length", "sss.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 696 697 { &hf_verb, 698 { "Verb", "sss.verb", FT_UINT32, BASE_HEX, VALS(sss_verb_enum), 0x0, NULL, HFILL }}, 699 700 { &hf_user, 701 { "User", "sss.user", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 702 703 { &hf_secret, 704 { "Secret ID", "sss.secret", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 705 706 { &hf_sss_version, 707 { "SecretStore Protocol Version", "sss.version", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 708 709 { &hf_return_code, 710 { "Return Code", "sss.return_code", FT_UINT32, BASE_HEX, VALS(sss_errors_enum), 0x0, NULL, HFILL }}, 711 712 { &hf_enc_cred, 713 { "Encrypted Credential", "sss.enc_cred", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 714 715 { &hf_enc_data, 716 { "Encrypted Data", "sss.enc_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 717 718 { &hfbit1, 719 { "Enhanced Protection", "ncp.sss_bit1", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL }}, 720 721 { &hfbit2, 722 { "Create ID", "ncp.sss_bit2", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL }}, 723 724 { &hfbit3, 725 { "Remove Lock", "ncp.sss_bit3", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL }}, 726 727 { &hfbit4, 728 { "Repair", "ncp.sss_bit4", FT_BOOLEAN, 32, NULL, 0x00000008, NULL, HFILL }}, 729 730 { &hfbit5, 731 { "Unicode", "ncp.sss_bit5", FT_BOOLEAN, 32, NULL, 0x00000010, NULL, HFILL }}, 732 733 { &hfbit6, 734 { "EP Master Password Used", "ncp.sss_bit6", FT_BOOLEAN, 32, NULL, 0x00000020, NULL, HFILL }}, 735 736 { &hfbit7, 737 { "EP Password Used", "ncp.sss_bit7", FT_BOOLEAN, 32, NULL, 0x00000040, NULL, HFILL }}, 738 739 { &hfbit8, 740 { "Set Tree Name", "ncp.sss_bit8", FT_BOOLEAN, 32, NULL, 0x00000080, NULL, HFILL }}, 741 742 { &hfbit9, 743 { "Get Context", "ncp.sss_bit9", FT_BOOLEAN, 32, NULL, 0x00000100, NULL, HFILL }}, 744 745 { &hfbit10, 746 { "Destroy Context", "ncp.sss_bit10", FT_BOOLEAN, 32, NULL, 0x00000200, NULL, HFILL }}, 747 748 { &hfbit11, 749 { "Not Defined", "ncp.sss_bit11", FT_BOOLEAN, 32, NULL, 0x00000400, NULL, HFILL }}, 750 751 { &hfbit12, 752 { "Not Defined", "ncp.sss_bit12", FT_BOOLEAN, 32, NULL, 0x00000800, NULL, HFILL }}, 753 754 { &hfbit13, 755 { "Not Defined", "ncp.sss_bit13", FT_BOOLEAN, 32, NULL, 0x00001000, NULL, HFILL }}, 756 757 { &hfbit14, 758 { "Not Defined", "ncp.sss_bit14", FT_BOOLEAN, 32, NULL, 0x00002000, NULL, HFILL }}, 759 760 { &hfbit15, 761 { "Not Defined", "ncp.sss_bit15", FT_BOOLEAN, 32, NULL, 0x00004000, NULL, HFILL }}, 762 763 { &hfbit16, 764 { "Not Defined", "ncp.sss_bit16", FT_BOOLEAN, 32, NULL, 0x00008000, NULL, HFILL }}, 765 766 { &hfbit17, 767 { "EP Lock", "ncp.sss_bit17", FT_BOOLEAN, 32, NULL, 0x00010000, NULL, HFILL }}, 768 769 { &hfbit18, 770 { "Not Initialized", "ncp.sss_bit18", FT_BOOLEAN, 32, NULL, 0x00020000, NULL, HFILL }}, 771 772 { &hfbit19, 773 { "Enhanced Protection", "ncp.sss_bit19", FT_BOOLEAN, 32, NULL, 0x00040000, NULL, HFILL }}, 774 775 { &hfbit20, 776 { "Store Not Synced", "ncp.sss_bit20", FT_BOOLEAN, 32, NULL, 0x00080000, NULL, HFILL }}, 777 778 { &hfbit21, 779 { "Admin Last Modified", "ncp.sss_bit21", FT_BOOLEAN, 32, NULL, 0x00100000, NULL, HFILL }}, 780 781 { &hfbit22, 782 { "EP Password Present", "ncp.sss_bit22", FT_BOOLEAN, 32, NULL, 0x00200000, NULL, HFILL }}, 783 784 { &hfbit23, 785 { "EP Master Password Present", "ncp.sss_bit23", FT_BOOLEAN, 32, NULL, 0x00400000, NULL, HFILL }}, 786 787 { &hfbit24, 788 { "MP Disabled", "ncp.sss_bit24", FT_BOOLEAN, 32, NULL, 0x00800000, NULL, HFILL }}, 789 790 { &hfbit25, 791 { "Not Defined", "ncp.sss_bit25", FT_BOOLEAN, 32, NULL, 0x01000000, NULL, HFILL }}, 792 793 { &hfbit26, 794 { "Not Defined", "ncp.sss_bit26", FT_BOOLEAN, 32, NULL, 0x02000000, NULL, HFILL }}, 795 796 { &hfbit27, 797 { "Not Defined", "ncp.sss_bit27", FT_BOOLEAN, 32, NULL, 0x04000000, NULL, HFILL }}, 798 799 { &hfbit28, 800 { "Not Defined", "ncp.sss_bit28", FT_BOOLEAN, 32, NULL, 0x08000000, NULL, HFILL }}, 801 802 { &hfbit29, 803 { "Not Defined", "ncp.sss_bit29", FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL }}, 804 805 { &hfbit30, 806 { "Not Defined", "ncp.sss_bit30", FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL }}, 807 808 { &hfbit31, 809 { "Not Defined", "ncp.sss_bit31", FT_BOOLEAN, 32, NULL, 0x40000000, NULL, HFILL }}, 810 811 { &hfbit32, 812 { "Not Defined", "ncp.sss_bit32", FT_BOOLEAN, 32, NULL, 0x80000000, NULL, HFILL }} 813 }; 814 815 static gint *ett[] = { 816 &ett_sss 817 }; 818 819 static ei_register_info ei[] = { 820 { &ei_return_code, { "sss.return_code.expert", PI_RESPONSE_CODE, PI_NOTE, "SSS Error", EXPFILL }} 821 }; 822 823 expert_module_t* expert_sss; 824 /*module_t *sss_module;*/ 825 826 proto_sss = proto_register_protocol("Novell SecretStore Services", "SSS", "sss"); 827 proto_register_field_array(proto_sss, hf_sss, array_length(hf_sss)); 828 proto_register_subtree_array(ett, array_length(ett)); 829 expert_sss = expert_register_protocol(proto_sss); 830 expert_register_field_array(expert_sss, ei, array_length(ei)); 831 } 832 833 /* 834 * Editor modelines - https://www.wireshark.org/tools/modelines.html 835 * 836 * Local variables: 837 * c-basic-offset: 4 838 * tab-width: 8 839 * indent-tabs-mode: nil 840 * End: 841 * 842 * vi: set shiftwidth=4 tabstop=8 expandtab: 843 * :indentSize=4:tabSize=8:noTabs=true: 844 */ 845 846