package org.freertr.pack; import java.math.BigInteger; import org.freertr.enc.encAsn1; import org.freertr.pipe.pipeSide; /** * lightweight directory access protocol (rfc4511) packet * * @author matecsaba */ public class packLdap { /** * port number */ public final static int port = 389; /** * header size */ public final static int size = 6; /** * bind request */ public final static int tpBindReq = 0; /** * bind reply */ public final static int tpBindRep = 1; /** * unbind request */ public final static int tpUnbind = 2; /** * search request */ public final static int tpFindReq = 3; /** * search entry */ public final static int tpFindNtry = 4; /** * search done */ public final static int tpFindDone = 5; /** * search reference */ public final static int tpFindRef = 6; /** * modify request */ public final static int tpModReq = 7; /** * modify reply */ public final static int tpModRep = 8; /** * add request */ public final static int tpAddReq = 9; /** * add reply */ public final static int tpAddRep = 10; /** * delete request */ public final static int tpDelReq = 11; /** * delete reply */ public final static int tpDelRep = 12; /** * modify dn request */ public final static int tpModnReq = 13; /** * modify dn reply */ public final static int tpModnRep = 14; /** * compare request */ public final static int tpCmpReq = 15; /** * compare reply */ public final static int tpCmpRep = 16; /** * abandom request */ public final static int tpAbdReq = 17; /** * extended request */ public final static int tpExtReq = 18; /** * extended reply */ public final static int tpExtRep = 19; /** * success */ public final static int cdSucc = 0; /** * operation error */ public final static int cdOper = 1; /** * protocol error */ public final static int cdProto = 2; /** * time limit exceeded */ public final static int cdTime = 3; /** * size limit exceeded */ public final static int cdSize = 4; /** * compare false */ public final static int cdCmpF = 5; /** * compare true */ public final static int cdCmpT = 6; /** * unsupported method */ public final static int cdUnsup = 7; /** * weak method */ public final static int cdWeak = 8; /** * referral */ public final static int cdRef = 10; /** * admin limit exceeded */ public final static int cdAdmin = 11; /** * critical extension */ public final static int cdExt = 12; /** * confidentality required */ public final static int cdConf = 13; /** * sasl binding in progress */ public final static int cdSasl = 14; /** * no such attribute */ public final static int cdSuch = 16; /** * undefined attribute */ public final static int cdUndef = 17; /** * inappropirate mathching */ public final static int cdInapr = 18; /** * constraint violation */ public final static int cdConst = 19; /** * attribute exists */ public final static int cdExist = 20; /** * invalid attribute syntax */ public final static int cdSyntx = 21; /** * no such object */ public final static int cdObjN = 32; /** * alias problem */ public final static int cdAlias = 33; /** * invalid dn syntax */ public final static int cdDnSyn = 34; /** * alias dereferencing problem */ public final static int cdDeref = 36; /** * inappropirate authentication */ public final static int cdAuth = 48; /** * invalid credentinals */ public final static int cdCred = 49; /** * insufficient access rights */ public final static int cdRight = 50; /** * busy */ public final static int cdBusy = 51; /** * unavailable */ public final static int cdUnava = 52; /** * unwilling to perform */ public final static int cdUnwil = 53; /** * loop detect */ public final static int cdLoop = 54; /** * naming violation */ public final static int cdNaming = 64; /** * object class violation */ public final static int cdObjV = 65; /** * not allowed on non leaf */ public final static int cdNoLeaf = 66; /** * not allowed on rdn */ public final static int cdNoRdn = 67; /** * entry already exists */ public final static int cdAlredy = 68; /** * object class mods prohibited */ public final static int cdObjP = 69; /** * affect multiple dsa */ public final static int cdMult = 71; /** * current packet */ public packHolder pack; /** * lower pipe */ public pipeSide pipe; /** * message sequence ids */ public int seq; /** * message type */ public int typ; /** * result code */ public int cod; /** * username */ public String usr; /** * password */ public String pwd; /** * create packet holder */ public packLdap() { pack = new packHolder(true, true); } /** * create one header */ public void packSend() { packHolder temp = new packHolder(true, true); encAsn1.writeBigInt(temp, new BigInteger("" + seq)); encAsn1 a = new encAsn1(); a.putEoc(pack); a.tag = typ; a.cls = 1; a.tagWrite(temp); temp.merge2end(); pack.clear(); encAsn1.writeSequence(pack, temp); pack.merge2beg(); pack.pipeSend(pipe, 0, pack.dataSize(), 3); } /** * parse one header * * @return false on success, true on error */ public boolean packRecv() { typ = -1; pack.clear(); if (pack.pipeRecv(pipe, 0, size, 144) != size) { pipe.setClose(); return true; } typ = pack.getByte(0); // type if (typ != 0x30) { return true; } typ = pack.getByte(1); // length seq = 2; if (typ >= 0x80) { seq += (typ & 0x7f); switch (seq) { case 3: typ = pack.getByte(2); break; case 4: typ = pack.msbGetW(2); break; case 5: typ = pack.msbGetD(2) >>> 8; break; case 6: typ = pack.msbGetD(2); break; default: return true; } } seq += typ; seq -= size; if (pack.pipeRecv(pipe, size, seq, 144) != seq) { pipe.setClose(); typ = -1; return true; } encAsn1 a = new encAsn1(); if (a.tagRead(pack)) { return true; } if ((!a.cnst) || (a.tag != encAsn1.tagSequence)) { return true; } packHolder temp = a.getPack(); BigInteger num = encAsn1.readBigInt(temp); if (num == null) { return true; } seq = num.intValue(); if (a.tagRead(temp)) { return true; } if (!a.cnst) { return true; } typ = a.tag; pack = a.getPack(); return false; } /** * dump this packet * * @return string */ public String dump() { return "typ=" + typ + " seq=" + seq + " cod=" + cod + " usr=" + usr + " pwd=" + pwd; } /** * create bind request */ public void createBindReq() { pack.clear(); encAsn1.writeBigInt(pack, new BigInteger("3")); packHolder temp = new packHolder(true, true); temp.clear(); byte[] buf = usr.getBytes(); temp.putCopy(buf, 0, 0, buf.length); temp.putSkip(buf.length); encAsn1.writeOctString(pack, temp); temp.clear(); buf = pwd.getBytes(); temp.putCopy(buf, 0, 0, buf.length); temp.putSkip(buf.length); encAsn1 a = new encAsn1(); a.putEoc(temp); a.cnst = false; a.tagWrite(pack); pack.merge2end(); typ = tpBindReq; } /** * parse bind request * * @return true on error, false on success */ public boolean parseBindReq() { if (typ != tpBindReq) { return true; } BigInteger num = encAsn1.readBigInt(pack); if (num == null) { return true; } if (num.intValue() != 3) { return true; } encAsn1 a = new encAsn1(); if (a.tagRead(pack)) { return true; } if (a.cnst || (a.tag != encAsn1.tagOctetString)) { return true; } usr = new String(a.buf); if (a.tagRead(pack)) { return true; } if (a.cnst || (a.tag != encAsn1.tagEoc)) { return true; } pwd = new String(a.buf); return false; } /** * create bind request */ public void createBindRep() { pack.clear(); encAsn1 a = new encAsn1(); a.putBigInt(new BigInteger("" + cod)); a.tag = encAsn1.tagEnumerated; a.tagWrite(pack); a.buf = usr.getBytes(); a.cls = 0; a.cnst = false; a.tag = encAsn1.tagOctetString; a.tagWrite(pack); a.buf = pwd.getBytes(); a.tagWrite(pack); typ = tpBindRep; } /** * parse bind reply * * @return true on error, false on success */ public boolean parseBindRep() { cod = -1; if (typ != tpBindRep) { return true; } encAsn1 a = new encAsn1(); if (a.tagRead(pack)) { return true; } if (a.cnst || (a.tag != encAsn1.tagEnumerated)) { return true; } BigInteger num = a.getBigInt(); if (num == null) { return true; } cod = num.intValue(); return false; } }