#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/udp.h>
#include "snoop.h"
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
extern char *src_name;
extern char *dst_name;
#define MAX_CTX (10)
#define LINE_LEN (255)
#define BUF_SIZE (16000)
static int ldap = 0;
struct ctx {
int src;
int dst;
char *src_name;
char *dst_name;
};
char *osibuff = NULL;
int osilen = 0;
char scrbuffer[BUF_SIZE];
char resultcode[LINE_LEN];
char operation[LINE_LEN];
char bb[LINE_LEN];
int gi_osibuf[MAX_CTX];
int otyp[MAX_CTX];
int olen[MAX_CTX];
int level[MAX_CTX];
void decode_ldap(char *buf, int len);
#define X unsigned char
typedef X * A;
#define INT(a) ((int)(a))
#define SCRUB (void) strcat(scrbuffer, bb);
static X hex;
static A *PTRaclass;
#define asnshw1(a) {(void)sprintf(bb, a); SCRUB }
#define asnshw2(a, b) {(void)sprintf(bb, a, b); SCRUB }
#define asnshw3(a, b, c) {(void)sprintf(bb, a, b, c); SCRUB }
#define asnshw4(a, b, c, d) {(void)sprintf(bb, a, b, c, d); SCRUB }
#define asnshw5(a, b, c, d, e) {(void)sprintf(bb, a, b, c, d, e); SCRUB }
typedef struct {
A oidname;
X oidcode[16];
} oidelmT;
typedef oidelmT *oidelmTp;
void
interpret_ldap(flags, data, fraglen, src, dst)
int flags;
char *data;
int fraglen;
int src;
int dst;
{
if (!ldap) {
init_ldap();
ldap = 1;
}
(void) decode_ldap(data, fraglen);
if (flags & F_DTAIL) {
show_header("LDAP: ",
"Lightweight Directory Access Protocol Header", fraglen);
show_space();
printf("%s", scrbuffer);
}
if (flags & F_SUM) {
(void) strcpy(data, "");
if (strlen(operation) != 0) {
(void) strcat(data, " ");
(void) strncat(data, operation, 30);
(void) strcpy(operation, "");
}
if (strlen(resultcode) != 0) {
(void) strcat(data, " ");
(void) strncat(data, resultcode, 30);
(void) strcpy(resultcode, "");
}
if (dst == 389) {
(void) sprintf(get_sum_line(),
"LDAP C port=%d%s", src, data);
}
if (src == 389) {
(void) sprintf(get_sum_line(),
"LDAP R port=%d%s", dst, data);
}
}
(void) strcpy(scrbuffer, "");
}
static oidelmT OidTab[] = {
{(A)"ObjectClass", { 0x03, 0x55, 0x04, 0x00 }},
{(A)"AliasObjectName", { 0x03, 0x55, 0x04, 0x01 }},
{(A)"KnowledgeInfo", { 0x03, 0x55, 0x04, 0x02 }},
{(A)"CommonName", { 0x03, 0x55, 0x04, 0x03 }},
{(A)"Surname", { 0x03, 0x55, 0x04, 0x04 }},
{(A)"SerialNumber", { 0x03, 0x55, 0x04, 0x05 }},
{(A)"CountryName", { 0x03, 0x55, 0x04, 0x06 }},
{(A)"LocalityName", { 0x03, 0x55, 0x04, 0x07 }},
{(A)"StateOrProvinceName", { 0x03, 0x55, 0x04, 0x08 }},
{(A)"StreetAddress", { 0x03, 0x55, 0x04, 0x09 }},
{(A)"OrganizationName", { 0x03, 0x55, 0x04, 0x0a }},
{(A)"OrganizationUnitName", { 0x03, 0x55, 0x04, 0x0b }},
{(A)"Title", { 0x03, 0x55, 0x04, 0x0c }},
{(A)"Description", { 0x03, 0x55, 0x04, 0x0d }},
{(A)"SearchGuide", { 0x03, 0x55, 0x04, 0x0e }},
{(A)"BusinessCategory", { 0x03, 0x55, 0x04, 0x0f }},
{(A)"PostalAddress", { 0x03, 0x55, 0x04, 0x10 }},
{(A)"PostalCode", { 0x03, 0x55, 0x04, 0x11 }},
{(A)"PostOfficeBox", { 0x03, 0x55, 0x04, 0x12 }},
{(A)"PhysicalDeliveryOffice", { 0x03, 0x55, 0x04, 0x13 }},
{(A)"TelephoneNUmber", { 0x03, 0x55, 0x04, 0x14 }},
{(A)"TelexNumber", { 0x03, 0x55, 0x04, 0x15 }},
{(A)"TeletexTerminalId", { 0x03, 0x55, 0x04, 0x16 }},
{(A)"FaxTelephoneNumber", { 0x03, 0x55, 0x04, 0x17 }},
{(A)"X121Address", { 0x03, 0x55, 0x04, 0x18 }},
{(A)"IsdnAddress", { 0x03, 0x55, 0x04, 0x19 }},
{(A)"RegisteredAddress", { 0x03, 0x55, 0x04, 0x1a }},
{(A)"DestinationIndicator", { 0x03, 0x55, 0x04, 0x1b }},
{(A)"PreferDeliveryMethod", { 0x03, 0x55, 0x04, 0x1c }},
{(A)"PresentationAddress", { 0x03, 0x55, 0x04, 0x1d }},
{(A)"SupportedApplContext", { 0x03, 0x55, 0x04, 0x1e }},
{(A)"Member", { 0x03, 0x55, 0x04, 0x1f }},
{(A)"Owner", { 0x03, 0x55, 0x04, 0x20 }},
{(A)"RoleOccupant", { 0x03, 0x55, 0x04, 0x21 }},
{(A)"SeeAlso", { 0x03, 0x55, 0x04, 0x22 }},
{(A)"Password", { 0x03, 0x55, 0x04, 0x23 }},
{(A)"UserCertificate", { 0x03, 0x55, 0x04, 0x24 }},
{(A)"CaCertificate", { 0x03, 0x55, 0x04, 0x25 }},
{(A)"AuthorityRevList", { 0x03, 0x55, 0x04, 0x26 }},
{(A)"CertificateRevList", { 0x03, 0x55, 0x04, 0x27 }},
{(A)"CrossCertificatePair", { 0x03, 0x55, 0x04, 0x28 }},
{(A)"Top", { 0x03, 0x55, 0x06, 0x00 }},
{(A)"Alias", { 0x03, 0x55, 0x06, 0x01 }},
{(A)"Country", { 0x03, 0x55, 0x06, 0x02 }},
{(A)"Locality", { 0x03, 0x55, 0x06, 0x03 }},
{(A)"Organization", { 0x03, 0x55, 0x06, 0x04 }},
{(A)"OrganizationUnit", { 0x03, 0x55, 0x06, 0x05 }},
{(A)"Person", { 0x03, 0x55, 0x06, 0x06 }},
{(A)"OrganizationPersion", { 0x03, 0x55, 0x06, 0x07 }},
{(A)"OrganizationRole", { 0x03, 0x55, 0x06, 0x08 }},
{(A)"Group", { 0x03, 0x55, 0x06, 0x09 }},
{(A)"ResidentialPerson", { 0x03, 0x55, 0x06, 0x0A }},
{(A)"ApplicationProcess", { 0x03, 0x55, 0x06, 0x0B }},
{(A)"ApplicationEntity", { 0x03, 0x55, 0x06, 0x0C }},
{(A)"Dsa", { 0x03, 0x55, 0x06, 0x0D }},
{(A)"Device", { 0x03, 0x55, 0x06, 0x0E }},
{(A)"StrongAuthenticUser", { 0x03, 0x55, 0x06, 0x0F }},
{(A)"CaAuthority", { 0x03, 0x55, 0x06, 0x10 }},
{(A)"Asn1BER-TS", { 0x02, 0x51, 0x01 }},
{(A)"Private-TS", { 0x06, 0x2b, 0xce, 0x06, 0x01, 0x04, 0x06 }},
{(A)"ACSE-AS", { 0x04, 0x52, 0x01, 0x00, 0x01 }},
{(A)"DirAccess-AC", { 0x03, 0x55, 0x03, 0x01 }},
{(A)"DirSystem-AC", { 0x03, 0x55, 0x03, 0x02 }},
{(A)"DirAccess-AS", { 0x03, 0x55, 0x09, 0x01 }},
{(A)"DirSystem-AS", { 0x03, 0x55, 0x09, 0x02 }},
};
#define OIDNB (sizeof (OidTab) / sizeof (oidelmT))
static A class[] = {
(A)"UNIV ",
(A)"APPL ",
(A)"CTXs ",
(A)"PRIV "
};
static A uclass[] = {
(A)"EndOfContents",
(A)"Boolean",
(A)"Integer",
(A)"BitString",
(A)"OctetString",
(A)"Null",
(A)"Oid",
(A)"ObjDescriptor",
(A)"External",
(A)"Real",
(A)"Enumerated",
(A)"Reserved",
(A)"Reserved",
(A)"Reserved",
(A)"Reserved",
(A)"Reserved",
(A)"Sequence",
(A)"Set",
(A)"NumericString",
(A)"PrintableString",
(A)"T.61String",
(A)"VideotexString",
(A)"IA5String",
(A)"UTCTime",
(A)"GeneralizedTime",
(A)"GraphicString",
(A)"VisibleString",
(A)"GeneralString",
(A)"Reserved",
(A)"Reserved",
(A)"Reserved",
(A)"Reserved"
};
static A MHSaclass[] = {
(A)"Bind Request",
(A)"Bind Response",
(A)"Unbind Request",
(A)"Search Request",
(A)"Search ResEntry",
(A)"Search ResDone",
(A)"Modify Request",
(A)"Modify Response",
(A)"Add Request",
(A)"Add Response",
(A)"Del Request",
(A)"Del Response",
(A)"ModDN Request",
(A)"ModDN Response",
(A)"Compare Request",
(A)"Compare Response",
(A)"Abandon Request",
(A)"",
(A)"",
(A)"Search ResRef",
(A)"",
(A)"",
(A)"",
(A)"Extended Request",
(A)"Extended Response",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)""
};
static A DFTaclass[] = {
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)"",
(A)""
};
typedef struct asndefS {
char *name;
int type;
int application;
int nbson;
struct {
char *sonname;
struct asndefS *sondef;
long tag;
} son[50];
} asndefT, * asndefTp;
#define SEQUENCE 0x0002
#define SEQUENCEOF 0x0003
#define SET 0x0004
#define PRINTABLE 0x0008
#define ENUM 0x0010
#define BITSTRING 0x0020
#define EXTENSION 0x0040
#define CONTENTTYPE 0x0080
#define CONTENT 0x0100
#define CHOICE 0x0200
static asndefT RTSpasswd = { "RTS Authentification data", SET, -1, 2, {
{"MTA Name", 0, 0},
{"MTA Password", 0, 1}}};
static asndefT RTSudata = { "RTS User data", SET, -1, 1, {
{0, &RTSpasswd, 1}}};
static asndefT baseObject = {"Base Object", PRINTABLE, -1, 0, {0}};
static asndefT scope = {"Scope", ENUM, -1, 3, {
{"BaseObject", 0, 0},
{"singleLevel", 0, 1},
{"wholeSubtree", 0, 2}}};
static asndefT derefAliases = {"DerefAliases", ENUM, -1, 4, {
{"neverDerefAliases", 0, 0},
{"derefInSearching", 0, 1},
{"derefFindingBaseObj", 0, 2},
{"derefAlways", 0, 3}}};
static asndefT filter;
static asndefT and = {"And", SET, -1, 1, {
{0, &filter, -1}}};
static asndefT or = {"Or", SET, -1, 1, {
{0, &filter, -1}}};
static asndefT not = {"Not", SET, -1, 1, {
{0, &filter, -1}}};
static asndefT equalityMatch = {"Equality Match", SEQUENCE, -1, 2, {
{"Attr Descr", 0, -1},
{"Value", 0, -1}}};
static asndefT substrings = {"Substring", SEQUENCE, -1, 2, {
{"Type", 0, -1},
{"Substrings (initial)", 0, 0},
{"Substrings (any)", 0, 1},
{"Substring (final)", 0, 2}}};
static asndefT greaterOrEqual = {"Greater Or Equal", SEQUENCE, -1, 2, {
{"Attr Descr", 0, -1},
{"Value", 0, -1}}};
static asndefT lessOrEqual = {"Less Or Equal", SEQUENCE, -1, 2, {
{"Attr Descr", 0, -1},
{"Value", 0, -1}}};
static asndefT approxMatch = {"Approx Match", SEQUENCE, -1, 2, {
{"Attr Descr", 0, -1},
{"Value", 0, -1}}};
static asndefT extensibleMatch = {"Extensible Match", SEQUENCE, -1, 4, {
{"MatchingRule", 0, 1},
{"Type", 0, 2},
{"MatchValue", 0, 3},
{"dnAttributes", 0, 4}}};
static asndefT filter = {"Filter", CHOICE, -1, 10, {
{0, &and, 0},
{0, &or, 1},
{0, ¬, 2},
{0, &equalityMatch, 3},
{0, &substrings, 4},
{0, &greaterOrEqual, 5},
{0, &lessOrEqual, 6},
{"Filter: Present", 0, 7},
{0, &approxMatch, 8},
{0, &extensibleMatch, 9}}};
static asndefT attributedescription = \
{"Attribute Description", PRINTABLE, -1, 0, {0}};
static asndefT attributes = {"Attribute List", SEQUENCEOF, -1, 1, {
{0, &attributedescription, -1}}};
static asndefT searchRequest = {"Operation", SEQUENCE, 3, 8, {
{0, &baseObject, -1},
{0, &scope, -1},
{0, &derefAliases, -1},
{"SizeLimit", 0, -1},
{"TimeLimit", 0, -1},
{"TypesOnly", 0, -1},
{0, &filter, -1},
{0, &attributes, -1}}};
static asndefT objectName = {"Object Name", PRINTABLE, -1, 0, {0}};
static asndefT ldapEntry = {"Entry", PRINTABLE, -1, 0, {0}};
static asndefT relativeLdapEntry = \
{"Relative LDAP Entry", PRINTABLE, -1, 0, {0}};
static asndefT newSuperior = {"New Superior", PRINTABLE, -1, 0, {0}};
static asndefT vals = {"Vals", SET, -1, 1, {
{"Value", 0, -1}}};
static asndefT attribute = {"Attribute", SEQUENCE, -1, 2, {
{"Type", 0, -1},
{0, &vals, -1}}};
static asndefT partialAttributes = {"Partial Attributes", SEQUENCEOF, -1, 1, {
{0, &attribute, -1}}};
static asndefT searchResEntry = {"Operation", SEQUENCE, 4, 2, {
{0, &objectName, -1},
{0, &partialAttributes, -1}}};
static asndefT authChoice = {"Authentication Choice", CHOICE, -1, 2, {
{"Authentication: Simple", 0, 0},
{"Authentication: SASL", 0, 3}}};
static asndefT bindRequest = {"Operation", SEQUENCE, 0, 3, {
{"Version", 0, -1},
{0, &objectName, -1},
{0, &authChoice, -1}}};
static asndefT resultCode = {"Result Code", ENUM, -1, 39, {
{"Success", 0, 0},
{"Operation Error", 0, 1},
{"Protocol Error", 0, 2},
{"Time Limit Exceeded", 0, 3},
{"Size Limit Exceeded", 0, 4},
{"Compare False", 0, 5},
{"Compare True", 0, 6},
{"Auth Method Not supported", 0, 7},
{"Strong Auth Required", 0, 8},
{"Referral", 0, 10},
{"Admin Limit Exceeded", 0, 11},
{"Unavailable Critical Extension", 0, 12},
{"Confidentiality required", 0, 13},
{"SASL Bind In Progress", 0, 14},
{"No Such Attribute", 0, 16},
{"Undefined Attribute Type", 0, 17},
{"Inappropriate Matching", 0, 18},
{"Constraint violation", 0, 19},
{"Attribute or Value Exists", 0, 20},
{"Invalid Attribute Syntax", 0, 21},
{"No Such Object", 0, 32},
{"Alias Problem", 0, 33},
{"Invalid DN Syntax", 0, 34},
{"Alias Dereferencing Problem", 0, 36},
{"Inappropriate Authentication", 0, 48},
{"Invalid Credentials", 0, 49},
{"Insufficient Access Rights", 0, 50},
{"Busy", 0, 51},
{"Unavailable", 0, 52},
{"Unwilling To Perform", 0, 53},
{"Loop Detect", 0, 54},
{"Naming Violation", 0, 64},
{"ObjectClass violation", 0, 65},
{"Not Allowed On Non Leaf", 0, 66},
{"Not Allowed On RDN", 0, 67},
{"Entry Already Exists", 0, 68},
{"ObjectClass Mods Prohibited", 0, 69},
{"Affects Multiple DSAs", 0, 71},
{"Other", 0, 80}}};
static asndefT referral = {"Referral", SEQUENCEOF, -1, 1, {
{"LDAP URL", 0, -1}}};
static asndefT ldapResult = {"LDAP Result", SEQUENCE, -1, 4, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3}}};
static asndefT bindResponse = {"Operation", SEQUENCE, 1, 5, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3},
{"SASL Credentials", 0, 7}}};
static asndefT unbindRequest = {"Operation", SEQUENCE, 2, 0, {0}};
static asndefT searchResDone = {"Operation", SEQUENCE, 5, 4, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3}}};
static asndefT seqModOperation = {"Operation", ENUM, -1, 4, {
{"Add", 0, 0},
{"Delete", 0, 1},
{"Replace", 0, 2}}};
static asndefT seqModModification = {"Modification", SEQUENCE, -1, 1, {
{0, &attribute, -1}}};
static asndefT seqModification = {"", SEQUENCE, -1, 2, {
{0, &seqModOperation, -1},
{0, &seqModModification, -1}}};
static asndefT modification = {"Modification", SEQUENCEOF, -1, 1, {
{0, &seqModification, -1}}};
static asndefT modifyRequest = {"Operation", SEQUENCE, 6, 2, {
{0, &objectName, -1},
{0, &modification, -1}}};
static asndefT modifyResponse = {"Operation", SEQUENCE, 7, 4, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3}}};
static asndefT addAttributes = {"Attributes", SEQUENCEOF, -1, 1, {
{0, &attribute, -1}}};
static asndefT addRequest = {"Operation", SEQUENCE, 8, 2, {
{0, &ldapEntry, -1},
{0, &addAttributes, -1}}};
static asndefT addResponse = {"Operation", SEQUENCE, 9, 4, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3}}};
static asndefT delRequest = {"Operation", SEQUENCE, 10, 1, {
{0, &ldapEntry, -1}}};
static asndefT delResponse = {"Operation", SEQUENCE, 11, 4, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3}}};
static asndefT modifyDNRequest = {"Operation", SEQUENCE, 12, 4, {
{0, &ldapEntry, -1},
{0, &relativeLdapEntry, -1},
{"Delete Old RDN", 0, -1},
{0, &newSuperior, 0}}};
static asndefT modifyDNResponse = {"Operation", SEQUENCE, 13, 4, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3}}};
static asndefT ava = {"Ava", SEQUENCE, -1, 2, {
{"Attr Descr", 0, -1},
{"Value", 0, -1}}};
static asndefT compareRequest = {"Operation", SEQUENCE, 14, 2, {
{0, &ldapEntry, -1},
{0, &ava, 0}}};
static asndefT compareResponse = {"Operation", SEQUENCE, 15, 4, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3}}};
static asndefT abandonRequest = {"Operation", SEQUENCE, 16, 1, {
{"Message ID", 0, -1}}};
static asndefT searchResRef = {"Operation", SEQUENCEOF, 19, 1, {
{"LDAP URL", 0, -1}}};
static asndefT extendedRequest = {"Operation", SEQUENCE, 14, 2, {
{"Request Name", 0, 0},
{"Request Value", 0, 1}}};
static asndefT extendedResponse = {"Operation", SEQUENCE, 24, 6, {
{0, &resultCode, -1},
{"Matched DN", 0, -1},
{"Error Message", 0, -1},
{0, &referral, 3},
{"Response Name", 0, 10},
{"Response", 0, 11}}};
static asndefT protocolOp = {"Protocol Op", CHOICE, -1, 20, {
{0, &bindRequest, 0},
{0, &bindResponse, 1},
{0, &unbindRequest, 2},
{0, &searchRequest, 3},
{0, &searchResEntry, 4},
{0, &searchResDone, 5},
{0, &modifyRequest, 6},
{0, &modifyResponse, 7},
{0, &addRequest, 8},
{0, &addResponse, 9},
{0, &delRequest, 10},
{0, &delResponse, 11},
{0, &modifyDNRequest, 12},
{0, &modifyDNResponse, 13},
{0, &compareRequest, 14},
{0, &compareResponse, 15},
{0, &abandonRequest, 16},
{0, &searchResRef, 19},
{0, &extendedRequest, 23},
{0, &extendedResponse, 24}}};
static asndefT control = {"Control", SEQUENCE, -1, 3, {
{"LDAP OID", 0, -1},
{"Criticality", 0, -1},
{"Control value", 0, -1}}};
static asndefT controls = {"Controls List", SEQUENCEOF, -1, 1, {
{0, &control, -1}}};
static asndefT LDAPMessage = { "LDAPMessage", SEQUENCE, -1, 3, {
{"Message ID", 0, -1},
{0, &protocolOp, -1},
{0, &controls, 0}}};
static asndefT MPDU = { "MPDU", SET, -1, 1,
{{0, &LDAPMessage, 0}}};
static int mytype[] = {
0,
0,
0,
BITSTRING,
0,
0,
0,
0,
0,
0,
ENUM,
0,
0,
0,
0,
0,
SEQUENCE,
SET,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
};
static int
oidmap(A oid, int olg)
{
register int ix, goon;
register A oidptr, tabptr, tabend;
for (ix = 0; ix < OIDNB; ix++) {
oidptr = oid; tabptr = (&(OidTab[ix].oidcode[0]));
if (olg == INT(*tabptr++)) {
tabend = tabptr + olg;
goon = 1;
while (goon != 0 && tabptr < tabend) {
if (*tabptr++ != *oidptr++)
goon = 0;
}
if (goon != 0)
return (ix);
}
}
return (OIDNB);
}
static int getnext(int ctxnum)
{
static X c[3];
hex = 0;
if (gi_osibuf[ctxnum] == osilen)
return (-1);
hex = osibuff[gi_osibuf[ctxnum]++];
(void) sprintf((char *)c, "%02x", (hex&0x00FF));
return (0);
}
static char *skipjunk(len, pdu)
int len;
char *pdu;
{
int tag;
char *buf = pdu;
int offset = 0;
while (len > 0) {
if ((len > 5) && (buf[0] == 0x30)) {
tag = buf[1]&0x00ff;
if (tag < 0x80) {
offset = 1;
} else {
offset = 1+ tag&0x007f;
}
if (len - (1+offset) > 0) {
tag = buf[1+offset]&0x00ff;
if (tag == 0x02) {
return (buf);
}
}
}
len --;
buf++;
}
return (buf);
}
#define GETNEXT(a) (void)getnext(a);
static int
decpdu(int pdulen, asndefTp ASNDESC, int ctxnum)
{
X scrlin[99];
X oidstr[80];
int slen;
int stlv;
int oix;
int effnb;
int i = 0, j = 0;
int ai = -2;
asndefTp SASNDESC = 0;
asndefTp TMPDESC = 0;
asndefTp GR_TMPDESC = 0;
int tmpai = 0;
int gr_tmpai = 0;
int dontprint = 0;
int already = 0;
static int rlen = 0;
++level[ctxnum];
effnb = 0;
while (pdulen > 1) {
if (getnext(ctxnum)) {
break;
}
if (strlen(scrbuffer)) asnshw2("%s ", "LDAP:");
for (i = 1; i < level[ctxnum]; ++i) asnshw1(" ");
otyp[ctxnum] = INT(hex);
--pdulen;
++effnb;
GETNEXT(ctxnum);
olen[ctxnum] = INT(hex);
--pdulen;
++effnb;
if (olen[ctxnum] < 128) {
rlen = olen[ctxnum];
} else {
for (rlen = 0, olen[ctxnum] &= 0x0F;
(olen[ctxnum]) && (pdulen > 0);
--olen[ctxnum], --pdulen, ++effnb) {
GETNEXT(ctxnum);
rlen = (rlen << 8) | INT(hex);
}
if (!rlen) {
pdulen = 0x7fffffff;
}
}
i = otyp[ctxnum]&0x1F;
switch (otyp[ctxnum] >> 6) {
case 0:
if (ASNDESC && i != 0) {
int dobreak = 0;
switch (ASNDESC->type) {
case CONTENT:
SASNDESC = ASNDESC;
break;
case SET:
for (ai = 0;
ai < ASNDESC->nbson && i < 32 &&
ASNDESC->son[ai].sondef &&
(ASNDESC->son[ai].sondef
->type&0xFE)
!= mytype[i]; ++ai);
if (ai < ASNDESC->nbson) {
SASNDESC =
ASNDESC->son[ai].sondef;
if (ASNDESC->son[ai].sonname != NULL) {
if (ASNDESC->son[ai].sondef != NULL &&
ASNDESC->son[ai].sondef->name !=
NULL) {
asnshw2("%s ", "LDAP:");
asnshw4(" %c[%s %s]",
((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sonname,
ASNDESC->son[ai].sondef->name);
} else {
asnshw2("%s ", "");
asnshw3(" %c[%s]",
((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sonname);
}
dobreak = 1;
} else if (ASNDESC->son[ai].sondef !=
NULL &&
ASNDESC->son[ai].sondef->name !=
NULL) {
asnshw2("%s ", "LDAP:");
asnshw3(" %c[%s]",
((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sondef->name);
dobreak = 1;
}
}
break;
case CHOICE:
if (GR_TMPDESC) {
ASNDESC = TMPDESC;
TMPDESC = GR_TMPDESC;
GR_TMPDESC = 0;
} else if (TMPDESC) {
ASNDESC = TMPDESC;
TMPDESC = 0;
}
if (gr_tmpai) {
ai = tmpai;
tmpai = gr_tmpai;
gr_tmpai = 0;
} else if (tmpai) {
ai = tmpai;
tmpai = 0;
}
break;
case SEQUENCE:
if (ai == -2) {
ai = 0;
} else {
do {
ai++;
} while \
(ai < ASNDESC->nbson && i < 32 && mytype[i] && \
ASNDESC->son[ai].sondef &&
(ASNDESC->son[ai].sondef->type&0xFE) != mytype[i]);
}
if (ai < ASNDESC->nbson) {
SASNDESC = \
ASNDESC->son[ai].sondef;
if (ASNDESC->son[ai].sonname) {
if \
(ASNDESC->son[ai].sondef &&
ASNDESC->son[ai].sondef->name) {
asnshw4 \
(" %c[%s %s]", ((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sonname,
ASNDESC->son[ai].sondef->name);
} else {
asnshw3 \
(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sonname);
}
dobreak = 1;
} else if \
(ASNDESC->son[ai].sondef &&
ASNDESC->son[ai].sondef->name) {
asnshw3 \
(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sondef->name);
dobreak = 1;
}
}
break;
case SEQUENCEOF:
ai = 0;
SASNDESC = ASNDESC->son[ai].sondef;
if (ASNDESC->son[ai].sonname) {
if (ASNDESC->son[ai].sondef && \
ASNDESC->son[ai].sondef->name) {
asnshw4 \
(" %c[%s %s]", ((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sonname,
ASNDESC->son[ai].sondef->name);
} else {
asnshw3 \
(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sonname);
}
dobreak = 1;
} else if \
(ASNDESC->son[ai].sondef &&
ASNDESC->son[ai].sondef->name) {
asnshw3 \
(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
ASNDESC->son[ai].sondef->name);
dobreak = 1;
}
}
if (dobreak) {
break;
}
}
if (uclass[i]) {
asnshw3 \
(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '), uclass[i]);
} else {
asnshw4 \
(" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '),
class[0], i);
}
break;
case 1:
if (ASNDESC) {
for (ai = 0; ai < ASNDESC->nbson; ++ai) {
int i2 = 0;
if \
(ASNDESC->son[ai].sondef &&
ASNDESC->son[ai].sondef->type == CHOICE) {
while \
(i2 < ASNDESC->son[ai].sondef->nbson &&
ASNDESC->son[ai].sondef->son[i2].sondef && \
ASNDESC->son[ai].sondef->son[i2].sondef->application != i) {
i2++;
continue;
}
if \
(i2 == ASNDESC->son[ai].sondef->nbson) {
ai = ASNDESC->nbson;
break;
}
if (TMPDESC) {
GR_TMPDESC = TMPDESC;
gr_tmpai = tmpai;
}
TMPDESC = ASNDESC;
ASNDESC = ASNDESC->son[ai].sondef;
tmpai = ai;
ai = i2;
}
if (ASNDESC->son[ai].sondef && \
ASNDESC->son[ai].sondef->application == i) {
SASNDESC = \
ASNDESC->son[ai].sondef;
if (ASNDESC->son[ai].sonname) {
if \
(ASNDESC->son[ai].sondef->name) {
asnshw3 \
(" %s %s", ASNDESC->son[ai].sonname,
ASNDESC->son[ai].sondef->name);
} else {
asnshw2 \
(" %s", ASNDESC->son[ai].sonname);
}
} else if \
(ASNDESC->son[ai].sondef->name) {
asnshw2 \
(" %s", ASNDESC->son[ai].sondef->name);
}
break;
}
}
if (ai >= ASNDESC->nbson) {
ai = -1;
}
}
if (PTRaclass[i]) {
asnshw5 \
(" %c[%s%d: %s]", ((otyp[ctxnum]&0x20)?'*':' '),
class[1], i, PTRaclass[i]);
(void) strcpy(operation, (char *)PTRaclass[i]);
} else {
asnshw4 \
(" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '), \
class[1], i);
}
break;
case 2:
if (TMPDESC) {
ASNDESC = TMPDESC;
TMPDESC = GR_TMPDESC;
already = 1;
}
if (ASNDESC) {
for (ai = 0; ai < ASNDESC->nbson; ++ai) {
if \
(!already && ASNDESC->son[ai].sondef &&
ASNDESC->son[ai].sondef->type == CHOICE) {
int i2 = 0;
while \
(i2 < ASNDESC->son[ai].sondef->nbson &&
ASNDESC->son[ai].sondef->son[i2].tag != i) {
i2++;
continue;
}
if (i2 == \
ASNDESC->son[ai].sondef->nbson) {
ai = ASNDESC->nbson;
break;
}
if (TMPDESC) {
GR_TMPDESC = TMPDESC;
gr_tmpai = tmpai;
}
TMPDESC = ASNDESC;
ASNDESC = \
ASNDESC->son[ai].sondef;
tmpai = ai;
ai = i2;
}
if \
(ASNDESC->son[ai].tag == i) {
SASNDESC = \
ASNDESC->son[ai].sondef;
if (ASNDESC->son[ai].sonname) {
if \
(ASNDESC->son[ai].sondef &&
ASNDESC->son[ai].sondef->name) {
asnshw3 \
(" %s %s", ASNDESC->son[ai].sonname,
ASNDESC->son[ai].sondef->name);
} else {
asnshw2 \
(" %s", ASNDESC->son[ai].sonname);
}
} else if \
(ASNDESC->son[ai].sondef &&
ASNDESC->son[ai].sondef->name) {
asnshw2 \
(" %s", ASNDESC->son[ai].sondef->name);
}
break;
}
}
if (ai >= ASNDESC->nbson) {
ai = -1;
}
}
asnshw3 \
(" %c[%d]", ((otyp[ctxnum]&0x20)?'*':' '), i);
break;
case 3:
asnshw4 \
(" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '), \
class[3], i);
}
asnshw1("\n");
if (rlen > pdulen) {
asnshw1("*** Decode length error,");
asnshw2(" PDU length = %d ***\n", pdulen);
rlen = pdulen;
}
if (otyp[ctxnum]&0x20) {
stlv = decpdu((rlen?rlen:pdulen), \
ASNDESC && ai != -1 ?(ai == -2 ? ASNDESC:
ASNDESC->son[ai].sondef):0, ctxnum);
pdulen -= stlv;
effnb += stlv;
} else if (otyp[ctxnum] == 0x06) {
for (j = 0; (rlen) && (pdulen > 0); \
--rlen, --pdulen, ++effnb) {
GETNEXT(ctxnum);
oidstr[j++] = hex;
}
oidstr[j++] = '\0';
oix = oidmap(oidstr, j-1);
asnshw1("\n");
if (oix >= 0 && oix < OIDNB) {
asnshw2("%s\n", OidTab[oix].oidname);
} else {
asnshw1("Unknown Oid\n");
}
} else {
if (!otyp[ctxnum] && !rlen) {
pdulen = 0;
} else {
X hexstr[5];
int k = 0;
int klen = rlen;
if (SASNDESC && SASNDESC->type == CONTENT && \
SASNDESC->nbson && SASNDESC->son[0].sondef) {
(void)
decpdu(rlen, SASNDESC->son[0].sondef, ctxnum);
} else {
if (rlen < 200) {
for (j = 0, slen = 0; \
(rlen) && (pdulen > 0);
--rlen, --pdulen, ++effnb) {
if (!slen) {
(void) \
strcpy((char *)scrlin, "LDAP: "); j += 7;
for \
(i = 0; i < level[ctxnum]; ++i) {
scrlin[j++] = ' ';
scrlin[j++] = ' ';
scrlin[j++] = ' ';
scrlin[j++] = ' ';
}
}
GETNEXT(ctxnum);
if (k < 5) {
hexstr[k++] = hex;
}
if (!isprint(hex)) {
hex = '_';
dontprint = 1;
}
scrlin[j++] = hex;
if ((slen += 2) >= \
(72 - (level[ctxnum] * 3))) {
slen = 0;
scrlin[j] = 0;
if (!dontprint) {
asnshw2 \
("%s\n", scrlin);
}
j = 0;
}
}
if (slen) {
scrlin[j] = 0;
if (!dontprint) {
asnshw2("%s\n", scrlin);
}
}
dontprint = 0;
} else {
asnshw2("%s ", "LDAP:");
for (i = 0; i < level[ctxnum]; ++i) {
asnshw1(" ");
scrlin[j++] = ' ';
scrlin[j++] = ' ';
scrlin[j++] = ' ';
}
for (j = 0; (rlen) && (pdulen > 0); \
--rlen, --pdulen, ++effnb) {
GETNEXT(ctxnum);
if (k < 5) {
hexstr[k++] = hex;
}
}
(void) strcpy \
((char *)scrlin, \
"*** NOT PRINTED - Too long value ***");
asnshw2("%s\n", scrlin);
}
if \
(SASNDESC && SASNDESC->type == BITSTRING &&\
klen <= 5) {
unsigned long bitstr = 0;
for (i = 1; i < 5; ++i) {
bitstr = \
((bitstr) << 8) + ((i < klen)?hexstr[i]:0);
}
for \
(i = 0; i < SASNDESC->nbson; ++i) {
if ((bitstr & \
((unsigned long)SASNDESC->son[i].sondef)) ==
((unsigned long)SASNDESC->son[i].tag)) {
if \
(SASNDESC->son[i].sonname) {
int k;
asnshw2 \
("%s ", "LDAP:");
for \
(k = 0; k < level[ctxnum]; ++k) {
asnshw1(" ");
}
asnshw2 \
("%s", SASNDESC->son[i].sonname);
}
}
}
}
if (SASNDESC && \
(SASNDESC->type == ENUM ||
SASNDESC->type == CONTENTTYPE) && klen <= 5) {
unsigned long value = 0;
for (i = 0; i < klen; ++i) {
value = \
((value) << 8) + hexstr[i];
}
for \
(i = 0; i < SASNDESC->nbson; ++i) {
if \
(value == ((unsigned long)SASNDESC->son[i].tag)) {
if \
(SASNDESC->son[i].sonname) {
int k;
asnshw2 \
("%s ", "LDAP:");
for \
(k = 0; k < level[ctxnum]; ++k) {
asnshw1(" ");
}
asnshw2 \
("%s\n", SASNDESC->son[i].sonname);
(void) \
strcpy(resultcode, SASNDESC->son[i].sonname);
}
break;
}
}
}
}
}
}
}
--level[ctxnum];
return (effnb);
}
void
init_ldap()
{
int i;
for (i = 0; i < MAX_CTX; i++) {
gi_osibuf[i] = 0;
level[i] = 0;
}
}
static void
ldapdump(char *data, int datalen)
{
char *p;
ushort_t *p16 = (ushort_t *)data;
char *p8 = data;
int i, left, len;
int chunk = 16;
asnshw1("LDAP: Skipping until next full LDAPMessage\n");
for (p = data; p < data + datalen; p += chunk) {
asnshw2("LDAP:\t%4d: ", p - data);
left = (data + datalen) - p;
len = MIN(chunk, left);
for (i = 0; i < (len / 2); i++)
asnshw2("%04x ", ntohs(*p16++) & 0xffff);
if (len % 2) {
asnshw2("%02x ", *((unsigned char *)p16));
}
for (i = 0; i < (chunk - left) / 2; i++)
asnshw1(" ");
asnshw1(" ");
for (i = 0; i < len; i++, p8++)
asnshw2("%c", isprint(*p8) ? *p8 : '.');
asnshw1("\n");
}
asnshw1("LDAP:\n");
}
void
decode_ldap(char *buf, int len)
{
asndefTp ASNDESC = 0;
char *newbuf;
int skipped = 0;
PTRaclass = MHSaclass;
ASNDESC = &MPDU;
newbuf = skipjunk(len, buf);
if (newbuf > buf) {
skipped = newbuf-buf;
ldapdump(buf, newbuf-buf);
}
buf = newbuf;
len = len-skipped;
osibuff = buf;
osilen = len;
(void) decpdu(len, ASNDESC, 0);
gi_osibuf[0] = 0;
}