You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/01/12 14:06:35 UTC

[27/50] [abbrv] directory-kerberos git commit: Renaming packages in haox-kerb projects, using "apache"

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/PreauthHandler.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/PreauthHandler.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/PreauthHandler.java
new file mode 100644
index 0000000..2652889
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/PreauthHandler.java
@@ -0,0 +1,230 @@
+package org.apache.kerberos.kerb.client.preauth;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.client.preauth.builtin.EncTsPreauth;
+import org.apache.kerberos.kerb.client.preauth.builtin.TgtPreauth;
+import org.apache.kerberos.kerb.client.preauth.pkinit.PkinitPreauth;
+import org.apache.kerberos.kerb.client.preauth.token.TokenPreauth;
+import org.apache.kerberos.kerb.client.request.KdcRequest;
+import org.apache.kerberos.kerb.codec.KrbCodec;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.EtypeInfo;
+import org.apache.kerberos.kerb.spec.common.EtypeInfo2;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PreauthHandler {
+    private KrbContext krbContext;
+    private List<KrbPreauth> preauths;
+
+    public void init(KrbContext krbContext) {
+        this.krbContext = krbContext;
+        loadPreauthPlugins(krbContext);
+    }
+
+    private void loadPreauthPlugins(KrbContext context) {
+        preauths = new ArrayList<KrbPreauth>();
+
+        KrbPreauth preauth = new EncTsPreauth();
+        preauth.init(context);
+        preauths.add(preauth);
+
+        preauth = new TgtPreauth();
+        preauth.init(context);
+        preauths.add(preauth);
+
+        preauth = new PkinitPreauth();
+        preauth.init(context);
+        preauths.add(preauth);
+
+        preauth = new TokenPreauth();
+        preauth.init(context);
+        preauths.add(preauth);
+    }
+
+    public PreauthContext preparePreauthContext(KdcRequest kdcRequest) {
+        PreauthContext preauthContext = new PreauthContext();
+        preauthContext.setPreauthRequired(krbContext.getConfig().isPreauthRequired());
+        for (KrbPreauth preauth : preauths) {
+            PreauthHandle handle = new PreauthHandle(preauth);
+            handle.initRequestContext(kdcRequest);
+            preauthContext.getHandles().add(handle);
+        }
+
+        return preauthContext;
+    }
+
+    /**
+     * Process preauth inputs and options, prepare and generate pdata to be out
+     */
+    public void preauth(KdcRequest kdcRequest) throws KrbException {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        if (!preauthContext.isPreauthRequired()) {
+            return;
+        }
+
+        if (!preauthContext.hasInputPaData()) {
+            tryFirst(kdcRequest, preauthContext.getOutputPaData());
+            return;
+        }
+
+        attemptETypeInfo(kdcRequest, preauthContext.getInputPaData());
+
+        setPreauthOptions(kdcRequest, kdcRequest.getPreauthOptions());
+
+        prepareUserResponses(kdcRequest, preauthContext.getInputPaData());
+
+        preauthContext.getUserResponser().respondQuestions();
+
+        if (!kdcRequest.isRetrying()) {
+            process(kdcRequest, preauthContext.getInputPaData(),
+                    preauthContext.getOutputPaData());
+        } else {
+            tryAgain(kdcRequest, preauthContext.getInputPaData(),
+                    preauthContext.getOutputPaData());
+        }
+    }
+
+    public void prepareUserResponses(KdcRequest kdcRequest,
+                                     PaData inPadata) throws KrbException {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        for (PaDataEntry pae : inPadata.getElements()) {
+            if (! preauthContext.isPaTypeAllowed(pae.getPaDataType())) {
+                continue;
+            }
+
+            PreauthHandle handle = findHandle(kdcRequest, pae.getPaDataType());
+            if (handle == null) {
+                continue;
+            }
+
+            handle.prepareQuestions(kdcRequest);
+        }
+    }
+
+    public void setPreauthOptions(KdcRequest kdcRequest,
+                                  KrbOptions preauthOptions) throws KrbException {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        for (PreauthHandle handle : preauthContext.getHandles()) {
+            handle.setPreauthOptions(kdcRequest, preauthOptions);
+        }
+    }
+
+    public void tryFirst(KdcRequest kdcRequest,
+                         PaData outPadata) throws KrbException {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        PreauthHandle handle = findHandle(kdcRequest,
+                preauthContext.getAllowedPaType());
+        handle.tryFirst(kdcRequest, outPadata);
+    }
+
+    public void process(KdcRequest kdcRequest,
+                        PaData inPadata, PaData outPadata) throws KrbException {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        /**
+         * Process all informational padata types, then the first real preauth type
+         * we succeed on
+         */
+        for (int real = 0; real <= 1; real ++) {
+            for (PaDataEntry pae : inPadata.getElements()) {
+
+                // Restrict real mechanisms to the chosen one if we have one
+                if (real >0 && !preauthContext.isPaTypeAllowed(pae.getPaDataType())) {
+                    continue;
+                }
+
+                PreauthHandle handle = findHandle(kdcRequest,
+                        preauthContext.getAllowedPaType());
+                if (handle == null) {
+                    continue;
+                }
+
+                // Make sure this type is for the current pass
+                int tmpReal = handle.isReal(pae.getPaDataType()) ? 1 : 0;
+                if (tmpReal != real) {
+                    continue;
+                }
+
+                if (real > 0 && preauthContext.checkAndPutTried(pae.getPaDataType())) {
+                    continue;
+                }
+
+                boolean gotData = handle.process(kdcRequest, pae, outPadata);
+                if (real > 0 && gotData) {
+                    return;
+                }
+            }
+        }
+    }
+
+    public void tryAgain(KdcRequest kdcRequest,
+                         PaData inPadata, PaData outPadata) {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        PreauthHandle handle;
+        for (PaDataEntry pae : inPadata.getElements()) {
+            handle = findHandle(kdcRequest, pae.getPaDataType());
+            if (handle == null) continue;
+
+            boolean gotData = handle.tryAgain(kdcRequest,
+                    pae.getPaDataType(), preauthContext.getErrorPaData(), outPadata);
+        }
+    }
+
+    public void destroy() {
+        for (KrbPreauth preauth : preauths) {
+            preauth.destroy();
+        }
+    }
+
+    private PreauthHandle findHandle(KdcRequest kdcRequest,
+                                     PaDataType paType) {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        for (PreauthHandle handle : preauthContext.getHandles()) {
+            for (PaDataType pt : handle.preauth.getPaTypes()) {
+                if (pt == paType) {
+                    return handle;
+                }
+            }
+        }
+        return null;
+    }
+
+    private void attemptETypeInfo(KdcRequest kdcRequest,
+                                  PaData inPadata) throws KrbException {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        // Find an etype-info2 or etype-info element in padata
+        EtypeInfo etypeInfo = null;
+        EtypeInfo2 etypeInfo2 = null;
+        PaDataEntry pae = inPadata.findEntry(PaDataType.ETYPE_INFO);
+        if (pae != null) {
+            etypeInfo = KrbCodec.decode(pae.getPaDataValue(), EtypeInfo.class);
+        } else {
+            pae = inPadata.findEntry(PaDataType.ETYPE_INFO2);
+            if (pae != null) {
+                etypeInfo2 = KrbCodec.decode(pae.getPaDataValue(), EtypeInfo2.class);
+            }
+        }
+
+        if (etypeInfo == null && etypeInfo2 == null) {
+            attemptSalt(kdcRequest, inPadata);
+        }
+    }
+
+    private void attemptSalt(KdcRequest kdcRequest,
+                                  PaData inPadata) throws KrbException {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponseItem.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponseItem.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponseItem.java
new file mode 100644
index 0000000..47ef365
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponseItem.java
@@ -0,0 +1,12 @@
+package org.apache.kerberos.kerb.client.preauth;
+
+public class UserResponseItem {
+    protected String question;
+    protected String challenge;
+    protected String answer;
+
+    public UserResponseItem(String question, String challenge) {
+        this.question = question;
+        this.challenge = challenge;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponser.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponser.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponser.java
new file mode 100644
index 0000000..df8ba92
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/UserResponser.java
@@ -0,0 +1,58 @@
+package org.apache.kerberos.kerb.client.preauth;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UserResponser {
+
+    private List<UserResponseItem> items = new ArrayList<UserResponseItem>(1);
+
+    /**
+     * Let customize an interface like CMD or WEB UI to selectively respond all the questions
+     */
+    public void respondQuestions() {
+        // TODO
+    }
+
+    public UserResponseItem findQuestion(String question) {
+        for (UserResponseItem ri : items) {
+            if (ri.question.equals(question)) {
+                return ri;
+            }
+        }
+        return null;
+    }
+
+    public void askQuestion(String question, String challenge) {
+        UserResponseItem ri = findQuestion(question);
+        if (ri == null) {
+            items.add(new UserResponseItem(question, challenge));
+        } else {
+            ri.challenge = challenge;
+        }
+    }
+
+    public String getChallenge(String question) {
+        UserResponseItem ri = findQuestion(question);
+        if (ri != null) {
+            return ri.challenge;
+        }
+        return null;
+    }
+
+    public void setAnswer(String question, String answer) {
+        UserResponseItem ri = findQuestion(question);
+        if (ri == null) {
+            throw new IllegalArgumentException("Question isn't exist for the answer");
+        }
+        ri.answer = answer;
+    }
+
+    public String getAnswer(String question) {
+        UserResponseItem ri = findQuestion(question);
+        if (ri != null) {
+            return ri.answer;
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/EncTsPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/EncTsPreauth.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/EncTsPreauth.java
new file mode 100644
index 0000000..8b832c8
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/EncTsPreauth.java
@@ -0,0 +1,75 @@
+package org.apache.kerberos.kerb.client.preauth.builtin;
+
+import org.apache.kerberos.kerb.client.preauth.AbstractPreauthPlugin;
+import org.apache.kerberos.kerb.client.request.KdcRequest;
+import org.apache.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerberos.kerb.preauth.PaFlag;
+import org.apache.kerberos.kerb.preauth.PaFlags;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.builtin.EncTsPreauthMeta;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.EncryptedData;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.kerberos.kerb.spec.pa.PaEncTsEnc;
+
+public class EncTsPreauth extends AbstractPreauthPlugin {
+
+    public EncTsPreauth() {
+        super(new EncTsPreauthMeta());
+    }
+
+    @Override
+    public void prepareQuestions(KdcRequest kdcRequest,
+                                 PluginRequestContext requestContext) throws KrbException {
+
+        kdcRequest.needAsKey();
+    }
+
+    public void tryFirst(KdcRequest kdcRequest,
+                         PluginRequestContext requestContext,
+                         PaData outPadata) throws KrbException {
+
+        if (kdcRequest.getAsKey() == null) {
+            kdcRequest.needAsKey();
+        }
+        outPadata.addElement(makeEntry(kdcRequest));
+    }
+
+    @Override
+    public boolean process(KdcRequest kdcRequest,
+                           PluginRequestContext requestContext,
+                           PaDataEntry inPadata,
+                           PaData outPadata) throws KrbException {
+
+        if (kdcRequest.getAsKey() == null) {
+            kdcRequest.needAsKey();
+        }
+        outPadata.addElement(makeEntry(kdcRequest));
+
+        return true;
+    }
+
+    @Override
+    public PaFlags getFlags(PaDataType paType) {
+        PaFlags paFlags = new PaFlags(0);
+        paFlags.setFlag(PaFlag.PA_REAL);
+
+        return paFlags;
+    }
+
+    private PaDataEntry makeEntry(KdcRequest kdcRequest) throws KrbException {
+        PaEncTsEnc paTs = new PaEncTsEnc();
+        paTs.setPaTimestamp(kdcRequest.getPreauthTime());
+
+        EncryptedData paDataValue = EncryptionUtil.seal(paTs,
+                kdcRequest.getAsKey(), KeyUsage.AS_REQ_PA_ENC_TS);
+        PaDataEntry tsPaEntry = new PaDataEntry();
+        tsPaEntry.setPaDataType(PaDataType.ENC_TIMESTAMP);
+        tsPaEntry.setPaDataValue(paDataValue.encode());
+
+        return tsPaEntry;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/TgtPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/TgtPreauth.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/TgtPreauth.java
new file mode 100644
index 0000000..db26f7d
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/builtin/TgtPreauth.java
@@ -0,0 +1,47 @@
+package org.apache.kerberos.kerb.client.preauth.builtin;
+
+import org.apache.kerberos.kerb.client.preauth.AbstractPreauthPlugin;
+import org.apache.kerberos.kerb.client.request.KdcRequest;
+import org.apache.kerberos.kerb.client.request.TgsRequest;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.builtin.TgtPreauthMeta;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class TgtPreauth extends AbstractPreauthPlugin {
+
+    public TgtPreauth() {
+        super(new TgtPreauthMeta());
+    }
+
+    public void tryFirst(KdcRequest kdcRequest,
+                         PluginRequestContext requestContext,
+                         PaData outPadata) throws KrbException {
+
+        outPadata.addElement(makeEntry(kdcRequest));
+    }
+
+    @Override
+    public boolean process(KdcRequest kdcRequest,
+                        PluginRequestContext requestContext,
+                        PaDataEntry inPadata,
+                        PaData outPadata) throws KrbException {
+
+        outPadata.addElement(makeEntry(kdcRequest));
+
+        return true;
+    }
+
+    private PaDataEntry makeEntry(KdcRequest kdcRequest) throws KrbException {
+
+        TgsRequest tgsRequest = (TgsRequest) kdcRequest;
+
+        PaDataEntry paEntry = new PaDataEntry();
+        paEntry.setPaDataType(PaDataType.TGS_REQ);
+        paEntry.setPaDataValue(tgsRequest.getApReq().encode());
+
+        return paEntry;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitContext.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitContext.java
new file mode 100644
index 0000000..9c373cd
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitContext.java
@@ -0,0 +1,11 @@
+package org.apache.kerberos.kerb.client.preauth.pkinit;
+
+import org.apache.kerberos.kerb.preauth.pkinit.IdentityOpts;
+import org.apache.kerberos.kerb.preauth.pkinit.PluginOpts;
+
+public class PkinitContext {
+
+    public PluginOpts pluginOpts = new PluginOpts();
+    public IdentityOpts identityOpts = new IdentityOpts();
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
new file mode 100644
index 0000000..6a9f856
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
@@ -0,0 +1,214 @@
+package org.apache.kerberos.kerb.client.preauth.pkinit;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.client.preauth.AbstractPreauthPlugin;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.client.request.KdcRequest;
+import org.apache.kerberos.kerb.preauth.PaFlag;
+import org.apache.kerberos.kerb.preauth.PaFlags;
+import org.apache.kerberos.kerb.preauth.pkinit.PkinitIdenity;
+import org.apache.kerberos.kerb.preauth.pkinit.PkinitPreauthMeta;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+import org.apache.kerberos.kerb.spec.common.PrincipalName;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.kerberos.kerb.spec.pa.pkinit.*;
+import org.apache.kerberos.kerb.spec.x509.SubjectPublicKeyInfo;
+
+public class PkinitPreauth extends AbstractPreauthPlugin {
+
+    private PkinitContext pkinitContext;
+
+    public PkinitPreauth() {
+        super(new PkinitPreauthMeta());
+    }
+
+    @Override
+    public void init(KrbContext context) {
+        super.init(context);
+        this.pkinitContext = new PkinitContext();
+    }
+
+    @Override
+    public PluginRequestContext initRequestContext(KdcRequest kdcRequest) {
+        PkinitRequestContext reqCtx = new PkinitRequestContext();
+
+        reqCtx.updateRequestOpts(pkinitContext.pluginOpts);
+
+        return reqCtx;
+    }
+
+    @Override
+    public void setPreauthOptions(KdcRequest kdcRequest,
+                                  PluginRequestContext requestContext,
+                                  KrbOptions options) {
+        if (options.contains(KrbOption.PKINIT_X509_IDENTITY)) {
+            pkinitContext.identityOpts.identity =
+                    options.getStringOption(KrbOption.PKINIT_X509_IDENTITY);
+        }
+
+        if (options.contains(KrbOption.PKINIT_X509_ANCHORS)) {
+            pkinitContext.identityOpts.anchors.add(
+                    options.getStringOption(KrbOption.PKINIT_X509_ANCHORS));
+        }
+
+        if (options.contains(KrbOption.PKINIT_USING_RSA)) {
+            pkinitContext.pluginOpts.usingRsa =
+                    options.getBooleanOption(KrbOption.PKINIT_USING_RSA);
+        }
+
+    }
+
+    @Override
+    public void prepareQuestions(KdcRequest kdcRequest,
+                                 PluginRequestContext requestContext) {
+
+        PkinitRequestContext reqCtx = (PkinitRequestContext) requestContext;
+
+        if (!reqCtx.identityInitialized) {
+            PkinitIdenity.initialize(reqCtx.identityOpts, kdcRequest.getClientPrincipal());
+            reqCtx.identityInitialized = true;
+        }
+
+        // Might have questions asking for password to access the private key
+    }
+
+    public void tryFirst(KdcRequest kdcRequest,
+                         PluginRequestContext requestContext,
+                         PaData outPadata) throws KrbException {
+
+    }
+
+    @Override
+    public boolean process(KdcRequest kdcRequest,
+                        PluginRequestContext requestContext,
+                        PaDataEntry inPadata,
+                        PaData outPadata) throws KrbException {
+
+        PkinitRequestContext reqCtx = (PkinitRequestContext) requestContext;
+        if (inPadata == null) return false;
+
+        boolean processingRequest = false;
+        switch (inPadata.getPaDataType()) {
+            case PK_AS_REQ:
+                processingRequest = true;
+                break;
+            case PK_AS_REP:
+                break;
+        }
+
+        if (processingRequest) {
+            generateRequest(reqCtx, kdcRequest, outPadata);
+        } else {
+            EncryptionType encType = kdcRequest.getEncType();
+            processReply(kdcRequest, reqCtx, inPadata, encType);
+        }
+
+        return false;
+    }
+
+    private void generateRequest(PkinitRequestContext reqCtx, KdcRequest kdcRequest,
+                                 PaData outPadata) {
+
+    }
+
+    private PaPkAsReq makePaPkAsReq(PkinitContext pkinitContext, PkinitRequestContext reqCtx,
+                                    KerberosTime ctime, int cusec, int nonce, byte[] checksum,
+                                    PrincipalName client, PrincipalName server) {
+
+        PaPkAsReq paPkAsReq = new PaPkAsReq();
+        AuthPack authPack = new AuthPack();
+        SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo();
+        PkAuthenticator pkAuthen = new PkAuthenticator();
+
+        boolean usingRsa = reqCtx.requestOpts.usingRsa;
+        PaDataType paType = reqCtx.paType = PaDataType.PK_AS_REQ;
+
+        pkAuthen.setCtime(ctime);
+        pkAuthen.setCusec(cusec);
+        pkAuthen.setNonce(nonce);
+        pkAuthen.setPaChecksum(checksum);
+
+        authPack.setPkAuthenticator(pkAuthen);
+        DHNonce dhNonce = new DHNonce();
+        authPack.setClientDhNonce(dhNonce);
+        authPack.setClientPublicValue(pubInfo);
+
+        authPack.setsupportedCmsTypes(pkinitContext.pluginOpts.createSupportedCMSTypes());
+
+        if (usingRsa) {
+            // DH case
+        } else {
+            authPack.setClientPublicValue(null);
+        }
+
+        byte[] signedAuthPack = signAuthPack(pkinitContext, reqCtx, authPack);
+        paPkAsReq.setSignedAuthPack(signedAuthPack);
+
+        TrustedCertifiers trustedCertifiers = pkinitContext.pluginOpts.createTrustedCertifiers();
+        paPkAsReq.setTrustedCertifiers(trustedCertifiers);
+
+        byte[] kdcPkId = pkinitContext.pluginOpts.createIssuerAndSerial();
+        paPkAsReq.setKdcPkId(kdcPkId);
+
+        return paPkAsReq;
+    }
+
+    private byte[] signAuthPack(PkinitContext pkinitContext,
+                                   PkinitRequestContext reqCtx, AuthPack authPack) {
+        return null;
+    }
+
+    private void processReply(KdcRequest kdcRequest,
+                              PkinitRequestContext reqCtx,
+                              PaDataEntry inPadata,
+                              EncryptionType encType) {
+
+        EncryptionKey asKey = null;
+
+        // TODO
+
+        kdcRequest.setAsKey(asKey);
+    }
+
+    @Override
+    public boolean tryAgain(KdcRequest kdcRequest,
+                         PluginRequestContext requestContext,
+                         PaDataType preauthType,
+                         PaData errPadata,
+                         PaData outPadata) {
+
+        PkinitRequestContext reqCtx = (PkinitRequestContext) requestContext;
+        if (reqCtx.paType != preauthType && errPadata == null) {
+            return false;
+        }
+
+        boolean doAgain = false;
+        for (PaDataEntry pde : errPadata.getElements()) {
+            switch (pde.getPaDataType()) {
+                // TODO
+            }
+        }
+
+        if (doAgain) {
+            generateRequest(reqCtx, kdcRequest, outPadata);
+        }
+
+        return false;
+    }
+
+    @Override
+    public PaFlags getFlags(PaDataType paType) {
+        PaFlags paFlags = new PaFlags(0);
+        paFlags.setFlag(PaFlag.PA_REAL);
+
+        return paFlags;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestContext.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestContext.java
new file mode 100644
index 0000000..ef008cb
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestContext.java
@@ -0,0 +1,25 @@
+package org.apache.kerberos.kerb.client.preauth.pkinit;
+
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.pkinit.IdentityOpts;
+import org.apache.kerberos.kerb.preauth.pkinit.PluginOpts;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class PkinitRequestContext implements PluginRequestContext {
+
+    public PkinitRequestOpts requestOpts = new PkinitRequestOpts();
+    public IdentityOpts identityOpts = new IdentityOpts();
+    public boolean doIdentityMatching;
+    public PaDataType paType;
+    public boolean rfc6112Kdc;
+    public boolean identityInitialized;
+    public boolean identityPrompted;
+    
+    public void updateRequestOpts(PluginOpts pluginOpts) {
+        requestOpts.requireEku = pluginOpts.requireEku;
+        requestOpts.acceptSecondaryEku = pluginOpts.acceptSecondaryEku;
+        requestOpts.allowUpn = pluginOpts.allowUpn;
+        requestOpts.usingRsa = pluginOpts.usingRsa;
+        requestOpts.requireCrlChecking = pluginOpts.requireCrlChecking;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java
new file mode 100644
index 0000000..af31dc4
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/pkinit/PkinitRequestOpts.java
@@ -0,0 +1,21 @@
+package org.apache.kerberos.kerb.client.preauth.pkinit;
+
+public class PkinitRequestOpts {
+
+    // From MIT Krb5 _pkinit_plg_opts
+
+    // require EKU checking (default is true)
+    public boolean requireEku = true;
+    // accept secondary EKU (default is false)
+    public boolean acceptSecondaryEku = false;
+    // allow UPN-SAN instead of pkinit-SAN
+    public boolean allowUpn = true;
+    // selects DH or RSA based pkinit
+    public boolean usingRsa = true;
+    // require CRL for a CA (default is false)
+    public boolean requireCrlChecking = false;
+    // initial request DH modulus size (default=1024)
+    public int dhSize = 1024;
+
+    public boolean requireHostnameMatch = true;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenContext.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenContext.java
new file mode 100644
index 0000000..cb3f3d4
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenContext.java
@@ -0,0 +1,9 @@
+package org.apache.kerberos.kerb.client.preauth.token;
+
+import org.haox.token.KerbToken;
+
+public class TokenContext {
+
+    public boolean usingIdToken = true;
+    public KerbToken token = null;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenPreauth.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenPreauth.java
new file mode 100644
index 0000000..c8613f9
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenPreauth.java
@@ -0,0 +1,105 @@
+package org.apache.kerberos.kerb.client.preauth.token;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.client.preauth.AbstractPreauthPlugin;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.client.request.KdcRequest;
+import org.apache.kerberos.kerb.preauth.PaFlag;
+import org.apache.kerberos.kerb.preauth.PaFlags;
+import org.apache.kerberos.kerb.preauth.token.TokenPreauthMeta;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.haox.token.KerbToken;
+
+import java.util.Collections;
+import java.util.List;
+
+public class TokenPreauth extends AbstractPreauthPlugin {
+
+    private TokenContext tokenContext;
+
+    public TokenPreauth() {
+        super(new TokenPreauthMeta());
+    }
+
+    public void init(KrbContext context) {
+        super.init(context);
+        this.tokenContext = new TokenContext();
+    }
+
+    @Override
+    public PluginRequestContext initRequestContext(KdcRequest kdcRequest) {
+        TokenRequestContext reqCtx = new TokenRequestContext();
+
+        return reqCtx;
+    }
+
+    @Override
+    public void prepareQuestions(KdcRequest kdcRequest,
+                                 PluginRequestContext requestContext) {
+
+    }
+
+    @Override
+    public List<EncryptionType> getEncTypes(KdcRequest kdcRequest,
+                                            PluginRequestContext requestContext) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void setPreauthOptions(KdcRequest kdcRequest,
+                                  PluginRequestContext requestContext,
+                                  KrbOptions options) {
+
+        tokenContext.usingIdToken = options.getBooleanOption(KrbOption.TOKEN_USING_IDTOKEN);
+        if (tokenContext.usingIdToken) {
+            if (options.contains(KrbOption.TOKEN_USER_ID_TOKEN)) {
+                tokenContext.token =
+                        (KerbToken) options.getOptionValue(KrbOption.TOKEN_USER_ID_TOKEN);
+            }
+        } else {
+            if (options.contains(KrbOption.TOKEN_USER_AC_TOKEN)) {
+                tokenContext.token =
+                        (KerbToken) options.getOptionValue(KrbOption.TOKEN_USER_AC_TOKEN);
+            }
+        }
+
+    }
+
+    public void tryFirst(KdcRequest kdcRequest,
+                         PluginRequestContext requestContext,
+                         PaData outPadata) throws KrbException {
+
+    }
+
+    @Override
+    public boolean process(KdcRequest kdcRequest,
+                        PluginRequestContext requestContext,
+                        PaDataEntry inPadata,
+                        PaData outPadata) throws KrbException {
+
+        return false;
+    }
+
+    @Override
+    public boolean tryAgain(KdcRequest kdcRequest,
+                         PluginRequestContext requestContext,
+                         PaDataType preauthType,
+                         PaData errPadata,
+                         PaData outPadata) {
+        return false;
+    }
+
+    @Override
+    public PaFlags getFlags(PaDataType paType) {
+        PaFlags paFlags = new PaFlags(0);
+        paFlags.setFlag(PaFlag.PA_REAL);
+
+        return paFlags;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenRequestContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenRequestContext.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenRequestContext.java
new file mode 100644
index 0000000..a31e3d1
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/preauth/token/TokenRequestContext.java
@@ -0,0 +1,13 @@
+package org.apache.kerberos.kerb.client.preauth.token;
+
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class TokenRequestContext implements PluginRequestContext {
+
+    public boolean doIdentityMatching;
+    public PaDataType paType;
+    public boolean identityInitialized;
+    public boolean identityPrompted;
+    
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequest.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequest.java
new file mode 100644
index 0000000..74b81e6
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequest.java
@@ -0,0 +1,108 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.KrbErrorCode;
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.KrbConstant;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.*;
+import org.apache.kerberos.kerb.spec.kdc.*;
+import org.apache.kerberos.kerb.spec.ticket.TgtTicket;
+
+import java.io.IOException;
+import java.util.List;
+
+public class AsRequest extends KdcRequest {
+
+    private PrincipalName clientPrincipal;
+    private EncryptionKey clientKey;
+
+    public AsRequest(KrbContext context) {
+        super(context);
+
+        setServerPrincipal(makeTgsPrincipal());
+    }
+
+    public PrincipalName getClientPrincipal() {
+        return clientPrincipal;
+    }
+
+    public void setClientPrincipal(PrincipalName clientPrincipal) {
+        this.clientPrincipal = clientPrincipal;
+    }
+
+    public void setClientKey(EncryptionKey clientKey) {
+        this.clientKey = clientKey;
+    }
+
+    public EncryptionKey getClientKey() throws KrbException {
+        return clientKey;
+    }
+
+    @Override
+    public void process() throws KrbException {
+        super.process();
+
+        KdcReqBody body = makeReqBody();
+
+        AsReq asReq = new AsReq();
+        asReq.setReqBody(body);
+        asReq.setPaData(getPreauthContext().getOutputPaData());
+
+        setKdcReq(asReq);
+    }
+
+    @Override
+    public void processResponse(KdcRep kdcRep) throws KrbException  {
+        setKdcRep(kdcRep);
+
+        PrincipalName clientPrincipal = getKdcRep().getCname();
+        String clientRealm = getKdcRep().getCrealm();
+        clientPrincipal.setRealm(clientRealm);
+        if (! clientPrincipal.equals(getClientPrincipal())) {
+            throw new KrbException(KrbErrorCode.KDC_ERR_CLIENT_NAME_MISMATCH);
+        }
+
+        byte[] decryptedData = decryptWithClientKey(getKdcRep().getEncryptedEncPart(),
+                KeyUsage.AS_REP_ENCPART);
+        EncKdcRepPart encKdcRepPart = new EncAsRepPart();
+        try {
+            encKdcRepPart.decode(decryptedData);
+        } catch (IOException e) {
+            throw new KrbException("Failed to decode EncAsRepPart", e);
+        }
+        getKdcRep().setEncPart(encKdcRepPart);
+
+        if (getChosenNonce() != encKdcRepPart.getNonce()) {
+            throw new KrbException("Nonce didn't match");
+        }
+
+        PrincipalName serverPrincipal = encKdcRepPart.getSname();
+        serverPrincipal.setRealm(encKdcRepPart.getSrealm());
+        if (! serverPrincipal.equals(getServerPrincipal())) {
+            throw new KrbException(KrbErrorCode.KDC_ERR_SERVER_NOMATCH);
+        }
+
+        HostAddresses hostAddresses = getHostAddresses();
+        if (hostAddresses != null) {
+            List<HostAddress> requestHosts = hostAddresses.getElements();
+            if (!requestHosts.isEmpty()) {
+                List<HostAddress> responseHosts = encKdcRepPart.getCaddr().getElements();
+                for (HostAddress h : requestHosts) {
+                    if (!responseHosts.contains(h)) {
+                        throw new KrbException("Unexpected client host");
+                    }
+                }
+            }
+        }
+    }
+
+    public TgtTicket getTicket() {
+        TgtTicket TgtTicket = new TgtTicket(getKdcRep().getTicket(),
+                (EncAsRepPart) getKdcRep().getEncPart(), getKdcRep().getCname().getName());
+        return TgtTicket;
+    }
+
+    private PrincipalName makeTgsPrincipal() {
+        return new PrincipalName(KrbConstant.TGS_PRINCIPAL + "@" + getContext().getKdcRealm());
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java
new file mode 100644
index 0000000..c905218
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithCert.java
@@ -0,0 +1,38 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class AsRequestWithCert extends AsRequest {
+
+    public static final String ANONYMOUS_PRINCIPAL = "ANONYMOUS@WELLKNOWN:ANONYMOUS";
+
+    public AsRequestWithCert(KrbContext context) {
+        super(context);
+
+        setAllowedPreauth(PaDataType.PK_AS_REQ);
+    }
+
+    @Override
+    public void process() throws KrbException {
+        throw new RuntimeException("To be implemented");
+    }
+
+    @Override
+    public KrbOptions getPreauthOptions() {
+        KrbOptions results = new KrbOptions();
+
+        KrbOptions krbOptions = getKrbOptions();
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_CERTIFICATE));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_ANCHORS));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_PRIVATE_KEY));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_X509_IDENTITY));
+        results.add(krbOptions.getOption(KrbOption.PKINIT_USING_RSA));
+
+        return results;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java
new file mode 100644
index 0000000..bc9c1ab
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithPasswd.java
@@ -0,0 +1,31 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class AsRequestWithPasswd extends AsRequest {
+
+    public AsRequestWithPasswd(KrbContext context) {
+        super(context);
+
+        setAllowedPreauth(PaDataType.ENC_TIMESTAMP);
+    }
+
+    public String getPassword() {
+        return getKrbOptions().getStringOption(KrbOption.USER_PASSWD);
+    }
+
+    @Override
+    public EncryptionKey getClientKey() throws KrbException {
+        if (super.getClientKey() == null) {
+            EncryptionKey tmpKey = EncryptionHandler.string2Key(getClientPrincipal().getName(),
+                    getPassword(), getChosenEncryptionType());
+            setClientKey(tmpKey);
+        }
+        return super.getClientKey();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java
new file mode 100644
index 0000000..2e792f0
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/AsRequestWithToken.java
@@ -0,0 +1,33 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOption;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class AsRequestWithToken extends AsRequest {
+
+    public AsRequestWithToken(KrbContext context) {
+        super(context);
+
+        setAllowedPreauth(PaDataType.TOKEN_REQUEST);
+    }
+
+    @Override
+    public void process() throws KrbException {
+        throw new RuntimeException("To be implemented");
+    }
+
+    @Override
+    public KrbOptions getPreauthOptions() {
+        KrbOptions results = new KrbOptions();
+
+        KrbOptions krbOptions = getKrbOptions();
+        results.add(krbOptions.getOption(KrbOption.TOKEN_USING_IDTOKEN));
+        results.add(krbOptions.getOption(KrbOption.TOKEN_USER_ID_TOKEN));
+        results.add(krbOptions.getOption(KrbOption.TOKEN_USER_AC_TOKEN));
+
+        return results;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java
new file mode 100644
index 0000000..ac7b732
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/KdcRequest.java
@@ -0,0 +1,339 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.client.KrbOptions;
+import org.apache.kerberos.kerb.client.preauth.FastContext;
+import org.apache.kerberos.kerb.client.preauth.PreauthContext;
+import org.apache.kerberos.kerb.client.preauth.PreauthHandler;
+import org.apache.kerberos.kerb.crypto.EncryptionHandler;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerberos.kerb.spec.common.*;
+import org.apache.kerberos.kerb.spec.kdc.KdcOptions;
+import org.apache.kerberos.kerb.spec.kdc.KdcRep;
+import org.apache.kerberos.kerb.spec.kdc.KdcReq;
+import org.apache.kerberos.kerb.spec.kdc.KdcReqBody;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.haox.transport.Transport;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A wrapper for KdcReq request
+ */
+public abstract class KdcRequest {
+    private KrbContext context;
+    private Transport transport;
+
+    private KrbOptions krbOptions;
+    private PrincipalName serverPrincipal;
+    private List<HostAddress> hostAddresses = new ArrayList<HostAddress>();
+    private KdcOptions kdcOptions = new KdcOptions();
+    private List<EncryptionType> encryptionTypes;
+    private EncryptionType chosenEncryptionType;
+    private int chosenNonce;
+    private KdcReq kdcReq;
+    private KdcRep kdcRep;
+    protected Map<String, Object> credCache;
+    private PreauthContext preauthContext;
+    private FastContext fastContext;
+    private EncryptionKey asKey;
+
+    private KrbError errorReply;
+    private boolean isRetrying;
+
+    public KdcRequest(KrbContext context) {
+        this.context = context;
+        this.isRetrying = false;
+        this.credCache = new HashMap<String, Object>();
+        this.preauthContext = context.getPreauthHandler()
+                .preparePreauthContext(this);
+        this.fastContext = new FastContext();
+    }
+
+    public void setTransport(Transport transport) {
+        this.transport = transport;
+    }
+
+    public Transport getTransport() {
+        return this.transport;
+    }
+
+    public void setKrbOptions(KrbOptions options) {
+        this.krbOptions = options;
+    }
+
+    public KrbOptions getKrbOptions() {
+        return krbOptions;
+    }
+
+    public boolean isRetrying() {
+        return isRetrying;
+    }
+
+    public void setAsKey(EncryptionKey asKey) {
+        this.asKey = asKey;
+    }
+
+    public EncryptionKey getAsKey() throws KrbException {
+        return asKey;
+    }
+
+    public void setAllowedPreauth(PaDataType paType) {
+        preauthContext.setAllowedPaType(paType);
+    }
+
+    public Map<String, Object> getCredCache() {
+        return credCache;
+    }
+
+    public void setPreauthRequired(boolean preauthRequired) {
+        preauthContext.setPreauthRequired(preauthRequired);
+    }
+
+    public PreauthContext getPreauthContext() {
+        return preauthContext;
+    }
+
+    protected void loadCredCache() {
+        // TODO
+    }
+
+    public KdcReq getKdcReq() {
+        return kdcReq;
+    }
+
+    public void setKdcReq(KdcReq kdcReq) {
+        this.kdcReq = kdcReq;
+    }
+
+    public KdcRep getKdcRep() {
+        return kdcRep;
+    }
+
+    public void setKdcRep(KdcRep kdcRep) {
+        this.kdcRep = kdcRep;
+    }
+
+    protected KdcReqBody makeReqBody() throws KrbException {
+        KdcReqBody body = new KdcReqBody();
+
+        long startTime = System.currentTimeMillis();
+        body.setFrom(new KerberosTime(startTime));
+
+        PrincipalName cName = null;
+        cName = getClientPrincipal();
+        body.setCname(cName);
+
+        body.setRealm(cName.getRealm());
+
+        PrincipalName sName = getServerPrincipal();
+        body.setSname(sName);
+
+        body.setTill(new KerberosTime(startTime + getTicketValidTime()));
+
+        int nonce = generateNonce();
+        body.setNonce(nonce);
+        setChosenNonce(nonce);
+
+        body.setKdcOptions(getKdcOptions());
+
+        HostAddresses addresses = getHostAddresses();
+        if (addresses != null) {
+            body.setAddresses(addresses);
+        }
+
+        body.setEtypes(getEncryptionTypes());
+
+        return body;
+    }
+
+    public KdcOptions getKdcOptions() {
+        return kdcOptions;
+    }
+
+    public HostAddresses getHostAddresses() {
+        HostAddresses addresses = null;
+        if (!hostAddresses.isEmpty()) {
+            addresses = new HostAddresses();
+            for(HostAddress ha : hostAddresses) {
+                addresses.addElement(ha);
+            }
+        }
+        return addresses;
+    }
+
+    public KrbContext getContext() {
+        return context;
+    }
+
+    protected byte[] decryptWithClientKey(EncryptedData data, KeyUsage usage) throws KrbException {
+        return EncryptionHandler.decrypt(data, getClientKey(), usage);
+    }
+
+    public void setContext(KrbContext context) {
+        this.context = context;
+    }
+
+    public void setHostAddresses(List<HostAddress> hostAddresses) {
+        this.hostAddresses = hostAddresses;
+    }
+
+    public void setKdcOptions(KdcOptions kdcOptions) {
+        this.kdcOptions = kdcOptions;
+    }
+
+    public abstract PrincipalName getClientPrincipal();
+
+    public PrincipalName getServerPrincipal() {
+        return serverPrincipal;
+    }
+
+    public void setServerPrincipal(PrincipalName serverPrincipal) {
+        this.serverPrincipal = serverPrincipal;
+    }
+
+    public List<EncryptionType> getEncryptionTypes() {
+        if (encryptionTypes == null) {
+            encryptionTypes = context.getConfig().getEncryptionTypes();
+        }
+        return encryptionTypes;
+    }
+
+    public void setEncryptionTypes(List<EncryptionType> encryptionTypes) {
+        this.encryptionTypes = encryptionTypes;
+    }
+
+    public EncryptionType getChosenEncryptionType() {
+        return chosenEncryptionType;
+    }
+
+    public void setChosenEncryptionType(EncryptionType chosenEncryptionType) {
+        this.chosenEncryptionType = chosenEncryptionType;
+    }
+
+    public int generateNonce() {
+        return context.generateNonce();
+    }
+
+    public int getChosenNonce() {
+        return chosenNonce;
+    }
+
+    public void setChosenNonce(int nonce) {
+        this.chosenNonce = nonce;
+    }
+
+    public abstract EncryptionKey getClientKey() throws KrbException;
+
+    public long getTicketValidTime() {
+        return context.getTicketValidTime();
+    }
+
+    public KerberosTime getTicketTillTime() {
+        long now = System.currentTimeMillis();
+        return new KerberosTime(now + KerberosTime.MINUTE * 60 * 1000);
+    }
+
+    public void addHost(String hostNameOrIpAddress) throws UnknownHostException {
+        InetAddress address = InetAddress.getByName(hostNameOrIpAddress);
+        hostAddresses.add(new HostAddress(address));
+    }
+
+    public void process() throws KrbException {
+        preauth();
+    }
+
+    public abstract void processResponse(KdcRep kdcRep) throws KrbException;
+
+    public KrbOptions getPreauthOptions() {
+        return new KrbOptions();
+    }
+
+    protected void preauth() throws KrbException {
+        loadCredCache();
+
+        List<EncryptionType> etypes = getEncryptionTypes();
+        if (etypes.isEmpty()) {
+            throw new KrbException("No encryption type is configured and available");
+        }
+        EncryptionType encryptionType = etypes.iterator().next();
+        setChosenEncryptionType(encryptionType);
+
+        getPreauthHandler().preauth(this);
+    }
+
+    protected PreauthHandler getPreauthHandler() {
+        return getContext().getPreauthHandler();
+    }
+
+    /**
+     * Indicate interest in the AS key.
+     */
+    public void needAsKey() throws KrbException {
+        EncryptionKey clientKey = getClientKey();
+        if (clientKey == null) {
+            throw new RuntimeException("Client key should be prepared or prompted at this time!");
+        }
+        setAsKey(clientKey);
+    }
+
+    /**
+     * Get the enctype expected to be used to encrypt the encrypted portion of
+     * the AS_REP packet.  When handling a PREAUTH_REQUIRED error, this
+     * typically comes from etype-info2.  When handling an AS reply, it is
+     * initialized from the AS reply itself.
+     */
+    public EncryptionType getEncType() {
+
+        return getChosenEncryptionType();
+    }
+
+    public void askQuestion(String question, String challenge) {
+        preauthContext.getUserResponser().askQuestion(question, challenge);
+    }
+
+    /**
+     * Get a pointer to the FAST armor key, or NULL if the client is not using FAST.
+     */
+    public EncryptionKey getArmorKey() {
+        return fastContext.armorKey;
+    }
+
+    /**
+     * Get the current time for use in a preauth response.  If
+     * allow_unauth_time is true and the library has been configured to allow
+     * it, the current time will be offset using unauthenticated timestamp
+     * information received from the KDC in the preauth-required error, if one
+     * has been received.  Otherwise, the timestamp in a preauth-required error
+     * will only be used if it is protected by a FAST channel.  Only set
+     * allow_unauth_time if using an unauthenticated time offset would not
+     * create a security issue.
+     */
+    public KerberosTime getPreauthTime() {
+        return KerberosTime.now();
+    }
+
+    /**
+     * Get a state item from an input ccache, which may allow it
+     * to retrace the steps it took last time.  The returned data string is an
+     * alias and should not be freed.
+     */
+    public Object getCacheValue(String key) {
+        return credCache.get(key);
+    }
+
+    /**
+     * Set a state item which will be recorded to an output
+     * ccache, if the calling application supplied one.  Both key and data
+     * should be valid UTF-8 text.
+     */
+    public void cacheValue(String key, Object value) {
+        credCache.put(key, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java
new file mode 100644
index 0000000..60c3ad3
--- /dev/null
+++ b/haox-kerb/kerb-client/src/main/java/org/apache/kerberos/kerb/client/request/TgsRequest.java
@@ -0,0 +1,117 @@
+package org.apache.kerberos.kerb.client.request;
+
+import org.apache.kerberos.kerb.client.KrbContext;
+import org.apache.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerberos.kerb.spec.ap.ApOptions;
+import org.apache.kerberos.kerb.spec.ap.ApReq;
+import org.apache.kerberos.kerb.spec.ap.Authenticator;
+import org.apache.kerberos.kerb.spec.common.EncryptedData;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+import org.apache.kerberos.kerb.spec.common.PrincipalName;
+import org.apache.kerberos.kerb.spec.kdc.*;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerberos.kerb.spec.ticket.TgtTicket;
+
+public class TgsRequest extends KdcRequest {
+    private TgtTicket tgt;
+    private ApReq apReq;
+
+    public TgsRequest(KrbContext context, TgtTicket tgtTicket) {
+        super(context);
+        this.tgt = tgtTicket;
+
+        setAllowedPreauth(PaDataType.TGS_REQ);
+    }
+
+    public PrincipalName getClientPrincipal() {
+        return tgt.getClientPrincipal();
+    }
+
+    @Override
+    public EncryptionKey getClientKey() throws KrbException {
+        return getSessionKey();
+    }
+
+    public EncryptionKey getSessionKey() {
+        return tgt.getSessionKey();
+    }
+
+    @Override
+    protected void preauth() throws KrbException {
+        apReq = makeApReq();
+        super.preauth();
+    }
+
+    @Override
+    public void process() throws KrbException {
+        super.process();
+
+        TgsReq tgsReq = new TgsReq();
+
+        KdcReqBody tgsReqBody = makeReqBody();
+        tgsReq.setReqBody(tgsReqBody);
+        tgsReq.setPaData(getPreauthContext().getOutputPaData());
+
+        setKdcReq(tgsReq);
+    }
+
+    private ApReq makeApReq() throws KrbException {
+        ApReq apReq = new ApReq();
+
+        Authenticator authenticator = makeAuthenticator();
+        EncryptionKey sessionKey = tgt.getSessionKey();
+        EncryptedData authnData = EncryptionUtil.seal(authenticator,
+                sessionKey, KeyUsage.TGS_REQ_AUTH);
+        apReq.setEncryptedAuthenticator(authnData);
+
+        apReq.setTicket(tgt.getTicket());
+        ApOptions apOptions = new ApOptions();
+        apReq.setApOptions(apOptions);
+
+        return apReq;
+    }
+
+    private Authenticator makeAuthenticator() {
+        Authenticator authenticator = new Authenticator();
+        authenticator.setCname(getClientPrincipal());
+        authenticator.setCrealm(tgt.getRealm());
+
+        authenticator.setCtime(KerberosTime.now());
+        authenticator.setCusec(0);
+
+        EncryptionKey sessionKey = tgt.getSessionKey();
+        authenticator.setSubKey(sessionKey);
+
+        return authenticator;
+    }
+
+    @Override
+    public void processResponse(KdcRep kdcRep) throws KrbException {
+        setKdcRep(kdcRep);
+
+        TgsRep tgsRep = (TgsRep) getKdcRep();
+        EncTgsRepPart encTgsRepPart = EncryptionUtil.unseal(tgsRep.getEncryptedEncPart(),
+                getSessionKey(),
+                KeyUsage.TGS_REP_ENCPART_SESSKEY, EncTgsRepPart.class);
+
+        tgsRep.setEncPart(encTgsRepPart);
+
+        if (getChosenNonce() != encTgsRepPart.getNonce()) {
+            throw new KrbException("Nonce didn't match");
+        }
+    }
+
+    public ServiceTicket getServiceTicket() {
+        ServiceTicket serviceTkt = new ServiceTicket(getKdcRep().getTicket(),
+                (EncTgsRepPart) getKdcRep().getEncPart());
+        return serviceTkt;
+    }
+
+    public ApReq getApReq() {
+        return apReq;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbClient.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbClient.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbClient.java
deleted file mode 100644
index 03191dc..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbClient.java
+++ /dev/null
@@ -1,302 +0,0 @@
-package org.haox.kerb.client;
-
-import org.apache.haox.event.Event;
-import org.apache.haox.event.EventHub;
-import org.apache.haox.event.EventWaiter;
-import org.haox.kerb.KrbErrorCode;
-import org.haox.kerb.client.event.KrbClientEvent;
-import org.haox.kerb.client.event.KrbClientEventType;
-import org.haox.kerb.client.request.*;
-import org.haox.kerb.common.KrbErrorUtil;
-import org.haox.kerb.common.KrbStreamingDecoder;
-import org.haox.kerb.KrbErrorException;
-import org.haox.kerb.KrbException;
-import org.haox.kerb.spec.common.KrbError;
-import org.haox.kerb.spec.common.PrincipalName;
-import org.haox.kerb.spec.ticket.ServiceTicket;
-import org.haox.kerb.spec.ticket.TgtTicket;
-import org.haox.token.KerbToken;
-import org.apache.haox.transport.Connector;
-import org.apache.haox.transport.Transport;
-import org.apache.haox.transport.event.TransportEvent;
-import org.apache.haox.transport.event.TransportEventType;
-import org.apache.haox.transport.tcp.TcpConnector;
-
-import java.io.IOException;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * A krb client API for applications to interact with KDC
- */
-public class KrbClient {
-
-    private EventHub eventHub;
-    private EventWaiter eventWaiter;
-    private Transport transport;
-
-    private KrbHandler krbHandler;
-    private KrbContext context;
-    private KrbConfig config;
-
-    /**
-     *
-     * @param kdcHost
-     * @param kdcPort
-     */
-    public KrbClient(String kdcHost, short kdcPort) {
-        this(new KrbConfig());
-
-        setKdcHost(kdcHost);
-        setKdcPort(kdcPort);
-    }
-
-    public KrbClient(KrbConfig config) {
-        this.config = config;
-        this.context = new KrbContext();
-        context.init(config);
-    }
-
-    /**
-     * Set KDC realm for ticket request
-     * @param realm
-     */
-    public void setKdcRealm(String realm) {
-        context.setKdcRealm(realm);
-    }
-
-    /**
-     *
-     * @param kdcHost
-     */
-    public void setKdcHost(String kdcHost) {
-        context.setKdcHost(kdcHost);
-    }
-
-    /**
-     *
-     * @param kdcPort
-     */
-    public void setKdcPort(short kdcPort) {
-        context.setKdcPort(kdcPort);
-    }
-
-    /**
-     * Set time out for connection
-     * @param timeout in seconds
-     */
-    public void setTimeout(long timeout) {
-        context.setTimeout(timeout);
-    }
-
-    public void init() {
-        this.krbHandler = new KrbHandler();
-        krbHandler.init(context);
-
-        this.eventHub = new EventHub();
-        eventHub.register(krbHandler);
-
-        Connector connector = new TcpConnector(new KrbStreamingDecoder());
-        eventHub.register(connector);
-
-        eventWaiter = eventHub.waitEvent(
-                TransportEventType.NEW_TRANSPORT,
-                KrbClientEventType.TGT_RESULT,
-                KrbClientEventType.TKT_RESULT
-        );
-
-        eventHub.start();
-
-        connector.connect(context.getKdcHost(), context.getKdcPort());
-        Event event = eventWaiter.waitEvent(TransportEventType.NEW_TRANSPORT);
-        transport = ((TransportEvent) event).getTransport();
-    }
-
-    /**
-     * Attempt to request a TGT and you'll be prompted to input a credential.
-     * Whatever credential requested to provide depends on KDC admin configuration.
-     * @param options
-     * @return
-     * @throws KrbException
-     */
-    public TgtTicket requestTgtTicket(String principal, KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        AsRequest asRequest = new AsRequest(context);
-        asRequest.setKrbOptions(options);
-        return requestTgtTicket(principal, asRequest);
-    }
-
-    /**
-     * Request a TGT with user plain credential
-     * @param principal
-     * @param password
-     * @param options
-     * @return
-     * @throws KrbException
-     */
-    public TgtTicket requestTgtTicket(String principal, String password,
-                                      KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        AsRequest asRequest = new AsRequestWithPasswd(context);
-        options.add(KrbOption.USER_PASSWD, password);
-        asRequest.setKrbOptions(options);
-        return requestTgtTicket(principal, asRequest);
-    }
-
-    /**
-     * Request a TGT with user x509 certificate credential
-     * @param principal
-     * @param certificate
-     * @param privateKey
-     * @param options
-     * @return
-     * @throws KrbException
-     */
-    public TgtTicket requestTgtTicket(String principal, Certificate certificate,
-                                      PrivateKey privateKey, KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        AsRequestWithCert asRequest = new AsRequestWithCert(context);
-        options.add(KrbOption.PKINIT_X509_CERTIFICATE, certificate);
-        options.add(KrbOption.PKINIT_X509_PRIVATE_KEY, privateKey);
-        asRequest.setKrbOptions(options);
-        return requestTgtTicket(principal, asRequest);
-    }
-
-    /**
-     * Request a TGT with using Anonymous PKINIT
-     * @param options
-     * @return
-     * @throws KrbException
-     */
-    public TgtTicket requestTgtTicket(KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        AsRequestWithCert asRequest = new AsRequestWithCert(context);
-        options.add(KrbOption.PKINIT_X509_ANONYMOUS);
-        asRequest.setKrbOptions(options);
-
-        String principal = AsRequestWithCert.ANONYMOUS_PRINCIPAL;
-        return requestTgtTicket(principal, asRequest);
-    }
-
-    /**
-     * Request a TGT with user token credential
-     * @param principal
-     * @param token
-     * @param options
-     * @return
-     * @throws KrbException
-     */
-    public TgtTicket requestTgtTicket(String principal, KerbToken token,
-                                      KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        AsRequestWithToken asRequest = new AsRequestWithToken(context);
-        options.add(KrbOption.TOKEN_USER_ID_TOKEN, token);
-        asRequest.setKrbOptions(options);
-        return requestTgtTicket(principal, asRequest);
-    }
-
-    /**
-     * Request a service ticket targeting for a server with user plain credentials
-     * @param clientPrincipal
-     * @param password
-     * @param serverPrincipal
-     * @param options
-     * @return
-     * @throws KrbException
-     */
-    public ServiceTicket requestServiceTicket(String clientPrincipal, String password,
-                                              String serverPrincipal, KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        TgtTicket tgt = requestTgtTicket(clientPrincipal, password, options);
-        return requestServiceTicket(tgt, serverPrincipal, options);
-    }
-
-    /**
-     * Request a service ticket targeting for a server with an user Access Token
-     * @param clientPrincipal
-     * @param token
-     * @param serverPrincipal
-     * @param options
-     * @return
-     * @throws KrbException
-     */
-    public ServiceTicket requestServiceTicket(String clientPrincipal, KerbToken token,
-                                              String serverPrincipal, KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        TgtTicket tgt = requestTgtTicket(clientPrincipal, token, options);
-        return requestServiceTicket(tgt, serverPrincipal, options);
-    }
-
-    private TgtTicket requestTgtTicket(String clientPrincipal, AsRequest tgtTktReq) throws KrbException {
-        tgtTktReq.setClientPrincipal(new PrincipalName(clientPrincipal));
-        tgtTktReq.setTransport(transport);
-
-        try {
-            return doRequestTgtTicket(tgtTktReq);
-        } catch(KrbErrorException e) {
-            KrbError krbError = e.getKrbError();
-            if (krbError.getErrorCode() == KrbErrorCode.KDC_ERR_PREAUTH_REQUIRED) {
-                try {
-                    tgtTktReq.setEncryptionTypes(KrbErrorUtil.getEtypes(krbError));
-                } catch (IOException ioe) {
-                    throw new KrbException("Failed to decode and get etypes from krbError", ioe);
-                }
-                tgtTktReq.getPreauthContext().setPreauthRequired(true);
-                return requestTgtTicket(clientPrincipal, tgtTktReq);
-            }
-            throw e;
-        }
-    }
-
-    private TgtTicket doRequestTgtTicket(AsRequest tgtTktReq) throws KrbException {
-        eventHub.dispatch(KrbClientEvent.createTgtIntentEvent(tgtTktReq));
-        Event resultEvent = null;
-        try {
-            resultEvent = eventWaiter.waitEvent(KrbClientEventType.TGT_RESULT,
-                    context.getTimeout(), TimeUnit.SECONDS);
-        } catch (TimeoutException e) {
-            throw new KrbException("Network timeout", e);
-        }
-        AsRequest asResponse = (AsRequest) resultEvent.getEventData();
-
-        return asResponse.getTicket();
-    }
-
-    /**
-     * Request a service ticket with a TGT targeting for a server
-     * @param tgt
-     * @param serverPrincipal
-     * @return
-     * @throws KrbException
-     */
-    public ServiceTicket requestServiceTicket(TgtTicket tgt, String serverPrincipal,
-                                              KrbOptions options) throws KrbException {
-        if (options == null) options = new KrbOptions();
-
-        TgsRequest ticketReq = new TgsRequest(context, tgt);
-        ticketReq.setServerPrincipal(new PrincipalName(serverPrincipal));
-        ticketReq.setTransport(transport);
-
-        eventHub.dispatch(KrbClientEvent.createTktIntentEvent(ticketReq));
-        Event resultEvent = null;
-        try {
-            resultEvent = eventWaiter.waitEvent(KrbClientEventType.TKT_RESULT,
-                    context.getTimeout(), TimeUnit.SECONDS);
-        } catch (TimeoutException e) {
-            throw new KrbException("Network timeout", e);
-        }
-        TgsRequest tgsResponse = (TgsRequest) resultEvent.getEventData();
-
-        return tgsResponse.getServiceTicket();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfig.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfig.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfig.java
deleted file mode 100644
index 3e3be29..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfig.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.haox.kerb.client;
-
-import org.apache.haox.config.Conf;
-import org.haox.kerb.common.KrbConfHelper;
-import org.haox.kerb.spec.common.EncryptionType;
-
-import java.util.List;
-
-public class KrbConfig {
-    protected Conf conf;
-
-    public KrbConfig() {
-        this.conf = new Conf();
-    }
-
-    public Conf getConf() {
-        return this.conf;
-    }
-
-    public boolean enableDebug() {
-        return conf.getBoolean(KrbConfigKey.KRB_DEBUG);
-    }
-
-    public String getKdcHost() {
-        return conf.getString(KrbConfigKey.KDC_HOST);
-    }
-
-    public short getKdcPort() {
-        Integer kdcPort = conf.getInt(KrbConfigKey.KDC_PORT);
-        return kdcPort.shortValue();
-    }
-
-    public String getKdcRealm() {
-        return conf.getString(KrbConfigKey.KDC_REALM);
-    }
-
-    public String getKdcDomain() {
-        return conf.getString(KrbConfigKey.KDC_DOMAIN);
-    }
-
-    public boolean isPreauthRequired() {
-        return conf.getBoolean(KrbConfigKey.PREAUTH_REQUIRED);
-    }
-
-    public String getTgsPrincipal() {
-        return conf.getString(KrbConfigKey.TGS_PRINCIPAL);
-    }
-
-    public long getAllowableClockSkew() {
-        return conf.getLong(KrbConfigKey.ALLOWABLE_CLOCKSKEW);
-    }
-
-    public boolean isEmptyAddressesAllowed() {
-        return conf.getBoolean(KrbConfigKey.EMPTY_ADDRESSES_ALLOWED);
-    }
-
-    public boolean isForwardableAllowed() {
-        return conf.getBoolean(KrbConfigKey.FORWARDABLE_ALLOWED);
-    }
-
-    public boolean isPostdatedAllowed() {
-        return conf.getBoolean(KrbConfigKey.POSTDATED_ALLOWED);
-    }
-
-    public boolean isProxiableAllowed() {
-        return conf.getBoolean(KrbConfigKey.PROXIABLE_ALLOWED);
-    }
-
-    public boolean isRenewableAllowed() {
-        return conf.getBoolean(KrbConfigKey.RENEWABLE_ALLOWED);
-    }
-
-    public long getMaximumRenewableLifetime() {
-        return conf.getLong(KrbConfigKey.MAXIMUM_RENEWABLE_LIFETIME);
-    }
-
-    public long getMaximumTicketLifetime() {
-        return conf.getLong(KrbConfigKey.MAXIMUM_TICKET_LIFETIME);
-    }
-
-    public long getMinimumTicketLifetime() {
-        return conf.getLong(KrbConfigKey.MINIMUM_TICKET_LIFETIME);
-    }
-
-    public List<EncryptionType> getEncryptionTypes() {
-        return KrbConfHelper.getEncryptionTypes(
-                conf.getList(KrbConfigKey.ENCRYPTION_TYPES));
-    }
-
-    public boolean isPaEncTimestampRequired() {
-        return conf.getBoolean(KrbConfigKey.PA_ENC_TIMESTAMP_REQUIRED);
-    }
-
-    public boolean isBodyChecksumVerified() {
-        return conf.getBoolean(KrbConfigKey.VERIFY_BODY_CHECKSUM);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfigKey.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfigKey.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfigKey.java
deleted file mode 100644
index 7ad80f5..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbConfigKey.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.haox.kerb.client;
-
-import org.apache.haox.config.ConfigKey;
-
-public enum KrbConfigKey implements ConfigKey {
-    KRB_DEBUG(true),
-    KDC_HOST("localhost"),
-    KDC_PORT(8015),
-    KDC_DOMAIN("example.com"),
-    KDC_REALM("EXAMPLE.COM"),
-    TGS_PRINCIPAL("krbtgt@EXAMPLE.COM"),
-    PREAUTH_REQUIRED(true),
-    ALLOWABLE_CLOCKSKEW(5 * 60),
-    EMPTY_ADDRESSES_ALLOWED(true),
-    PA_ENC_TIMESTAMP_REQUIRED(true),
-    MAXIMUM_TICKET_LIFETIME(24 * 3600),
-    MINIMUM_TICKET_LIFETIME(1 * 3600),
-    MAXIMUM_RENEWABLE_LIFETIME(48 * 3600),
-    FORWARDABLE_ALLOWED(true),
-    POSTDATED_ALLOWED(true),
-    PROXIABLE_ALLOWED(true),
-    RENEWABLE_ALLOWED(true),
-    VERIFY_BODY_CHECKSUM(true),
-    ENCRYPTION_TYPES(new String[] { "aes128-cts-hmac-sha1-96", "des-cbc-md5" });
-
-    private Object defaultValue;
-
-    private KrbConfigKey() {
-        this.defaultValue = null;
-    }
-
-    private KrbConfigKey(Object defaultValue) {
-        this.defaultValue = defaultValue;
-    }
-
-    @Override
-    public String getPropertyKey() {
-        return name().toLowerCase();
-    }
-
-    @Override
-    public Object getDefaultValue() {
-        return this.defaultValue;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbContext.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbContext.java
deleted file mode 100644
index 74016d6..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbContext.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.haox.kerb.client;
-
-import org.haox.kerb.client.preauth.PreauthContext;
-import org.haox.kerb.client.preauth.PreauthHandler;
-import org.haox.kerb.crypto.Nonce;
-
-public class KrbContext {
-
-    private String kdcRealm;
-    private KrbConfig config;
-    private String kdcHost;
-    private short kdcPort;
-    private long timeout = 10L;
-    private PreauthHandler preauthHandler;
-
-    public void init(KrbConfig config) {
-        this.config = config;
-        preauthHandler = new PreauthHandler();
-        preauthHandler.init(this);
-    }
-
-    public String getKdcHost() {
-        if (kdcHost != null) {
-            return kdcHost;
-        }
-        return config.getKdcHost();
-    }
-
-    public void setKdcHost(String kdcHost) {
-        this.kdcHost = kdcHost;
-    }
-
-    public short getKdcPort() {
-        if (kdcPort > 0) {
-            return kdcPort;
-        }
-        return config.getKdcPort();
-    }
-
-    public void setKdcPort(short kdcPort) {
-        this.kdcPort = kdcPort;
-    }
-
-    public void setTimeout(long timeout) {
-        this.timeout = timeout;
-    }
-
-    public long getTimeout() {
-        return this.timeout;
-    }
-
-    public KrbConfig getConfig() {
-        return config;
-    }
-
-    public void setKdcRealm(String realm) {
-        this.kdcRealm = realm;
-    }
-
-    public String getKdcRealm() {
-        if (kdcRealm != null) {
-            return kdcRealm;
-        }
-
-        return config.getKdcRealm();
-    }
-
-    public int generateNonce() {
-        return Nonce.value();
-    }
-
-    public long getTicketValidTime() {
-        return 8 * 60 * 60 * 1000;
-    }
-
-    public PreauthHandler getPreauthHandler() {
-        return preauthHandler;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbHandler.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbHandler.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbHandler.java
deleted file mode 100644
index ed77a56..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbHandler.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.haox.kerb.client;
-
-import org.apache.haox.event.AbstractEventHandler;
-import org.apache.haox.event.Event;
-import org.apache.haox.event.EventType;
-import org.haox.kerb.client.event.KrbClientEvent;
-import org.haox.kerb.client.event.KrbClientEventType;
-import org.haox.kerb.client.preauth.PreauthHandler;
-import org.haox.kerb.client.request.AsRequest;
-import org.haox.kerb.client.request.KdcRequest;
-import org.haox.kerb.client.request.TgsRequest;
-import org.haox.kerb.common.KrbUtil;
-import org.haox.kerb.KrbException;
-import org.haox.kerb.spec.common.KrbMessage;
-import org.haox.kerb.spec.common.KrbMessageType;
-import org.haox.kerb.spec.kdc.KdcRep;
-import org.haox.kerb.spec.kdc.KdcReq;
-import org.apache.haox.transport.Transport;
-import org.apache.haox.transport.event.MessageEvent;
-import org.apache.haox.transport.event.TransportEventType;
-
-import java.nio.ByteBuffer;
-
-public class KrbHandler extends AbstractEventHandler {
-
-    private KrbContext context;
-    private PreauthHandler preauthHandler;
-
-    public void init(KrbContext context) {
-        this.context = context;
-        preauthHandler = new PreauthHandler();
-        preauthHandler.init(context);
-    }
-
-    @Override
-    public EventType[] getInterestedEvents() {
-        return new EventType[] {
-                TransportEventType.INBOUND_MESSAGE,
-                KrbClientEventType.TGT_INTENT,
-                KrbClientEventType.TKT_INTENT
-        };
-    }
-
-    @Override
-    protected void doHandle(Event event) throws Exception {
-        EventType eventType = event.getEventType();
-
-        if (eventType == KrbClientEventType.TGT_INTENT ||
-                eventType == KrbClientEventType.TKT_INTENT) {
-            KdcRequest kdcRequest = (KdcRequest) event.getEventData();
-            handleKdcRequest(kdcRequest);
-        } else if (event.getEventType() == TransportEventType.INBOUND_MESSAGE) {
-            handleMessage((MessageEvent) event);
-        }
-    }
-
-    protected void handleKdcRequest(KdcRequest kdcRequest) throws KrbException {
-        kdcRequest.process();
-        KdcReq kdcReq = kdcRequest.getKdcReq();
-        Transport transport = kdcRequest.getTransport();
-        transport.setAttachment(kdcRequest);
-        KrbUtil.sendMessage(kdcReq, transport);
-    }
-
-    protected void handleMessage(MessageEvent event) throws Exception {
-        ByteBuffer message = event.getMessage();
-        KrbMessage kdcRep = KrbUtil.decodeMessage(message);
-
-        KrbMessageType messageType = kdcRep.getMsgType();
-        if (messageType == KrbMessageType.AS_REP) {
-            KdcRequest kdcRequest = (KdcRequest) event.getTransport().getAttachment();
-            kdcRequest.processResponse((KdcRep) kdcRep);
-            dispatch(KrbClientEvent.createTgtResultEvent((AsRequest) kdcRequest));
-        } else if (messageType == KrbMessageType.TGS_REP) {
-            KdcRequest kdcRequest = (KdcRequest) event.getTransport().getAttachment();
-            kdcRequest.processResponse((KdcRep) kdcRep);
-            dispatch(KrbClientEvent.createTktResultEvent((TgsRequest) kdcRequest));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOption.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOption.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOption.java
deleted file mode 100644
index ab6094b..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOption.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.haox.kerb.client;
-
-public enum KrbOption {
-    LIFE_TIME("-l lifetime"),
-    START_TIME("-s start time"),
-    RENEWABLE_TIME("-r renewable lifetime"),
-    FORWARDABLE("-f forwardable"),
-    NOT_FORWARDABLE("-F not forwardable"),
-    PROXIABLE("-p proxiable"),
-    NOT_PROXIABLE("-P not proxiable"),
-    ANONYMOUS("-n anonymous"),
-    INCLUDE_ADDRESSES("-a include addresses"),
-    NOT_INCLUDE_ADDRESSES("-A do not include addresses"),
-    VALIDATE("-v validate"),
-    RENEW("-R renew"),
-    CANONICALIZE("-C canonicalize"),
-    AS_ENTERPRISE_PN("-E client is enterprise principal name"),
-    USE_KEYTAB("-k use keytab"),
-    USE_DFT_KEYTAB("-i use default client keytab (with -k)"),
-    USER_KEYTAB_FILE("-t filename of keytab to use"),
-    KRB5_CACHE("-c Kerberos 5 cache name"),
-    SERVICE("-S service"),
-    ARMOR_CACHE("-T armor credential cache"),
-    XATTR("-X <attribute>[=<value>]"),
-
-    USER_PASSWD("user_passwd", "User plain password"),
-
-    PKINIT_X509_IDENTITY("x509_identities", "X509 user private key and cert"),
-    PKINIT_X509_PRIVATE_KEY("x509_privatekey", "X509 user private key"),
-    PKINIT_X509_CERTIFICATE("x509_cert", "X509 user certificate"),
-    PKINIT_X509_ANCHORS("x509_anchors", "X509 anchors"),
-    PKINIT_X509_ANONYMOUS("x509_anonymous", "X509 anonymous"),
-    PKINIT_USING_RSA("using_rsa_or_dh", "Using RSA or DH"),
-
-    TOKEN_USING_IDTOKEN("using_id_token", "Using identity token"),
-    TOKEN_USER_ID_TOKEN("user_id_token", "User identity token"),
-    TOKEN_USER_AC_TOKEN("user_ac_token", "User access token"),
-
-    ;
-
-    private String name;
-    private String description;
-    private Object value;
-
-    KrbOption(String description) {
-        this.description = description;
-    }
-
-    KrbOption(String name, String description) {
-        this.name = name;
-        this.description = description;
-    }
-
-    public String getName() {
-        if (name != null) {
-            return name;
-        }
-        return name();
-    }
-
-    public String getDescription() {
-        return this.description;
-    }
-
-    public void setValue(Object value) {
-        this.value = value;
-    }
-
-    public Object getValue() {
-        return value;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOptions.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOptions.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOptions.java
deleted file mode 100644
index 8d9fddf..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/KrbOptions.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.haox.kerb.client;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class KrbOptions {
-
-    private Map<KrbOption, KrbOption> options = new HashMap<KrbOption, KrbOption>(4);
-
-    public void add(KrbOption option) {
-        if (option != null) {
-            options.put(option, option);
-        }
-    }
-
-    public void add(KrbOption option, Object optionValue) {
-        option.setValue(optionValue);
-        add(option);
-    }
-
-    public boolean contains(KrbOption option) {
-        return options.containsKey(option);
-    }
-
-    public KrbOption getOption(KrbOption option) {
-        if (! options.containsKey(option)) {
-            return null;
-        }
-
-        return options.get(option);
-    }
-
-    public Object getOptionValue(KrbOption option) {
-        if (! contains(option)) {
-            return null;
-        }
-        return options.get(option).getValue();
-    }
-
-    public String getStringOption(KrbOption option) {
-        Object value = getOptionValue(option);
-        if (value != null && value instanceof String) {
-            return (String) value;
-        }
-        return null;
-    }
-
-    public boolean getBooleanOption(KrbOption option) {
-        Object value = getOptionValue(option);
-        if (value != null) {
-            if (value instanceof String) {
-                String strVal = (String) value;
-                if (strVal.equalsIgnoreCase("true") ||
-                        strVal.equalsIgnoreCase("yes") ||
-                        strVal.equals("1")) {
-                    return true;
-                }
-            } else if (value instanceof Boolean) {
-                return (Boolean) value;
-            }
-        }
-        return false;
-    }
-
-    public int getIntegerOption(KrbOption option) {
-        Object value = getOptionValue(option);
-        if (value != null) {
-            if (value instanceof String) {
-                String strVal = (String) value;
-                return Integer.valueOf(strVal);
-            } else if (value instanceof Integer) {
-                return (Integer) value;
-            }
-        }
-        return -1;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/967d7e1c/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/event/KrbClientEvent.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/event/KrbClientEvent.java b/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/event/KrbClientEvent.java
deleted file mode 100644
index 4a9225a..0000000
--- a/haox-kerb/kerb-client/src/main/java/org/haox/kerb/client/event/KrbClientEvent.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.haox.kerb.client.event;
-
-import org.apache.haox.event.Event;
-import org.haox.kerb.client.request.AsRequest;
-import org.haox.kerb.client.request.TgsRequest;
-
-public class KrbClientEvent {
-
-    public static Event createTgtIntentEvent(AsRequest asRequest) {
-        return new Event(KrbClientEventType.TGT_INTENT, asRequest);
-    }
-
-    public static Event createTktIntentEvent(TgsRequest tgsRequest) {
-        return new Event(KrbClientEventType.TKT_INTENT, tgsRequest);
-    }
-
-    public static Event createTgtResultEvent(AsRequest asRequest) {
-        return new Event(KrbClientEventType.TGT_RESULT, asRequest);
-    }
-
-    public static Event createTktResultEvent(TgsRequest tgsRequest) {
-        return new Event(KrbClientEventType.TKT_RESULT, tgsRequest);
-    }
-}