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
interpret_ldap(flags,data,fraglen,src,dst)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
oidmap(A oid,int olg)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 */
getnext(int ctxnum)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 */
skipjunk(len,pdu)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
decpdu(int pdulen,asndefTp ASNDESC,int ctxnum)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
init_ldap()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
ldapdump(char * data,int datalen)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
decode_ldap(char * buf,int len)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