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