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