1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <ctype.h> 31 #include <string.h> 32 #include <fcntl.h> 33 #include <string.h> 34 #include <sys/types.h> 35 #include <sys/time.h> 36 #include <sys/stat.h> 37 #include <sys/uio.h> 38 #include <unistd.h> 39 #include <signal.h> 40 #include <errno.h> 41 #include <stdlib.h> 42 #include <sys/wait.h> 43 #include <sys/socket.h> 44 #include <sys/sockio.h> 45 #include <net/if.h> 46 #include <netinet/in_systm.h> 47 #include <netinet/in.h> 48 #include <netinet/ip.h> 49 #include <netinet/if_ether.h> 50 #include <netinet/udp.h> 51 #include "snoop.h" 52 53 #ifndef MIN 54 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 55 #endif 56 57 extern char *src_name; 58 extern char *dst_name; 59 #define MAX_CTX (10) 60 #define LINE_LEN (255) 61 #define BUF_SIZE (16000) 62 static int ldap = 0; /* flag to control initialization */ 63 struct ctx { 64 int src; 65 int dst; 66 char *src_name; 67 char *dst_name; 68 }; 69 char *osibuff = NULL; 70 int osilen = 0; 71 char scrbuffer[BUF_SIZE]; /* buffer to accumulate data until a */ 72 /* complete LDAPmessage is received */ 73 char resultcode[LINE_LEN]; /* These are used */ 74 char operation[LINE_LEN]; /* by -V option. */ 75 char bb[LINE_LEN]; 76 77 int gi_osibuf[MAX_CTX]; 78 int otyp[MAX_CTX]; 79 int olen[MAX_CTX]; 80 int level[MAX_CTX]; 81 82 void decode_ldap(char *buf, int len); 83 84 #define X unsigned char 85 typedef X * A; 86 #define INT(a) ((int)(a)) 87 #define SCRUB (void) strcat(scrbuffer, bb); 88 89 static X hex; /* input hex octet */ 90 static A *PTRaclass; /* application tag table pointer */ 91 92 /* 93 * ASN.1 Message Printing Macros 94 */ 95 96 #define asnshw1(a) {(void)sprintf(bb, a); SCRUB } 97 #define asnshw2(a, b) {(void)sprintf(bb, a, b); SCRUB } 98 #define asnshw3(a, b, c) {(void)sprintf(bb, a, b, c); SCRUB } 99 #define asnshw4(a, b, c, d) {(void)sprintf(bb, a, b, c, d); SCRUB } 100 #define asnshw5(a, b, c, d, e) {(void)sprintf(bb, a, b, c, d, e); SCRUB } 101 102 /* 103 * Local Types And Variables 104 */ 105 106 /* 107 * Object identifier oid to name mapping description type 108 */ 109 110 typedef struct { 111 A oidname; /* object identifier string name */ 112 X oidcode[16]; /* object identifier hexa code */ 113 } oidelmT; 114 typedef oidelmT *oidelmTp; 115 116 /* 117 * Snoop's entry point to ldap decoding 118 */ 119 120 void 121 interpret_ldap(flags, data, fraglen, src, dst) 122 int flags; 123 char *data; 124 int fraglen; 125 int src; 126 int dst; 127 { 128 129 if (!ldap) { 130 init_ldap(); 131 ldap = 1; 132 } 133 134 (void) decode_ldap(data, fraglen); 135 136 if (flags & F_DTAIL) { 137 /* i.e. when snoop is run with -v (verbose) */ 138 show_header("LDAP: ", 139 "Lightweight Directory Access Protocol Header", fraglen); 140 show_space(); 141 printf("%s", scrbuffer); 142 } 143 144 if (flags & F_SUM) { 145 /* i.e. when snoop is run with -V (summary) */ 146 (void) strcpy(data, ""); 147 148 if (strlen(operation) != 0) { 149 (void) strcat(data, " "); 150 (void) strncat(data, operation, 30); 151 (void) strcpy(operation, ""); 152 } 153 154 if (strlen(resultcode) != 0) { 155 (void) strcat(data, " "); 156 (void) strncat(data, resultcode, 30); 157 (void) strcpy(resultcode, ""); 158 } 159 160 if (dst == 389) { 161 (void) sprintf(get_sum_line(), 162 "LDAP C port=%d%s", src, data); 163 } 164 if (src == 389) { 165 (void) sprintf(get_sum_line(), 166 "LDAP R port=%d%s", dst, data); 167 } 168 } 169 170 (void) strcpy(scrbuffer, ""); 171 } 172 173 /* 174 * Known object identifiers: customize to add your own oids 175 */ 176 177 static oidelmT OidTab[] = { 178 /* 179 * X.500 Standardized Attribute Types 180 */ 181 {(A)"ObjectClass", { 0x03, 0x55, 0x04, 0x00 }}, 182 {(A)"AliasObjectName", { 0x03, 0x55, 0x04, 0x01 }}, 183 {(A)"KnowledgeInfo", { 0x03, 0x55, 0x04, 0x02 }}, 184 {(A)"CommonName", { 0x03, 0x55, 0x04, 0x03 }}, 185 {(A)"Surname", { 0x03, 0x55, 0x04, 0x04 }}, 186 {(A)"SerialNumber", { 0x03, 0x55, 0x04, 0x05 }}, 187 {(A)"CountryName", { 0x03, 0x55, 0x04, 0x06 }}, 188 {(A)"LocalityName", { 0x03, 0x55, 0x04, 0x07 }}, 189 {(A)"StateOrProvinceName", { 0x03, 0x55, 0x04, 0x08 }}, 190 {(A)"StreetAddress", { 0x03, 0x55, 0x04, 0x09 }}, 191 {(A)"OrganizationName", { 0x03, 0x55, 0x04, 0x0a }}, 192 {(A)"OrganizationUnitName", { 0x03, 0x55, 0x04, 0x0b }}, 193 {(A)"Title", { 0x03, 0x55, 0x04, 0x0c }}, 194 {(A)"Description", { 0x03, 0x55, 0x04, 0x0d }}, 195 {(A)"SearchGuide", { 0x03, 0x55, 0x04, 0x0e }}, 196 {(A)"BusinessCategory", { 0x03, 0x55, 0x04, 0x0f }}, 197 {(A)"PostalAddress", { 0x03, 0x55, 0x04, 0x10 }}, 198 {(A)"PostalCode", { 0x03, 0x55, 0x04, 0x11 }}, 199 {(A)"PostOfficeBox", { 0x03, 0x55, 0x04, 0x12 }}, 200 {(A)"PhysicalDeliveryOffice", { 0x03, 0x55, 0x04, 0x13 }}, 201 {(A)"TelephoneNUmber", { 0x03, 0x55, 0x04, 0x14 }}, 202 {(A)"TelexNumber", { 0x03, 0x55, 0x04, 0x15 }}, 203 {(A)"TeletexTerminalId", { 0x03, 0x55, 0x04, 0x16 }}, 204 {(A)"FaxTelephoneNumber", { 0x03, 0x55, 0x04, 0x17 }}, 205 {(A)"X121Address", { 0x03, 0x55, 0x04, 0x18 }}, 206 {(A)"IsdnAddress", { 0x03, 0x55, 0x04, 0x19 }}, 207 {(A)"RegisteredAddress", { 0x03, 0x55, 0x04, 0x1a }}, 208 {(A)"DestinationIndicator", { 0x03, 0x55, 0x04, 0x1b }}, 209 {(A)"PreferDeliveryMethod", { 0x03, 0x55, 0x04, 0x1c }}, 210 {(A)"PresentationAddress", { 0x03, 0x55, 0x04, 0x1d }}, 211 {(A)"SupportedApplContext", { 0x03, 0x55, 0x04, 0x1e }}, 212 {(A)"Member", { 0x03, 0x55, 0x04, 0x1f }}, 213 {(A)"Owner", { 0x03, 0x55, 0x04, 0x20 }}, 214 {(A)"RoleOccupant", { 0x03, 0x55, 0x04, 0x21 }}, 215 {(A)"SeeAlso", { 0x03, 0x55, 0x04, 0x22 }}, 216 {(A)"Password", { 0x03, 0x55, 0x04, 0x23 }}, 217 {(A)"UserCertificate", { 0x03, 0x55, 0x04, 0x24 }}, 218 {(A)"CaCertificate", { 0x03, 0x55, 0x04, 0x25 }}, 219 {(A)"AuthorityRevList", { 0x03, 0x55, 0x04, 0x26 }}, 220 {(A)"CertificateRevList", { 0x03, 0x55, 0x04, 0x27 }}, 221 {(A)"CrossCertificatePair", { 0x03, 0x55, 0x04, 0x28 }}, 222 223 /* 224 * X.500 Standardized Object Classes 225 */ 226 {(A)"Top", { 0x03, 0x55, 0x06, 0x00 }}, 227 {(A)"Alias", { 0x03, 0x55, 0x06, 0x01 }}, 228 {(A)"Country", { 0x03, 0x55, 0x06, 0x02 }}, 229 {(A)"Locality", { 0x03, 0x55, 0x06, 0x03 }}, 230 {(A)"Organization", { 0x03, 0x55, 0x06, 0x04 }}, 231 {(A)"OrganizationUnit", { 0x03, 0x55, 0x06, 0x05 }}, 232 {(A)"Person", { 0x03, 0x55, 0x06, 0x06 }}, 233 {(A)"OrganizationPersion", { 0x03, 0x55, 0x06, 0x07 }}, 234 {(A)"OrganizationRole", { 0x03, 0x55, 0x06, 0x08 }}, 235 {(A)"Group", { 0x03, 0x55, 0x06, 0x09 }}, 236 {(A)"ResidentialPerson", { 0x03, 0x55, 0x06, 0x0A }}, 237 {(A)"ApplicationProcess", { 0x03, 0x55, 0x06, 0x0B }}, 238 {(A)"ApplicationEntity", { 0x03, 0x55, 0x06, 0x0C }}, 239 {(A)"Dsa", { 0x03, 0x55, 0x06, 0x0D }}, 240 {(A)"Device", { 0x03, 0x55, 0x06, 0x0E }}, 241 {(A)"StrongAuthenticUser", { 0x03, 0x55, 0x06, 0x0F }}, 242 {(A)"CaAuthority", { 0x03, 0x55, 0x06, 0x10 }}, 243 244 /* 245 * ACSE Protocol Object Identifiers 246 */ 247 {(A)"Asn1BER-TS", { 0x02, 0x51, 0x01 }}, 248 {(A)"Private-TS", { 0x06, 0x2b, 0xce, 0x06, 0x01, 0x04, 0x06 }}, 249 {(A)"ACSE-AS", { 0x04, 0x52, 0x01, 0x00, 0x01 }}, 250 251 /* 252 * Directory Protocol Oids 253 */ 254 {(A)"DirAccess-AC", { 0x03, 0x55, 0x03, 0x01 }}, 255 {(A)"DirSystem-AC", { 0x03, 0x55, 0x03, 0x02 }}, 256 257 {(A)"DirAccess-AS", { 0x03, 0x55, 0x09, 0x01 }}, 258 {(A)"DirSystem-AS", { 0x03, 0x55, 0x09, 0x02 }}, 259 260 /* 261 * and add your private object identifiers here ... 262 */ 263 }; 264 265 #define OIDNB (sizeof (OidTab) / sizeof (oidelmT)) /* total oid nb */ 266 267 /* 268 * asn.1 tag class definition 269 */ 270 271 static A class[] = { /* tag class */ 272 (A)"UNIV ", 273 (A)"APPL ", 274 (A)"CTXs ", 275 (A)"PRIV " 276 }; 277 278 /* 279 * universal tag definition 280 */ 281 282 static A uclass[] = { /* universal tag assignment */ 283 (A)"EndOfContents", /* 0 */ 284 (A)"Boolean", /* 1 */ 285 (A)"Integer", /* 2 */ 286 (A)"BitString", /* 3 */ 287 (A)"OctetString", /* 4 */ 288 (A)"Null", /* 5 */ 289 (A)"Oid", /* 6 */ 290 (A)"ObjDescriptor", /* 7 */ 291 (A)"External", /* 8 */ 292 (A)"Real", /* 9 */ 293 (A)"Enumerated", /* 10 */ 294 (A)"Reserved", /* 11 */ 295 (A)"Reserved", /* 12 */ 296 (A)"Reserved", /* 13 */ 297 (A)"Reserved", /* 14 */ 298 (A)"Reserved", /* 15 */ 299 (A)"Sequence", /* 16 */ 300 (A)"Set", /* 17 */ 301 (A)"NumericString", /* 18 */ 302 (A)"PrintableString", /* 19 */ 303 (A)"T.61String", /* 20 */ 304 (A)"VideotexString", /* 21 */ 305 (A)"IA5String", /* 22 */ 306 (A)"UTCTime", /* 23 */ 307 (A)"GeneralizedTime", /* 24 */ 308 (A)"GraphicString", /* 25 */ 309 (A)"VisibleString", /* 26 */ 310 (A)"GeneralString", /* 27 */ 311 (A)"Reserved", /* 28 */ 312 (A)"Reserved", /* 29 */ 313 (A)"Reserved", /* 30 */ 314 (A)"Reserved" /* 31 */ 315 }; 316 317 static A MHSaclass[] = { /* mhs application tag assignment */ 318 (A)"Bind Request", /* 0 */ 319 (A)"Bind Response", 320 (A)"Unbind Request", 321 (A)"Search Request", 322 (A)"Search ResEntry", 323 (A)"Search ResDone", /* 5 */ 324 (A)"Modify Request", 325 (A)"Modify Response", 326 (A)"Add Request", 327 (A)"Add Response", /* 9 */ 328 (A)"Del Request", 329 (A)"Del Response", 330 (A)"ModDN Request", 331 (A)"ModDN Response", 332 (A)"Compare Request", /* 14 */ 333 (A)"Compare Response", 334 (A)"Abandon Request", 335 (A)"", /* 17 */ 336 (A)"", /* 18 */ 337 (A)"Search ResRef", /* 19 */ 338 (A)"", /* 20 */ 339 (A)"", /* 21 */ 340 (A)"", /* 22 */ 341 (A)"Extended Request", 342 (A)"Extended Response", 343 (A)"", /* 25 */ 344 (A)"", /* 26 */ 345 (A)"", /* 27 */ 346 (A)"", /* 28 */ 347 (A)"", /* 29 */ 348 (A)"", /* 30 */ 349 (A)"" /* 31 */ 350 }; 351 352 353 static A DFTaclass[] = { /* Default Application Tag Assignment */ 354 (A)"", /* 0 */ 355 (A)"", /* 1 */ 356 (A)"", /* 2 */ 357 (A)"", /* 3 */ 358 (A)"", /* 4 */ 359 (A)"", /* 5 */ 360 (A)"", /* 6 */ 361 (A)"", /* 7 */ 362 (A)"", /* 8 */ 363 (A)"", /* 9 */ 364 (A)"", /* 10 */ 365 (A)"", /* 11 */ 366 (A)"", /* 12 */ 367 (A)"", /* 13 */ 368 (A)"", /* 14 */ 369 (A)"", /* 15 */ 370 (A)"", /* 16 */ 371 (A)"", /* 17 */ 372 (A)"", /* 18 */ 373 (A)"", /* 19 */ 374 (A)"", /* 20 */ 375 (A)"", /* 21 */ 376 (A)"", /* 22 */ 377 (A)"", /* 23 */ 378 (A)"", /* 24 */ 379 (A)"", /* 25 */ 380 (A)"", /* 26 */ 381 (A)"", /* 27 */ 382 (A)"", /* 28 */ 383 (A)"", /* 29 */ 384 (A)"", /* 30 */ 385 (A)"" /* 31 */ 386 }; 387 388 typedef struct asndefS { 389 char *name; 390 int type; 391 int application; 392 int nbson; 393 struct { 394 char *sonname; 395 struct asndefS *sondef; 396 long tag; 397 } son[50]; 398 } asndefT, * asndefTp; 399 400 #define SEQUENCE 0x0002 401 #define SEQUENCEOF 0x0003 402 #define SET 0x0004 403 #define PRINTABLE 0x0008 404 #define ENUM 0x0010 405 #define BITSTRING 0x0020 406 #define EXTENSION 0x0040 407 #define CONTENTTYPE 0x0080 408 #define CONTENT 0x0100 409 #define CHOICE 0x0200 410 411 static asndefT RTSpasswd = { "RTS Authentification data", SET, -1, 2, { 412 {"MTA Name", 0, 0}, 413 {"MTA Password", 0, 1}}}; 414 static asndefT RTSudata = { "RTS User data", SET, -1, 1, { 415 {0, &RTSpasswd, 1}}}; 416 417 static asndefT baseObject = {"Base Object", PRINTABLE, -1, 0, {0}}; 418 419 static asndefT scope = {"Scope", ENUM, -1, 3, { 420 {"BaseObject", 0, 0}, 421 {"singleLevel", 0, 1}, 422 {"wholeSubtree", 0, 2}}}; 423 424 static asndefT derefAliases = {"DerefAliases", ENUM, -1, 4, { 425 {"neverDerefAliases", 0, 0}, 426 {"derefInSearching", 0, 1}, 427 {"derefFindingBaseObj", 0, 2}, 428 {"derefAlways", 0, 3}}}; 429 430 static asndefT filter; 431 static asndefT and = {"And", SET, -1, 1, { 432 {0, &filter, -1}}}; 433 static asndefT or = {"Or", SET, -1, 1, { 434 {0, &filter, -1}}}; 435 static asndefT not = {"Not", SET, -1, 1, { 436 {0, &filter, -1}}}; 437 static asndefT equalityMatch = {"Equality Match", SEQUENCE, -1, 2, { 438 {"Attr Descr", 0, -1}, 439 {"Value", 0, -1}}}; 440 static asndefT substrings = {"Substring", SEQUENCE, -1, 2, { 441 {"Type", 0, -1}, 442 {"Substrings (initial)", 0, 0}, 443 {"Substrings (any)", 0, 1}, 444 {"Substring (final)", 0, 2}}}; 445 static asndefT greaterOrEqual = {"Greater Or Equal", SEQUENCE, -1, 2, { 446 {"Attr Descr", 0, -1}, 447 {"Value", 0, -1}}}; 448 static asndefT lessOrEqual = {"Less Or Equal", SEQUENCE, -1, 2, { 449 {"Attr Descr", 0, -1}, 450 {"Value", 0, -1}}}; 451 static asndefT approxMatch = {"Approx Match", SEQUENCE, -1, 2, { 452 {"Attr Descr", 0, -1}, 453 {"Value", 0, -1}}}; 454 static asndefT extensibleMatch = {"Extensible Match", SEQUENCE, -1, 4, { 455 {"MatchingRule", 0, 1}, 456 {"Type", 0, 2}, 457 {"MatchValue", 0, 3}, 458 {"dnAttributes", 0, 4}}}; 459 460 static asndefT filter = {"Filter", CHOICE, -1, 10, { 461 {0, &and, 0}, 462 {0, &or, 1}, 463 {0, ¬, 2}, 464 {0, &equalityMatch, 3}, 465 {0, &substrings, 4}, 466 {0, &greaterOrEqual, 5}, 467 {0, &lessOrEqual, 6}, 468 {"Filter: Present", 0, 7}, 469 {0, &approxMatch, 8}, 470 {0, &extensibleMatch, 9}}}; 471 472 static asndefT attributedescription = \ 473 {"Attribute Description", PRINTABLE, -1, 0, {0}}; 474 static asndefT attributes = {"Attribute List", SEQUENCEOF, -1, 1, { 475 {0, &attributedescription, -1}}}; 476 477 static asndefT searchRequest = {"Operation", SEQUENCE, 3, 8, { 478 {0, &baseObject, -1}, 479 {0, &scope, -1}, 480 {0, &derefAliases, -1}, 481 {"SizeLimit", 0, -1}, 482 {"TimeLimit", 0, -1}, 483 {"TypesOnly", 0, -1}, 484 {0, &filter, -1}, 485 {0, &attributes, -1}}}; 486 487 static asndefT objectName = {"Object Name", PRINTABLE, -1, 0, {0}}; 488 489 static asndefT ldapEntry = {"Entry", PRINTABLE, -1, 0, {0}}; 490 static asndefT relativeLdapEntry = \ 491 {"Relative LDAP Entry", PRINTABLE, -1, 0, {0}}; 492 static asndefT newSuperior = {"New Superior", PRINTABLE, -1, 0, {0}}; 493 494 static asndefT vals = {"Vals", SET, -1, 1, { 495 {"Value", 0, -1}}}; 496 497 static asndefT attribute = {"Attribute", SEQUENCE, -1, 2, { 498 {"Type", 0, -1}, 499 {0, &vals, -1}}}; 500 501 static asndefT partialAttributes = {"Partial Attributes", SEQUENCEOF, -1, 1, { 502 {0, &attribute, -1}}}; 503 504 static asndefT searchResEntry = {"Operation", SEQUENCE, 4, 2, { 505 {0, &objectName, -1}, 506 {0, &partialAttributes, -1}}}; 507 508 static asndefT authChoice = {"Authentication Choice", CHOICE, -1, 2, { 509 {"Authentication: Simple", 0, 0}, 510 {"Authentication: SASL", 0, 3}}}; 511 512 static asndefT bindRequest = {"Operation", SEQUENCE, 0, 3, { 513 {"Version", 0, -1}, 514 {0, &objectName, -1}, 515 {0, &authChoice, -1}}}; 516 517 static asndefT resultCode = {"Result Code", ENUM, -1, 39, { 518 {"Success", 0, 0}, 519 {"Operation Error", 0, 1}, 520 {"Protocol Error", 0, 2}, 521 {"Time Limit Exceeded", 0, 3}, 522 {"Size Limit Exceeded", 0, 4}, 523 {"Compare False", 0, 5}, 524 {"Compare True", 0, 6}, 525 {"Auth Method Not supported", 0, 7}, 526 {"Strong Auth Required", 0, 8}, 527 {"Referral", 0, 10}, 528 {"Admin Limit Exceeded", 0, 11}, 529 {"Unavailable Critical Extension", 0, 12}, 530 {"Confidentiality required", 0, 13}, 531 {"SASL Bind In Progress", 0, 14}, 532 {"No Such Attribute", 0, 16}, 533 {"Undefined Attribute Type", 0, 17}, 534 {"Inappropriate Matching", 0, 18}, 535 {"Constraint violation", 0, 19}, 536 {"Attribute or Value Exists", 0, 20}, 537 {"Invalid Attribute Syntax", 0, 21}, 538 {"No Such Object", 0, 32}, 539 {"Alias Problem", 0, 33}, 540 {"Invalid DN Syntax", 0, 34}, 541 {"Alias Dereferencing Problem", 0, 36}, 542 {"Inappropriate Authentication", 0, 48}, 543 {"Invalid Credentials", 0, 49}, 544 {"Insufficient Access Rights", 0, 50}, 545 {"Busy", 0, 51}, 546 {"Unavailable", 0, 52}, 547 {"Unwilling To Perform", 0, 53}, 548 {"Loop Detect", 0, 54}, 549 {"Naming Violation", 0, 64}, 550 {"ObjectClass violation", 0, 65}, 551 {"Not Allowed On Non Leaf", 0, 66}, 552 {"Not Allowed On RDN", 0, 67}, 553 {"Entry Already Exists", 0, 68}, 554 {"ObjectClass Mods Prohibited", 0, 69}, 555 {"Affects Multiple DSAs", 0, 71}, 556 {"Other", 0, 80}}}; 557 558 559 static asndefT referral = {"Referral", SEQUENCEOF, -1, 1, { 560 {"LDAP URL", 0, -1}}}; 561 562 static asndefT ldapResult = {"LDAP Result", SEQUENCE, -1, 4, { 563 {0, &resultCode, -1}, 564 {"Matched DN", 0, -1}, 565 {"Error Message", 0, -1}, 566 {0, &referral, 3}}}; 567 568 static asndefT bindResponse = {"Operation", SEQUENCE, 1, 5, { 569 {0, &resultCode, -1}, 570 {"Matched DN", 0, -1}, 571 {"Error Message", 0, -1}, 572 {0, &referral, 3}, 573 {"SASL Credentials", 0, 7}}}; 574 575 static asndefT unbindRequest = {"Operation", SEQUENCE, 2, 0, {0}}; 576 577 static asndefT searchResDone = {"Operation", SEQUENCE, 5, 4, { 578 {0, &resultCode, -1}, 579 {"Matched DN", 0, -1}, 580 {"Error Message", 0, -1}, 581 {0, &referral, 3}}}; 582 583 static asndefT seqModOperation = {"Operation", ENUM, -1, 4, { 584 {"Add", 0, 0}, 585 {"Delete", 0, 1}, 586 {"Replace", 0, 2}}}; 587 588 static asndefT seqModModification = {"Modification", SEQUENCE, -1, 1, { 589 {0, &attribute, -1}}}; 590 591 static asndefT seqModification = {"", SEQUENCE, -1, 2, { 592 {0, &seqModOperation, -1}, 593 {0, &seqModModification, -1}}}; 594 595 static asndefT modification = {"Modification", SEQUENCEOF, -1, 1, { 596 {0, &seqModification, -1}}}; 597 598 static asndefT modifyRequest = {"Operation", SEQUENCE, 6, 2, { 599 {0, &objectName, -1}, 600 {0, &modification, -1}}}; 601 602 static asndefT modifyResponse = {"Operation", SEQUENCE, 7, 4, { 603 {0, &resultCode, -1}, 604 {"Matched DN", 0, -1}, 605 {"Error Message", 0, -1}, 606 {0, &referral, 3}}}; 607 608 static asndefT addAttributes = {"Attributes", SEQUENCEOF, -1, 1, { 609 {0, &attribute, -1}}}; 610 611 static asndefT addRequest = {"Operation", SEQUENCE, 8, 2, { 612 {0, &ldapEntry, -1}, 613 {0, &addAttributes, -1}}}; 614 615 static asndefT addResponse = {"Operation", SEQUENCE, 9, 4, { 616 {0, &resultCode, -1}, 617 {"Matched DN", 0, -1}, 618 {"Error Message", 0, -1}, 619 {0, &referral, 3}}}; 620 621 static asndefT delRequest = {"Operation", SEQUENCE, 10, 1, { 622 {0, &ldapEntry, -1}}}; 623 624 static asndefT delResponse = {"Operation", SEQUENCE, 11, 4, { 625 {0, &resultCode, -1}, 626 {"Matched DN", 0, -1}, 627 {"Error Message", 0, -1}, 628 {0, &referral, 3}}}; 629 630 static asndefT modifyDNRequest = {"Operation", SEQUENCE, 12, 4, { 631 {0, &ldapEntry, -1}, 632 {0, &relativeLdapEntry, -1}, 633 {"Delete Old RDN", 0, -1}, 634 {0, &newSuperior, 0}}}; 635 636 static asndefT modifyDNResponse = {"Operation", SEQUENCE, 13, 4, { 637 {0, &resultCode, -1}, 638 {"Matched DN", 0, -1}, 639 {"Error Message", 0, -1}, 640 {0, &referral, 3}}}; 641 642 static asndefT ava = {"Ava", SEQUENCE, -1, 2, { 643 {"Attr Descr", 0, -1}, 644 {"Value", 0, -1}}}; 645 646 static asndefT compareRequest = {"Operation", SEQUENCE, 14, 2, { 647 {0, &ldapEntry, -1}, 648 {0, &ava, 0}}}; 649 650 static asndefT compareResponse = {"Operation", SEQUENCE, 15, 4, { 651 {0, &resultCode, -1}, 652 {"Matched DN", 0, -1}, 653 {"Error Message", 0, -1}, 654 {0, &referral, 3}}}; 655 656 static asndefT abandonRequest = {"Operation", SEQUENCE, 16, 1, { 657 {"Message ID", 0, -1}}}; 658 659 static asndefT searchResRef = {"Operation", SEQUENCEOF, 19, 1, { 660 {"LDAP URL", 0, -1}}}; 661 662 static asndefT extendedRequest = {"Operation", SEQUENCE, 14, 2, { 663 {"Request Name", 0, 0}, 664 {"Request Value", 0, 1}}}; 665 666 static asndefT extendedResponse = {"Operation", SEQUENCE, 24, 6, { 667 {0, &resultCode, -1}, 668 {"Matched DN", 0, -1}, 669 {"Error Message", 0, -1}, 670 {0, &referral, 3}, 671 {"Response Name", 0, 10}, 672 {"Response", 0, 11}}}; 673 674 static asndefT protocolOp = {"Protocol Op", CHOICE, -1, 20, { 675 {0, &bindRequest, 0}, 676 {0, &bindResponse, 1}, 677 {0, &unbindRequest, 2}, 678 {0, &searchRequest, 3}, 679 {0, &searchResEntry, 4}, 680 {0, &searchResDone, 5}, 681 {0, &modifyRequest, 6}, 682 {0, &modifyResponse, 7}, 683 {0, &addRequest, 8}, 684 {0, &addResponse, 9}, 685 {0, &delRequest, 10}, 686 {0, &delResponse, 11}, 687 {0, &modifyDNRequest, 12}, 688 {0, &modifyDNResponse, 13}, 689 {0, &compareRequest, 14}, 690 {0, &compareResponse, 15}, 691 {0, &abandonRequest, 16}, 692 {0, &searchResRef, 19}, 693 {0, &extendedRequest, 23}, 694 {0, &extendedResponse, 24}}}; 695 696 static asndefT control = {"Control", SEQUENCE, -1, 3, { 697 {"LDAP OID", 0, -1}, 698 {"Criticality", 0, -1}, 699 {"Control value", 0, -1}}}; 700 701 static asndefT controls = {"Controls List", SEQUENCEOF, -1, 1, { 702 {0, &control, -1}}}; 703 704 static asndefT LDAPMessage = { "LDAPMessage", SEQUENCE, -1, 3, { 705 {"Message ID", 0, -1}, 706 {0, &protocolOp, -1}, 707 {0, &controls, 0}}}; 708 709 static asndefT MPDU = { "MPDU", SET, -1, 1, 710 {{0, &LDAPMessage, 0}}}; 711 712 static int mytype[] = { 713 0, /* EndOfContents */ 714 0, /* Boolean */ 715 0, /* Integer */ 716 BITSTRING, /* BitString */ 717 0, /* OctetString */ 718 0, /* Null */ 719 0, /* Oid */ 720 0, /* ObjDescriptor */ 721 0, /* External */ 722 0, /* Real */ 723 ENUM, /* Enumerated */ 724 0, /* Reserved */ 725 0, /* Reserved */ 726 0, /* Reserved */ 727 0, /* Reserved */ 728 0, /* Reserved */ 729 SEQUENCE, /* Sequence */ 730 SET, /* Set */ 731 0, /* NumericString */ 732 0, /* PrintableString */ 733 0, /* T.61String */ 734 0, /* VideotexString */ 735 0, /* IA5String */ 736 0, /* UTCTime */ 737 0, /* GeneralizedTime */ 738 0, /* GraphicString */ 739 0, /* VisibleString */ 740 0, /* GeneralString */ 741 0, /* Reserved */ 742 0, /* Reserved */ 743 0, /* Reserved */ 744 0, /* Reserved */ 745 }; 746 747 /* 748 * Find object identifier in known oid table 749 * A oid - oid hexa string 750 * int olg - oid length 751 */ 752 static int 753 oidmap(A oid, int olg) 754 { 755 register int ix, goon; 756 register A oidptr, tabptr, tabend; 757 758 /* returns (oid table size) if not found */ 759 760 for (ix = 0; ix < OIDNB; ix++) { 761 oidptr = oid; tabptr = (&(OidTab[ix].oidcode[0])); 762 if (olg == INT(*tabptr++)) { 763 tabend = tabptr + olg; 764 goon = 1; 765 while (goon != 0 && tabptr < tabend) { 766 if (*tabptr++ != *oidptr++) 767 goon = 0; 768 } 769 if (goon != 0) 770 return (ix); 771 } 772 } 773 return (OIDNB); 774 } 775 776 /* 777 * Read an hexacode and convert it into ASCII 778 */ 779 static int getnext(int ctxnum) 780 { 781 static X c[3]; /* c[0-3] will contain ascii values on exit */ 782 hex = 0; 783 if (gi_osibuf[ctxnum] == osilen) 784 return (-1); 785 hex = osibuff[gi_osibuf[ctxnum]++]; 786 (void) sprintf((char *)c, "%02x", (hex&0x00FF)); 787 return (0); 788 } 789 790 /* 791 * Skip everything that is not an LDAPMessage 792 */ 793 static char *skipjunk(len, pdu) 794 int len; 795 char *pdu; 796 { 797 int tag; 798 char *buf = pdu; 799 int offset = 0; 800 while (len > 0) { 801 /* size minumum for a sequence + integer = 5 */ 802 /* LDAPMessage::= SEQUENCE */ 803 if ((len > 5) && (buf[0] == 0x30)) { 804 tag = buf[1]&0x00ff; 805 if (tag < 0x80) { 806 /* length is one one octet */ 807 offset = 1; 808 } else { 809 /* length is multiple octet. */ 810 offset = 1+ tag&0x007f; 811 } 812 /* Make sure we don't read past the end */ 813 /* of the buffer */ 814 if (len - (1+offset) > 0) { 815 /* skip after the length */ 816 tag = buf[1+offset]&0x00ff; 817 if (tag == 0x02) { /* INTEGER */ 818 /* looks like a valid PDU */ 819 return (buf); 820 } 821 } 822 } 823 len --; 824 buf++; 825 } 826 return (buf); 827 } 828 829 830 #define GETNEXT(a) (void)getnext(a); 831 832 /* 833 * main routine: decode a TLV; to be called recursively 834 * 835 * pdulen: current pdu's length 836 */ 837 static int 838 decpdu(int pdulen, asndefTp ASNDESC, int ctxnum) 839 { 840 X scrlin[99]; /* screen line */ 841 X oidstr[80]; /* oid hexa string */ 842 int slen; /* screen line length */ 843 int stlv; /* sub-tlv length */ 844 int oix; /* oid table index */ 845 int effnb; /* effectively traced octet nb */ 846 int i = 0, j = 0; 847 int ai = -2; 848 asndefTp SASNDESC = 0; 849 asndefTp TMPDESC = 0; 850 asndefTp GR_TMPDESC = 0; 851 int tmpai = 0; 852 int gr_tmpai = 0; 853 int dontprint = 0; 854 int already = 0; 855 static int rlen = 0; /* tlv's real length */ 856 857 ++level[ctxnum]; /* level indicator */ 858 effnb = 0; 859 860 /* 861 * Decode the current TLV segment 862 */ 863 while (pdulen > 1) { 864 865 if (getnext(ctxnum)) { 866 break; 867 } 868 if (strlen(scrbuffer)) asnshw2("%s ", "LDAP:"); 869 /* screen printing according to level indicator */ 870 for (i = 1; i < level[ctxnum]; ++i) asnshw1(" "); 871 872 /* get tag */ 873 otyp[ctxnum] = INT(hex); /* single octet type only */ 874 --pdulen; 875 ++effnb; 876 877 /* get length */ 878 GETNEXT(ctxnum); 879 olen[ctxnum] = INT(hex); /* tlv length */ 880 --pdulen; 881 ++effnb; 882 883 /* Continuing decoding of current TLV... */ 884 /* 885 * Snoop's lower layers do not allow us 886 * to know the true length for 887 * datastream protocols like LDAP. 888 */ 889 890 /* 891 * if length is less than 128, we 892 * already have the real TLV length. 893 */ 894 if (olen[ctxnum] < 128) { /* short length form */ 895 rlen = olen[ctxnum]; 896 } else { /* long and any form length */ 897 /* else we do more getnext()'s */ 898 for (rlen = 0, olen[ctxnum] &= 0x0F; 899 (olen[ctxnum]) && (pdulen > 0); 900 --olen[ctxnum], --pdulen, ++effnb) { 901 GETNEXT(ctxnum); 902 rlen = (rlen << 8) | INT(hex); 903 } 904 if (!rlen) { 905 pdulen = 0x7fffffff; 906 } 907 } 908 909 /* 910 * print the tag class and number 911 */ 912 i = otyp[ctxnum]&0x1F; 913 switch (otyp[ctxnum] >> 6) { /* class */ 914 case 0: /* universal */ 915 if (ASNDESC && i != 0) { 916 int dobreak = 0; 917 switch (ASNDESC->type) { 918 case CONTENT: 919 SASNDESC = ASNDESC; 920 break; 921 case SET: 922 for (ai = 0; 923 ai < ASNDESC->nbson && i < 32 && 924 ASNDESC->son[ai].sondef && 925 /* 926 * For this test SEQUENCE & SEQUENCE OF 927 * are same, so suppress the last bit 928 */ 929 (ASNDESC->son[ai].sondef 930 ->type&0xFE) 931 != mytype[i]; ++ai); 932 if (ai < ASNDESC->nbson) { 933 SASNDESC = 934 ASNDESC->son[ai].sondef; 935 if (ASNDESC->son[ai].sonname != NULL) { 936 937 if (ASNDESC->son[ai].sondef != NULL && 938 ASNDESC->son[ai].sondef->name != 939 NULL) { 940 asnshw2("%s ", "LDAP:"); 941 asnshw4(" %c[%s %s]", 942 ((otyp[ctxnum]&0x20)?'*':' '), 943 ASNDESC->son[ai].sonname, 944 ASNDESC->son[ai].sondef->name); 945 } else { 946 asnshw2("%s ", ""); 947 asnshw3(" %c[%s]", 948 ((otyp[ctxnum]&0x20)?'*':' '), 949 ASNDESC->son[ai].sonname); 950 } /* end if */ 951 952 dobreak = 1; 953 954 } else if (ASNDESC->son[ai].sondef != 955 NULL && 956 ASNDESC->son[ai].sondef->name != 957 NULL) { 958 asnshw2("%s ", "LDAP:"); 959 asnshw3(" %c[%s]", 960 ((otyp[ctxnum]&0x20)?'*':' '), 961 ASNDESC->son[ai].sondef->name); 962 dobreak = 1; 963 } /* end if */ 964 } /* end if */ 965 break; 966 case CHOICE: 967 if (GR_TMPDESC) { 968 ASNDESC = TMPDESC; 969 TMPDESC = GR_TMPDESC; 970 GR_TMPDESC = 0; 971 } else if (TMPDESC) { 972 ASNDESC = TMPDESC; 973 TMPDESC = 0; 974 } 975 if (gr_tmpai) { 976 ai = tmpai; 977 tmpai = gr_tmpai; 978 gr_tmpai = 0; 979 } else if (tmpai) { 980 ai = tmpai; 981 tmpai = 0; 982 } 983 break; 984 985 case SEQUENCE: 986 if (ai == -2) { 987 ai = 0; 988 } else { 989 do { 990 ai++; 991 } while \ 992 (ai < ASNDESC->nbson && i < 32 && mytype[i] && \ 993 ASNDESC->son[ai].sondef && 994 /* 995 * For this test SEQUENCE & SEQUENCE OF 996 * are the same, so suppress last bit 997 */ 998 (ASNDESC->son[ai].sondef->type&0xFE) != mytype[i]); 999 } /* end if */ 1000 if (ai < ASNDESC->nbson) { 1001 SASNDESC = \ 1002 ASNDESC->son[ai].sondef; 1003 if (ASNDESC->son[ai].sonname) { 1004 if \ 1005 (ASNDESC->son[ai].sondef && 1006 ASNDESC->son[ai].sondef->name) { 1007 asnshw4 \ 1008 (" %c[%s %s]", ((otyp[ctxnum]&0x20)?'*':' '), 1009 ASNDESC->son[ai].sonname, 1010 ASNDESC->son[ai].sondef->name); 1011 } else { 1012 asnshw3 \ 1013 (" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '), 1014 ASNDESC->son[ai].sonname); 1015 } /* end if */ 1016 dobreak = 1; 1017 } else if \ 1018 (ASNDESC->son[ai].sondef && 1019 ASNDESC->son[ai].sondef->name) { 1020 asnshw3 \ 1021 (" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '), 1022 ASNDESC->son[ai].sondef->name); 1023 dobreak = 1; 1024 } /* end if */ 1025 } /* end if */ 1026 break; 1027 case SEQUENCEOF: 1028 ai = 0; 1029 SASNDESC = ASNDESC->son[ai].sondef; 1030 if (ASNDESC->son[ai].sonname) { 1031 if (ASNDESC->son[ai].sondef && \ 1032 ASNDESC->son[ai].sondef->name) { 1033 asnshw4 \ 1034 (" %c[%s %s]", ((otyp[ctxnum]&0x20)?'*':' '), 1035 ASNDESC->son[ai].sonname, 1036 ASNDESC->son[ai].sondef->name); 1037 } else { 1038 asnshw3 \ 1039 (" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '), 1040 ASNDESC->son[ai].sonname); 1041 } /* end if */ 1042 dobreak = 1; 1043 } else if \ 1044 (ASNDESC->son[ai].sondef && 1045 ASNDESC->son[ai].sondef->name) { 1046 asnshw3 \ 1047 (" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '), 1048 ASNDESC->son[ai].sondef->name); 1049 dobreak = 1; 1050 } /* end if */ 1051 } /* end switch */ 1052 if (dobreak) { 1053 break; 1054 } /* end if */ 1055 } /* end if */ 1056 if (uclass[i]) { 1057 asnshw3 \ 1058 (" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '), uclass[i]); 1059 } else { 1060 asnshw4 \ 1061 (" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '), 1062 class[0], i); 1063 } 1064 break; 1065 case 1: /* application */ 1066 1067 if (ASNDESC) { 1068 1069 for (ai = 0; ai < ASNDESC->nbson; ++ai) { 1070 int i2 = 0; 1071 1072 if \ 1073 (ASNDESC->son[ai].sondef && 1074 ASNDESC->son[ai].sondef->type == CHOICE) { 1075 while \ 1076 (i2 < ASNDESC->son[ai].sondef->nbson && 1077 ASNDESC->son[ai].sondef->son[i2].sondef && \ 1078 ASNDESC->son[ai].sondef->son[i2].sondef->application != i) { 1079 i2++; 1080 continue; 1081 } 1082 if \ 1083 (i2 == ASNDESC->son[ai].sondef->nbson) { 1084 ai = ASNDESC->nbson; 1085 break; 1086 } 1087 if (TMPDESC) { 1088 GR_TMPDESC = TMPDESC; 1089 gr_tmpai = tmpai; 1090 } 1091 TMPDESC = ASNDESC; 1092 ASNDESC = ASNDESC->son[ai].sondef; 1093 tmpai = ai; 1094 ai = i2; 1095 } 1096 1097 if (ASNDESC->son[ai].sondef && \ 1098 ASNDESC->son[ai].sondef->application == i) { 1099 SASNDESC = \ 1100 ASNDESC->son[ai].sondef; 1101 if (ASNDESC->son[ai].sonname) { 1102 if \ 1103 (ASNDESC->son[ai].sondef->name) { 1104 asnshw3 \ 1105 (" %s %s", ASNDESC->son[ai].sonname, 1106 ASNDESC->son[ai].sondef->name); 1107 } else { 1108 asnshw2 \ 1109 (" %s", ASNDESC->son[ai].sonname); 1110 } /* end if */ 1111 } else if \ 1112 (ASNDESC->son[ai].sondef->name) { 1113 asnshw2 \ 1114 (" %s", ASNDESC->son[ai].sondef->name); 1115 } /* end if */ 1116 break; 1117 } /* end if */ 1118 } /* end for */ 1119 if (ai >= ASNDESC->nbson) { 1120 ai = -1; /* not found */ 1121 } /* end if */ 1122 } /* end if */ 1123 if (PTRaclass[i]) { 1124 asnshw5 \ 1125 (" %c[%s%d: %s]", ((otyp[ctxnum]&0x20)?'*':' '), 1126 class[1], i, PTRaclass[i]); 1127 (void) strcpy(operation, (char *)PTRaclass[i]); 1128 } else { 1129 asnshw4 \ 1130 (" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '), \ 1131 class[1], i); 1132 } 1133 break; 1134 1135 case 2: /* context-specific */ 1136 1137 if (TMPDESC) { 1138 ASNDESC = TMPDESC; 1139 TMPDESC = GR_TMPDESC; 1140 already = 1; 1141 } 1142 if (ASNDESC) { 1143 1144 for (ai = 0; ai < ASNDESC->nbson; ++ai) { 1145 if \ 1146 (!already && ASNDESC->son[ai].sondef && 1147 ASNDESC->son[ai].sondef->type == CHOICE) { 1148 int i2 = 0; 1149 while \ 1150 (i2 < ASNDESC->son[ai].sondef->nbson && 1151 ASNDESC->son[ai].sondef->son[i2].tag != i) { 1152 i2++; 1153 continue; 1154 } 1155 if (i2 == \ 1156 ASNDESC->son[ai].sondef->nbson) { 1157 ai = ASNDESC->nbson; 1158 break; 1159 } 1160 if (TMPDESC) { 1161 GR_TMPDESC = TMPDESC; 1162 gr_tmpai = tmpai; 1163 } 1164 TMPDESC = ASNDESC; 1165 ASNDESC = \ 1166 ASNDESC->son[ai].sondef; 1167 tmpai = ai; 1168 ai = i2; 1169 } 1170 1171 if \ 1172 (ASNDESC->son[ai].tag == i) { 1173 SASNDESC = \ 1174 ASNDESC->son[ai].sondef; 1175 if (ASNDESC->son[ai].sonname) { 1176 if \ 1177 (ASNDESC->son[ai].sondef && 1178 ASNDESC->son[ai].sondef->name) { 1179 asnshw3 \ 1180 (" %s %s", ASNDESC->son[ai].sonname, 1181 ASNDESC->son[ai].sondef->name); 1182 } else { 1183 asnshw2 \ 1184 (" %s", ASNDESC->son[ai].sonname); 1185 } /* end if */ 1186 } else if \ 1187 (ASNDESC->son[ai].sondef && 1188 ASNDESC->son[ai].sondef->name) { 1189 asnshw2 \ 1190 (" %s", ASNDESC->son[ai].sondef->name); 1191 } /* end if */ 1192 break; 1193 } /* end if */ 1194 } /* end for */ 1195 if (ai >= ASNDESC->nbson) { 1196 ai = -1; /* not found */ 1197 } /* end if */ 1198 } /* end if */ 1199 asnshw3 \ 1200 (" %c[%d]", ((otyp[ctxnum]&0x20)?'*':' '), i); 1201 break; 1202 1203 case 3: /* private */ 1204 asnshw4 \ 1205 (" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '), \ 1206 class[3], i); 1207 } /* esac: tag */ 1208 1209 /* 1210 * print the length - as a debug tool only. 1211 */ 1212 /* asnshw2(" Length=%d ",rlen); */ 1213 asnshw1("\n"); 1214 if (rlen > pdulen) { 1215 asnshw1("*** Decode length error,"); 1216 asnshw2(" PDU length = %d ***\n", pdulen); 1217 rlen = pdulen; 1218 } 1219 1220 /* 1221 * recursive interpretation of the value if constructor 1222 */ 1223 if (otyp[ctxnum]&0x20) { /* constructor */ 1224 1225 stlv = decpdu((rlen?rlen:pdulen), \ 1226 ASNDESC && ai != -1 ?(ai == -2 ? ASNDESC: 1227 ASNDESC->son[ai].sondef):0, ctxnum); 1228 /* recursive decoding */ 1229 pdulen -= stlv; 1230 effnb += stlv; 1231 } else if (otyp[ctxnum] == 0x06) { 1232 /* 1233 * interpretation of the object identifier 1234 */ 1235 for (j = 0; (rlen) && (pdulen > 0); \ 1236 --rlen, --pdulen, ++effnb) { 1237 GETNEXT(ctxnum); 1238 oidstr[j++] = hex; 1239 } 1240 1241 /* interpret the object identifier */ 1242 oidstr[j++] = '\0'; 1243 oix = oidmap(oidstr, j-1); 1244 asnshw1("\n"); 1245 if (oix >= 0 && oix < OIDNB) { /* recognized obj id */ 1246 asnshw2("%s\n", OidTab[oix].oidname); 1247 } else { 1248 asnshw1("Unknown Oid\n"); 1249 } 1250 } else { 1251 /* 1252 * interpretation of other primitive tags 1253 */ 1254 if (!otyp[ctxnum] && !rlen) { 1255 /* end of contents: any form length */ 1256 pdulen = 0; 1257 } else { 1258 X hexstr[5]; 1259 int k = 0; 1260 int klen = rlen; 1261 if (SASNDESC && SASNDESC->type == CONTENT && \ 1262 SASNDESC->nbson && SASNDESC->son[0].sondef) { 1263 (void) 1264 decpdu(rlen, SASNDESC->son[0].sondef, ctxnum); 1265 } else { 1266 if (rlen < 200) { 1267 for (j = 0, slen = 0; \ 1268 (rlen) && (pdulen > 0); 1269 --rlen, --pdulen, ++effnb) { 1270 if (!slen) { 1271 (void) \ 1272 strcpy((char *)scrlin, "LDAP: "); j += 7; 1273 for \ 1274 (i = 0; i < level[ctxnum]; ++i) { 1275 scrlin[j++] = ' '; 1276 scrlin[j++] = ' '; 1277 scrlin[j++] = ' '; 1278 scrlin[j++] = ' '; 1279 } 1280 } 1281 1282 GETNEXT(ctxnum); 1283 if (k < 5) { 1284 hexstr[k++] = hex; 1285 } /* end if */ 1286 if (!isprint(hex)) { 1287 hex = '_'; 1288 dontprint = 1; 1289 } 1290 scrlin[j++] = hex; 1291 if ((slen += 2) >= \ 1292 (72 - (level[ctxnum] * 3))) { 1293 slen = 0; 1294 scrlin[j] = 0; 1295 if (!dontprint) { 1296 asnshw2 \ 1297 ("%s\n", scrlin); 1298 } 1299 j = 0; 1300 } 1301 } /* rof: primitive values */ 1302 if (slen) { 1303 scrlin[j] = 0; 1304 if (!dontprint) { 1305 asnshw2("%s\n", scrlin); 1306 } 1307 } 1308 dontprint = 0; 1309 } else { 1310 asnshw2("%s ", "LDAP:"); 1311 for (i = 0; i < level[ctxnum]; ++i) { 1312 asnshw1(" "); 1313 scrlin[j++] = ' '; 1314 scrlin[j++] = ' '; 1315 scrlin[j++] = ' '; 1316 } 1317 1318 for (j = 0; (rlen) && (pdulen > 0); \ 1319 --rlen, --pdulen, ++effnb) { 1320 GETNEXT(ctxnum); 1321 if (k < 5) { 1322 hexstr[k++] = hex; 1323 } 1324 } 1325 (void) strcpy \ 1326 ((char *)scrlin, \ 1327 "*** NOT PRINTED - Too long value ***"); 1328 asnshw2("%s\n", scrlin); 1329 } 1330 1331 if \ 1332 (SASNDESC && SASNDESC->type == BITSTRING &&\ 1333 klen <= 5) { 1334 unsigned long bitstr = 0; 1335 for (i = 1; i < 5; ++i) { 1336 bitstr = \ 1337 ((bitstr) << 8) + ((i < klen)?hexstr[i]:0); 1338 } /* end for */ 1339 for \ 1340 (i = 0; i < SASNDESC->nbson; ++i) { 1341 if ((bitstr & \ 1342 ((unsigned long)SASNDESC->son[i].sondef)) == 1343 ((unsigned long)SASNDESC->son[i].tag)) { 1344 if \ 1345 (SASNDESC->son[i].sonname) { 1346 int k; 1347 asnshw2 \ 1348 ("%s ", "LDAP:"); 1349 for \ 1350 (k = 0; k < level[ctxnum]; ++k) { 1351 asnshw1(" "); 1352 } 1353 asnshw2 \ 1354 ("%s", SASNDESC->son[i].sonname); 1355 } /* end if */ 1356 } /* end if */ 1357 } /* end for */ 1358 } /* end if */ 1359 if (SASNDESC && \ 1360 (SASNDESC->type == ENUM || 1361 SASNDESC->type == CONTENTTYPE) && klen <= 5) { 1362 unsigned long value = 0; 1363 for (i = 0; i < klen; ++i) { 1364 value = \ 1365 ((value) << 8) + hexstr[i]; 1366 } /* end for */ 1367 for \ 1368 (i = 0; i < SASNDESC->nbson; ++i) { 1369 if \ 1370 (value == ((unsigned long)SASNDESC->son[i].tag)) { 1371 if \ 1372 (SASNDESC->son[i].sonname) { 1373 int k; 1374 asnshw2 \ 1375 ("%s ", "LDAP:"); 1376 for \ 1377 (k = 0; k < level[ctxnum]; ++k) { 1378 asnshw1(" "); 1379 } 1380 asnshw2 \ 1381 ("%s\n", SASNDESC->son[i].sonname); 1382 (void) \ 1383 strcpy(resultcode, SASNDESC->son[i].sonname); 1384 } /* end if */ 1385 break; 1386 } /* end if */ 1387 } /* end for */ 1388 } /* end if */ 1389 1390 } /* end if */ 1391 } /* fi: constructor/obj-id/primitive */ 1392 } /* fi: tag analysis */ 1393 } /* elihw: len>1 */ 1394 --level[ctxnum]; 1395 return (effnb); 1396 } 1397 1398 1399 /* init_ldap initializes various buffers and variables */ 1400 /* it is called one-time (in snoop_filter.c) only. */ 1401 1402 void 1403 init_ldap() 1404 { 1405 int i; 1406 1407 for (i = 0; i < MAX_CTX; i++) { 1408 gi_osibuf[i] = 0; 1409 level[i] = 0; 1410 } 1411 } 1412 static void 1413 ldapdump(char *data, int datalen) 1414 { 1415 char *p; 1416 ushort_t *p16 = (ushort_t *)data; 1417 char *p8 = data; 1418 int i, left, len; 1419 int chunk = 16; /* 16 bytes per line */ 1420 1421 asnshw1("LDAP: Skipping until next full LDAPMessage\n"); 1422 1423 for (p = data; p < data + datalen; p += chunk) { 1424 asnshw2("LDAP:\t%4d: ", p - data); 1425 left = (data + datalen) - p; 1426 len = MIN(chunk, left); 1427 for (i = 0; i < (len / 2); i++) 1428 asnshw2("%04x ", ntohs(*p16++) & 0xffff); 1429 if (len % 2) { 1430 asnshw2("%02x ", *((unsigned char *)p16)); 1431 } 1432 for (i = 0; i < (chunk - left) / 2; i++) 1433 asnshw1(" "); 1434 1435 asnshw1(" "); 1436 for (i = 0; i < len; i++, p8++) 1437 asnshw2("%c", isprint(*p8) ? *p8 : '.'); 1438 asnshw1("\n"); 1439 } 1440 1441 asnshw1("LDAP:\n"); 1442 } 1443 1444 /* decode_ldap is the entry point for the main decoding function */ 1445 /* decpdu(). decode_ldap() is only called by interpret_ldap. */ 1446 1447 void 1448 decode_ldap(char *buf, int len) 1449 { 1450 asndefTp ASNDESC = 0; 1451 char *newbuf; 1452 int skipped = 0; 1453 1454 PTRaclass = MHSaclass; 1455 ASNDESC = &MPDU; 1456 1457 1458 newbuf = skipjunk(len, buf); 1459 if (newbuf > buf) { 1460 skipped = newbuf-buf; 1461 ldapdump(buf, newbuf-buf); 1462 } 1463 buf = newbuf; 1464 len = len-skipped; 1465 osibuff = buf; /* Undecoded buf is passed by interpret_ldap */ 1466 osilen = len; /* length of tcp data is also passed */ 1467 1468 (void) decpdu(len, ASNDESC, 0); 1469 gi_osibuf[0] = 0; 1470 } 1471