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