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/03/29 16:19:33 UTC

[1/2] directory-kerby git commit: DIRKRB-199. Support both blocking and event based network transport

Repository: directory-kerby
Updated Branches:
  refs/heads/master bf116de47 -> ff0200f8b


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEventType.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEventType.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEventType.java
new file mode 100644
index 0000000..8f0e981
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEventType.java
@@ -0,0 +1,29 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.event;
+
+import org.apache.kerby.event.EventType;
+
+public enum KrbClientEventType implements EventType {
+    TGT_INTENT,
+    TGT_RESULT,
+    TKT_INTENT,
+    TKT_RESULT
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/AbstractPreauthPlugin.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/AbstractPreauthPlugin.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/AbstractPreauthPlugin.java
index a9988a1..bdc8ccf 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/AbstractPreauthPlugin.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/AbstractPreauthPlugin.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb.client.preauth;
 
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
 import org.apache.kerby.kerberos.kerb.preauth.PaFlag;
 import org.apache.kerby.kerberos.kerb.preauth.PaFlags;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbPreauth.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbPreauth.java
index 52a638f..23bb7d8 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbPreauth.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/KrbPreauth.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb.client.preauth;
 
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
 import org.apache.kerby.kerberos.kerb.preauth.PaFlags;
 import org.apache.kerby.kerberos.kerb.preauth.PluginRequestContext;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandle.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandle.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandle.java
index 6813ee6..b822dc7 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandle.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandle.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.client.preauth;
 
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
 import org.apache.kerby.kerberos.kerb.preauth.PaFlags;
 import org.apache.kerby.kerberos.kerb.preauth.PluginRequestContext;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
index de67884..30599d6 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/PreauthHandler.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb.client.preauth;
 
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.preauth.builtin.EncTsPreauth;
 import org.apache.kerby.kerberos.kerb.client.preauth.builtin.TgtPreauth;
 import org.apache.kerby.kerberos.kerb.client.preauth.pkinit.PkinitPreauth;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
index 21c7208..c616131 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/pkinit/PkinitPreauth.java
@@ -21,7 +21,7 @@ package org.apache.kerby.kerberos.kerb.client.preauth.pkinit;
 
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.preauth.AbstractPreauthPlugin;
 import org.apache.kerby.kerberos.kerb.preauth.PluginRequestContext;
 import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/token/TokenPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/token/TokenPreauth.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/token/TokenPreauth.java
index fbab3ee..23269c6 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/token/TokenPreauth.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/preauth/token/TokenPreauth.java
@@ -21,7 +21,7 @@ package org.apache.kerby.kerberos.kerb.client.preauth.token;
 
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.preauth.AbstractPreauthPlugin;
 import org.apache.kerby.kerberos.kerb.preauth.PluginRequestContext;
 import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
@@ -75,7 +75,7 @@ public class TokenPreauth extends AbstractPreauthPlugin {
                                   PluginRequestContext requestContext,
                                   KOptions options) {
 
-        tokenContext.usingIdToken = options.getBooleanOption(KrbOption.TOKEN_USING_IDTOKEN);
+        tokenContext.usingIdToken = options.getBooleanOption(KrbOption.USE_TOKEN);
         if (tokenContext.usingIdToken) {
             if (options.contains(KrbOption.TOKEN_USER_ID_TOKEN)) {
                 tokenContext.token =

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
index 6d19bf6..5c45479 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/ArmoredAsRequest.java
@@ -21,7 +21,7 @@ package org.apache.kerby.kerberos.kerb.client.request;
 
 import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.ccache.CredentialCache;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
 import org.apache.kerby.kerberos.kerb.crypto.fast.FastUtil;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
index 9b3d8fb..ef2808f 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithCert.java
@@ -21,7 +21,7 @@ package org.apache.kerby.kerberos.kerb.client.request;
 
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.spec.pa.PaDataType;
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithKeytab.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithKeytab.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithKeytab.java
index 5fa6799..3cde244 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithKeytab.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithKeytab.java
@@ -19,8 +19,8 @@
  */
 package org.apache.kerby.kerberos.kerb.client.request;
 
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
 import org.apache.kerby.kerberos.kerb.keytab.Keytab;
@@ -31,9 +31,6 @@ import java.io.File;
 import java.io.IOException;
 
 public class AsRequestWithKeytab extends AsRequest{
-    private static final String DEFAULT_KEY_LOCATION = "/etc/krb5.keytab";
-    private static final String DEFAULT_CLIENT_KEY_LOCATION = "/usr/local/var/krb5/user/0/client.keytab";
-
 
     public AsRequestWithKeytab(KrbContext context) {
         super(context);
@@ -45,12 +42,8 @@ public class AsRequestWithKeytab extends AsRequest{
         File keytabFile = null;
         KOptions kOptions = getKrbOptions();
 
-        if (kOptions.contains(KrbOption.USE_DFT_KEYTAB)) {
-            keytabFile = new File(DEFAULT_CLIENT_KEY_LOCATION);
-        } else if (kOptions.contains(KrbOption.USER_KEYTAB_FILE)) {
-            keytabFile = new File(kOptions.getStringOption(KrbOption.USER_KEYTAB_FILE));
-        } else {
-            keytabFile = new File(DEFAULT_KEY_LOCATION);
+        if (kOptions.contains(KrbOption.KEYTAB_FILE)) {
+            keytabFile = kOptions.getFileOption(KrbOption.KEYTAB_FILE);
         }
 
         Keytab keytab = null;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithToken.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithToken.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithToken.java
index 95e6021..0d08415 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithToken.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/AsRequestWithToken.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb.client.request;
 
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
 import org.apache.kerby.kerberos.kerb.spec.pa.PaDataType;
@@ -46,7 +46,7 @@ public class AsRequestWithToken extends ArmoredAsRequest {
         KOptions results = super.getPreauthOptions();
         KOptions krbOptions = getKrbOptions();
 
-        results.add(krbOptions.getOption(KrbOption.TOKEN_USING_IDTOKEN));
+        results.add(krbOptions.getOption(KrbOption.USE_TOKEN));
         results.add(krbOptions.getOption(KrbOption.TOKEN_USER_ID_TOKEN));
         //results.add(krbOptions.getOption(KrbOption.TOKEN_USER_AC_TOKEN));
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
index d4c2a4e..1a5570d 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
@@ -19,13 +19,13 @@
  */
 package org.apache.kerby.kerberos.kerb.client.request;
 
+import org.apache.kerby.KOptions;
+import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
 import org.apache.kerby.kerberos.kerb.client.preauth.KrbFastContext;
 import org.apache.kerby.kerberos.kerb.client.preauth.PreauthContext;
 import org.apache.kerby.kerberos.kerb.client.preauth.PreauthHandler;
 import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
-import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
 import org.apache.kerby.kerberos.kerb.spec.base.*;
 import org.apache.kerby.kerberos.kerb.spec.kdc.KdcOptions;
@@ -33,7 +33,7 @@ import org.apache.kerby.kerberos.kerb.spec.kdc.KdcRep;
 import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
 import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReqBody;
 import org.apache.kerby.kerberos.kerb.spec.pa.PaDataType;
-import org.apache.kerby.transport.Transport;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -47,7 +47,7 @@ import java.util.Map;
  */
 public abstract class KdcRequest {
     private KrbContext context;
-    private Transport transport;
+    private KrbTransport transport;
 
     private KOptions krbOptions;
     private PrincipalName serverPrincipal;
@@ -75,11 +75,11 @@ public abstract class KdcRequest {
         this.fastContext = new KrbFastContext();
     }
 
-    public void setTransport(Transport transport) {
+    public void setTransport(KrbTransport transport) {
         this.transport = transport;
     }
 
-    public Transport getTransport() {
+    public KrbTransport getTransport() {
         return this.transport;
     }
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
index e0ca3ed..4a4b6e0 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
@@ -39,6 +39,10 @@ public class TgsRequest extends KdcRequest {
     private TgtTicket tgt;
     private ApReq apReq;
 
+    public TgsRequest(KrbContext context) {
+        super(context);
+    }
+
     public TgsRequest(KrbContext context, TgtTicket tgtTicket) {
         super(context);
         this.tgt = tgtTicket;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithToken.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithToken.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithToken.java
new file mode 100644
index 0000000..a167718
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithToken.java
@@ -0,0 +1,36 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.client.request;
+
+import org.apache.kerby.kerberos.kerb.client.KrbContext;
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+/**
+ * Tgs request with an Access Token.
+ */
+public class TgsRequestWithToken extends TgsRequest {
+
+    public TgsRequestWithToken(KrbContext context) {
+        super(context);
+
+        // TODO: Access Token specific.
+        throw new NotImplementedException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
index 45020e0..ad461ba 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
@@ -21,6 +21,7 @@ package org.apache.kerby.kerberos.kerb.common;
 
 import org.apache.kerby.kerberos.kerb.KrbCodec;
 import org.apache.kerby.kerberos.kerb.spec.base.KrbMessage;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
 import org.apache.kerby.transport.Transport;
 
 import java.io.IOException;
@@ -28,7 +29,8 @@ import java.nio.ByteBuffer;
 
 public class KrbUtil {
 
-    public static void sendMessage(KrbMessage message, Transport transport) {
+    public static void sendMessage(KrbMessage message,
+                                   KrbTransport transport) throws IOException {
         int bodyLen = message.encodingLength();
         ByteBuffer buffer = ByteBuffer.allocate(bodyLen + 4);
         buffer.putInt(bodyLen);
@@ -37,7 +39,29 @@ public class KrbUtil {
         transport.sendMessage(buffer);
     }
 
-    public static KrbMessage decodeMessage(ByteBuffer message) throws IOException {
+    /**
+     * To be cleaned up
+     * @param message
+     * @param transport
+     * @throws IOException
+     */
+    public static void sendMessageOld(KrbMessage message,
+                                   Transport transport) throws IOException {
+        int bodyLen = message.encodingLength();
+        ByteBuffer buffer = ByteBuffer.allocate(bodyLen + 4);
+        buffer.putInt(bodyLen);
+        message.encode(buffer);
+        buffer.flip();
+        transport.sendMessage(buffer);
+    }
+
+    /**
+     * To be cleaned.
+     * @param message
+     * @return
+     * @throws IOException
+     */
+    public static KrbMessage decodeMessageOld(ByteBuffer message) throws IOException {
         int bodyLen = message.getInt();
         assert (message.remaining() >= bodyLen);
 
@@ -46,4 +70,10 @@ public class KrbUtil {
         return krbMessage;
     }
 
+    public static KrbMessage decodeMessage(ByteBuffer message) throws IOException {
+        KrbMessage krbMessage = KrbCodec.decodeMessage(message);
+
+        return krbMessage;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/AbstractKrbTransport.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/AbstractKrbTransport.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/AbstractKrbTransport.java
new file mode 100644
index 0000000..b7577cf
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/AbstractKrbTransport.java
@@ -0,0 +1,38 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.transport;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Abstract Krb transport.
+ */
+public abstract class AbstractKrbTransport implements KrbTransport {
+    private Object attachment;
+
+    public void setAttachment(Object attachment) {
+        this.attachment = attachment;
+    }
+
+    public Object getAttachment() {
+        return attachment;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/KrbTransport.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/KrbTransport.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/KrbTransport.java
new file mode 100644
index 0000000..432bda8
--- /dev/null
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/transport/KrbTransport.java
@@ -0,0 +1,53 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.transport;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Krb client transport.
+ */
+public interface KrbTransport {
+
+    /**
+     * Send out a Kerberos message to remote peer.
+     * @param message
+     */
+    public void sendMessage(ByteBuffer message) throws IOException;
+
+    /**
+     * Receive a Kerberos message from remote.
+     * @return
+     */
+    public ByteBuffer receiveMessage() throws IOException;
+
+    /**
+     * Set an attachment.
+     * @param attachment
+     */
+    public void setAttachment(Object attachment);
+
+    /**
+     * Get the attachment set before.
+     * @return attachment
+     */
+    public Object getAttachment();
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/KdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/KdcTest.java b/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/KdcTest.java
index 3a3d22d..17d4357 100644
--- a/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/KdcTest.java
+++ b/kerby-kerb/kerb-kdc-test/src/test/java/org/apache/kerby/kerberos/kerb/server/KdcTest.java
@@ -51,10 +51,10 @@ public abstract class KdcTest extends KdcTestBase {
 
         // With good password
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, password, null);
+            tgt = krbClnt.requestTgtWithPassword(clientPrincipal, password);
             assertThat(tgt).isNotNull();
 
-            tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+            tkt = krbClnt.requestServiceTicketWithTgt(tgt, serverPrincipal);
             assertThat(tkt).isNotNull();
         } catch (Exception e) {
             System.out.println("Exception occurred with good password");
@@ -64,23 +64,22 @@ public abstract class KdcTest extends KdcTestBase {
 
         // With bad password
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, "badpassword", null);
+            tgt = krbClnt.requestTgtWithPassword(clientPrincipal, "badpassword");
         } catch (Exception e) {
             System.out.println("Exception occurred with bad password");
         }
 
-        // TODO: With good password again. This will fail, to be investigated.
-        /*
+        // With good password again
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, password, null);
+            tgt = krbClnt.requestTgtWithPassword(clientPrincipal, password);
             assertThat(tgt).isNotNull();
 
-            tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+            tkt = krbClnt.requestServiceTicketWithTgt(tgt, serverPrincipal);
             assertThat(tkt).isNotNull();
         } catch (Exception e) {
             System.out.println("Exception occurred with good password again");
             e.printStackTrace();
             Assert.fail();
-        }*/
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
index 8c730fd..7a0a3d7 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcHandler.java
@@ -99,7 +99,7 @@ public class KdcHandler extends MessageHandler {
         ByteBuffer message = event.getMessage();
         Transport transport = event.getTransport();
 
-        KrbMessage krbRequest = KrbUtil.decodeMessage(message);
+        KrbMessage krbRequest = KrbUtil.decodeMessageOld(message);
         KdcRequest kdcRequest = null;
 
         KrbMessageType messageType = krbRequest.getMsgType();
@@ -128,7 +128,7 @@ public class KdcHandler extends MessageHandler {
             kdcRequest.process();
 
             KrbMessage krbResponse = kdcRequest.getReply();
-            KrbUtil.sendMessage(krbResponse, transport);
+            KrbUtil.sendMessageOld(krbResponse, transport);
         } catch (Exception e) {
             //TODO: log the error
             System.out.println("Error occured while processing request:"

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/ToolUtil.java
----------------------------------------------------------------------
diff --git a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/ToolUtil.java b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/ToolUtil.java
index bce6117..45d9c65 100644
--- a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/ToolUtil.java
+++ b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/ToolUtil.java
@@ -19,10 +19,10 @@
  */
 package org.apache.kerby.kerberos.tool;
 
-import org.apache.kerby.kerberos.kerb.client.KOption;
-import org.apache.kerby.kerberos.kerb.client.KOptionType;
+import org.apache.kerby.KOption;
+import org.apache.kerby.KOptionType;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
+import org.apache.kerby.KOptions;
 
 import java.io.File;
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/Kinit.java
----------------------------------------------------------------------
diff --git a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/Kinit.java b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/Kinit.java
index 740bb90..7c16c98 100644
--- a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/Kinit.java
+++ b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/Kinit.java
@@ -19,11 +19,11 @@
  */
 package org.apache.kerby.kerberos.tool.kinit;
 
+import org.apache.kerby.KOptionType;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.ccache.Credential;
 import org.apache.kerby.kerberos.kerb.ccache.CredentialCache;
-import org.apache.kerby.kerberos.kerb.client.KOptionType;
-import org.apache.kerby.kerberos.kerb.client.KOptions;
 import org.apache.kerby.kerberos.kerb.client.KrbClient;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
 import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
@@ -101,25 +101,25 @@ public class Kinit {
         return password;
     }
 
-    private static void requestTicket(String principal, KOptions krbOptions) throws KrbException, IOException {
-        KrbClient krbClient = getClient();
-        TgtTicket tgt;
-
-        if (krbOptions.contains(KrbOption.USE_KEYTAB)) {
-            tgt = krbClient.requestTgtTicket(principal, krbOptions);
-        } else {
+    private static void requestTicket(String principal,
+                                      KOptions ktOptions) throws Exception {
+        ktOptions.add(KinitOption.CLIENT_PRINCIPAL, principal);
+        if (! ktOptions.contains(KinitOption.USE_KEYTAB)) {
             String password = getPassword(principal);
-            tgt = krbClient.requestTgtTicket(principal, password,
-                    krbOptions);
+            ktOptions.add(KinitOption.USER_PASSWD, password);
         }
 
-        writeTgtToCache(tgt, principal, krbOptions);
+        KrbClient krbClient = getClient();
+        TgtTicket tgt = krbClient.requestTgtWithOptions(
+                ToolUtil.convertOptions(ktOptions));
+
+        writeTgtToCache(tgt, principal, ktOptions);
     }
 
     /**
      * Init the client.
      */
-    private static KrbClient getClient() {
+    private static KrbClient getClient() throws KrbException {
         KrbClient krbClient = new KrbClient();
         krbClient.init();
         return krbClient;
@@ -128,8 +128,8 @@ public class Kinit {
     /**
      * Write tgt into credentials cache.
      */
-    private static void writeTgtToCache(TgtTicket tgt, String principal, KOptions kinitOptions)
-            throws IOException {
+    private static void writeTgtToCache(
+            TgtTicket tgt, String principal, KOptions kinitOptions) throws IOException {
         Credential credential = new Credential(tgt);
         CredentialCache cCache = new CredentialCache();
         cCache.addCredential(credential);
@@ -189,7 +189,7 @@ public class Kinit {
             printUsage("No principal is specified");
         }
 
-        Kinit.requestTicket(principal, ToolUtil.convertOptions(ktOptions));
+        Kinit.requestTicket(principal, ktOptions);
         System.exit(0);
     }
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitOption.java
----------------------------------------------------------------------
diff --git a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitOption.java b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitOption.java
index cade8a8..bce997b 100644
--- a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitOption.java
+++ b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitOption.java
@@ -19,11 +19,12 @@
  */
 package org.apache.kerby.kerberos.tool.kinit;
 
-import org.apache.kerby.kerberos.kerb.client.KOption;
-import org.apache.kerby.kerberos.kerb.client.KOptionType;
+import org.apache.kerby.KOption;
+import org.apache.kerby.KOptionType;
 
 public enum KinitOption implements KOption {
     NONE("NONE"),
+    CLIENT_PRINCIPAL("client-principal", "Client principal", KOptionType.STR),
     LIFE_TIME("-l", "lifetime", KOptionType.INT),
     START_TIME("-s", "start time", KOptionType.INT),
     RENEWABLE_LIFE("-r", "renewable lifetime", KOptionType.INT),
@@ -38,6 +39,7 @@ public enum KinitOption implements KOption {
     RENEW("-R", "renew"),
     CANONICALIZE("-C", "canonicalize"),
     AS_ENTERPRISE_PN("-E", "client is enterprise principal name"),
+    USER_PASSWD("user-passwd", "User plain password"),
     USE_KEYTAB("-k", "use keytab"),
     USE_DFT_KEYTAB("-i", "use default client keytab (with -k)"),
     USER_KEYTAB_FILE("-t", "filename of keytab to use", KOptionType.STR),

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/lib/kerby-util/src/main/java/org/apache/kerby/KOption.java
----------------------------------------------------------------------
diff --git a/lib/kerby-util/src/main/java/org/apache/kerby/KOption.java b/lib/kerby-util/src/main/java/org/apache/kerby/KOption.java
new file mode 100644
index 0000000..52f185d
--- /dev/null
+++ b/lib/kerby-util/src/main/java/org/apache/kerby/KOption.java
@@ -0,0 +1,41 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby;
+
+public interface KOption {
+
+    public void setType(KOptionType type);
+
+    public KOptionType getType();
+
+    public String getOptionName();
+
+    public void setName(String name);
+
+    public String getName();
+
+    public void setDescription(String description);
+
+    public String getDescription();
+
+    public void setValue(Object value);
+
+    public Object getValue();
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/lib/kerby-util/src/main/java/org/apache/kerby/KOptionType.java
----------------------------------------------------------------------
diff --git a/lib/kerby-util/src/main/java/org/apache/kerby/KOptionType.java b/lib/kerby-util/src/main/java/org/apache/kerby/KOptionType.java
new file mode 100644
index 0000000..e985131
--- /dev/null
+++ b/lib/kerby-util/src/main/java/org/apache/kerby/KOptionType.java
@@ -0,0 +1,34 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby;
+
+/**
+ * Option type.
+ */
+public enum KOptionType {
+    NONE,
+    NOV, // no value, a control flag
+    STR, // string value
+    INT, // integer value
+    BOOL, // boolean value
+    FILE, // file path value
+    DIR, // dir path value
+    OBJ  // arbitrary object
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/lib/kerby-util/src/main/java/org/apache/kerby/KOptions.java
----------------------------------------------------------------------
diff --git a/lib/kerby-util/src/main/java/org/apache/kerby/KOptions.java b/lib/kerby-util/src/main/java/org/apache/kerby/KOptions.java
new file mode 100644
index 0000000..d124582
--- /dev/null
+++ b/lib/kerby-util/src/main/java/org/apache/kerby/KOptions.java
@@ -0,0 +1,122 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A KOption container.
+ */
+public class KOptions {
+
+    private final Map<KOption, KOption> options =
+            new HashMap<KOption, KOption>();
+
+    public void add(KOption option) {
+        if (option != null) {
+            options.put(option, option);
+        }
+    }
+
+    public void add(KOption option, Object optionValue) {
+        if (option != null) {
+            option.setValue(optionValue);
+            add(option);
+        }
+    }
+
+    public boolean contains(KOption option) {
+        return options.containsKey(option);
+    }
+
+    public List<KOption> getOptions() {
+        return new ArrayList<>(options.keySet());
+    }
+
+    public KOption getOption(KOption option) {
+        if (! options.containsKey(option)) {
+            return null;
+        }
+
+        return options.get(option);
+    }
+
+    public Object getOptionValue(KOption option) {
+        if (! contains(option)) {
+            return null;
+        }
+        return options.get(option).getValue();
+    }
+
+    public String getStringOption(KOption option) {
+        Object value = getOptionValue(option);
+        if (value instanceof String) {
+            return (String) value;
+        }
+        return null;
+    }
+
+    public Boolean getBooleanOption(KOption option) {
+        Object value = getOptionValue(option);
+        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 null;
+    }
+
+    public int getIntegerOption(KOption option) {
+        Object value = getOptionValue(option);
+        if (value instanceof String) {
+            String strVal = (String) value;
+            return Integer.valueOf(strVal);
+        } else if (value instanceof Integer) {
+            return (Integer) value;
+        }
+        return -1;
+    }
+
+    public File getFileOption(KOption option) {
+        Object value = getOptionValue(option);
+        if (value instanceof File) {
+            return (File) value;
+        }
+        return null;
+    }
+
+    public File getDirOption(KOption option) {
+        Object value = getOptionValue(option);
+        if (value instanceof File) {
+            return (File) value;
+        }
+        return null;
+    }
+}


[2/2] directory-kerby git commit: DIRKRB-199. Support both blocking and event based network transport

Posted by dr...@apache.org.
DIRKRB-199. Support both blocking and event based network transport


Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/ff0200f8
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/ff0200f8
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/ff0200f8

Branch: refs/heads/master
Commit: ff0200f8bb71a9e265e1339589aa773508371f21
Parents: bf116de
Author: Drankye <dr...@gmail.com>
Authored: Sun Mar 29 22:19:14 2015 +0800
Committer: Drankye <dr...@gmail.com>
Committed: Sun Mar 29 22:19:14 2015 +0800

----------------------------------------------------------------------
 README.md                                       |  30 --
 ...kinit-1.0-SNAPSHOT-jar-with-dependencies.jar | Bin 3510337 -> 0 bytes
 .../org/apache/kerby/kerberos/kdc/KdcTest.java  |  15 +-
 .../kerby/kerberos/kdc/WithCertKdcTest.java     |   4 +-
 .../kerby/kerberos/kdc/WithTokenKdcTest.java    |   4 +-
 .../kerby/kerberos/kerb/client/KOption.java     |  41 --
 .../kerby/kerberos/kerb/client/KOptionType.java |  33 --
 .../kerby/kerberos/kerb/client/KOptions.java    | 104 -----
 .../kerby/kerberos/kerb/client/KrbClient.java   | 378 +++++--------------
 .../kerby/kerberos/kerb/client/KrbHandler.java  |  99 -----
 .../kerby/kerberos/kerb/client/KrbOption.java   |  33 +-
 .../kerb/client/event/KrbClientEvent.java       |  43 ---
 .../kerb/client/event/KrbClientEventType.java   |  29 --
 .../client/impl/AbstractInternalKrbClient.java  | 181 +++++++++
 .../kerb/client/impl/InternalKrbClient.java     |  62 +++
 .../impl/blocking/BlockModeKrbClient.java       |  80 ++++
 .../impl/blocking/BlockingKrbHandler.java       |  72 ++++
 .../impl/blocking/KrbCombinedTransport.java     |  74 ++++
 .../client/impl/blocking/KrbTcpTransport.java   |  91 +++++
 .../client/impl/blocking/KrbUdpTransport.java   |  57 +++
 .../client/impl/event/EventBasedKrbClient.java  | 142 +++++++
 .../kerb/client/impl/event/EventKrbHandler.java |  97 +++++
 .../kerb/client/impl/event/KrbClientEvent.java  |  43 +++
 .../client/impl/event/KrbClientEventType.java   |  29 ++
 .../client/preauth/AbstractPreauthPlugin.java   |   2 +-
 .../kerb/client/preauth/KrbPreauth.java         |   2 +-
 .../kerb/client/preauth/PreauthHandle.java      |   2 +-
 .../kerb/client/preauth/PreauthHandler.java     |   2 +-
 .../client/preauth/pkinit/PkinitPreauth.java    |   2 +-
 .../kerb/client/preauth/token/TokenPreauth.java |   4 +-
 .../kerb/client/request/ArmoredAsRequest.java   |   2 +-
 .../kerb/client/request/AsRequestWithCert.java  |   2 +-
 .../client/request/AsRequestWithKeytab.java     |  13 +-
 .../kerb/client/request/AsRequestWithToken.java |   4 +-
 .../kerb/client/request/KdcRequest.java         |  12 +-
 .../kerb/client/request/TgsRequest.java         |   4 +
 .../client/request/TgsRequestWithToken.java     |  36 ++
 .../kerby/kerberos/kerb/common/KrbUtil.java     |  34 +-
 .../kerb/transport/AbstractKrbTransport.java    |  38 ++
 .../kerberos/kerb/transport/KrbTransport.java   |  53 +++
 .../kerby/kerberos/kerb/server/KdcTest.java     |  15 +-
 .../kerby/kerberos/kerb/server/KdcHandler.java  |   4 +-
 .../apache/kerby/kerberos/tool/ToolUtil.java    |   6 +-
 .../apache/kerby/kerberos/tool/kinit/Kinit.java |  32 +-
 .../kerby/kerberos/tool/kinit/KinitOption.java  |   6 +-
 .../src/main/java/org/apache/kerby/KOption.java |  41 ++
 .../main/java/org/apache/kerby/KOptionType.java |  34 ++
 .../main/java/org/apache/kerby/KOptions.java    | 122 ++++++
 48 files changed, 1468 insertions(+), 745 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 253cc3c..3ef35f5 100644
--- a/README.md
+++ b/README.md
@@ -17,36 +17,6 @@ Apache Kerby is a Java Kerberos binding. It provides a rich, intuitive and inter
 + Provides support for JAAS, GSSAPI and SASL frameworks that applications can leverage.
 + Minimal dependencies, the core part is ensured to depend only on JRE and SLF4J, for easy use and maintenance.
 
-### KrbClient APIs
-* Initiate a KrbClient
-<pre>
-KrbClient krbClient = new KrbClient(kdcHost, kdcPort);
-</pre>
-* Request a TGT with user plain password credential
-<pre>
-krbClient.requestTgtTicket(principal, password);
-</pre>
-* Request a TGT with a keytab file
-<pre>
-krbClient.requestTgtTicket(principal, keytab);
-</pre>
-* Request a TGT with user x509 certificate credential
-<pre>
-krbClient.requestTgtTicket(principal, certificate);
-</pre>
-* Request a TGT with user token credential
-<pre>
-krbClient.requestTgtTicket(principal, kerbToken);
-</pre>
-* Request a service ticket with user TGT credential for a server
-<pre>
-krbClient.requestServiceTicket(tgt, serverPrincipal);
-</pre>
-* Request a service ticket with user AccessToken credential for a server
-<pre>
-krbClient.requestServiceTicket(accessToken, serverPrincipal);
-</pre>
-
 ### ASN-1 support
 Please look at [kerby-asn1](kerby-asn1/) for details.
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kdc-tool/kinit/kinit-dist/kinit/kinit-1.0-SNAPSHOT-jar-with-dependencies.jar
----------------------------------------------------------------------
diff --git a/kdc-tool/kinit/kinit-dist/kinit/kinit-1.0-SNAPSHOT-jar-with-dependencies.jar b/kdc-tool/kinit/kinit-dist/kinit/kinit-1.0-SNAPSHOT-jar-with-dependencies.jar
deleted file mode 100644
index ff44e4f..0000000
Binary files a/kdc-tool/kinit/kinit-dist/kinit/kinit-1.0-SNAPSHOT-jar-with-dependencies.jar and /dev/null differ

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/KdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/KdcTest.java b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/KdcTest.java
index 56e4a92..559b785 100644
--- a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/KdcTest.java
+++ b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/KdcTest.java
@@ -52,10 +52,10 @@ public abstract class KdcTest extends KdcTestBase {
 
         // With good password
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, password, null);
+            tgt = krbClnt.requestTgtWithPassword(clientPrincipal, password);
             assertThat(tgt).isNotNull();
 
-            tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+            tkt = krbClnt.requestServiceTicketWithTgt(tgt, serverPrincipal);
             assertThat(tkt).isNotNull();
         } catch (Exception e) {
             System.out.println("Exception occurred with good password");
@@ -65,23 +65,22 @@ public abstract class KdcTest extends KdcTestBase {
 
         // With bad password
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, "badpassword", null);
+            tgt = krbClnt.requestTgtWithPassword(clientPrincipal, "badpassword");
         } catch (Exception e) {
             System.out.println("Exception occurred with bad password");
         }
 
-        // TODO: With good password again. This will fail, to be investigated.
-        /*
+        // With good password again
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, password, null);
+            tgt = krbClnt.requestTgtWithPassword(clientPrincipal, password);
             assertThat(tgt).isNotNull();
 
-            tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+            tkt = krbClnt.requestServiceTicketWithTgt(tgt, serverPrincipal);
             assertThat(tkt).isNotNull();
         } catch (Exception e) {
             System.out.println("Exception occurred with good password again");
             e.printStackTrace();
             Assert.fail();
-        }*/
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
index 5df9495..b211f68 100644
--- a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
+++ b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithCertKdcTest.java
@@ -80,14 +80,14 @@ public class WithCertKdcTest extends KdcTestBase {
 
         TgtTicket tgt = null;
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, userCert, userKey, null);
+            tgt = krbClnt.requestTgtWithCert(clientPrincipal, userCert, userKey);
         } catch (KrbException te) {
             assertThat(te.getMessage().contains("timeout")).isTrue();
             return;
         }
         assertThat(tgt).isNull();
 
-        ServiceTicket tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+        ServiceTicket tkt = krbClnt.requestServiceTicketWithTgt(tgt, serverPrincipal);
         assertThat(tkt).isNull();
     }
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTest.java b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTest.java
index e8f6a5a..6442323 100644
--- a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTest.java
+++ b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTest.java
@@ -94,14 +94,14 @@ public class WithTokenKdcTest extends KdcTestBase {
 
         TgtTicket tgt;
         try {
-            tgt = krbClnt.requestTgtTicket(clientPrincipal, authToken, null);
+            tgt = krbClnt.requestTgtWithToken(authToken);
         } catch (KrbException te) {
             assertThat(te.getMessage().contains("timeout")).isTrue();
             return;
         }
         assertThat(tgt).isNull();
 
-        ServiceTicket tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+        ServiceTicket tkt = krbClnt.requestServiceTicketWithTgt(tgt, serverPrincipal);
         assertThat(tkt).isNull();
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOption.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOption.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOption.java
deleted file mode 100644
index 6a85ad6..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOption.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.client;
-
-public interface KOption {
-
-    public void setType(KOptionType type);
-
-    public KOptionType getType();
-
-    public String getOptionName();
-
-    public void setName(String name);
-
-    public String getName();
-
-    public void setDescription(String description);
-
-    public String getDescription();
-
-    public void setValue(Object value);
-
-    public Object getValue();
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptionType.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptionType.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptionType.java
deleted file mode 100644
index fd83aeb..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptionType.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.client;
-
-/**
- * Option type.
- */
-public enum KOptionType {
-    NONE,
-    NOV, // no value, a control flag
-    STR, // string value
-    INT, // integer value
-    BOOL, // boolean value
-    FILE, // file path value
-    DIR // dir path value
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptions.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptions.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptions.java
deleted file mode 100644
index c196065..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KOptions.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.client;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A KOption container.
- */
-public class KOptions {
-
-    private final Map<KOption, KOption> options =
-            new HashMap<KOption, KOption>();
-
-    public void add(KOption option) {
-        if (option != null) {
-            options.put(option, option);
-        }
-    }
-
-    public void add(KOption option, Object optionValue) {
-        if (option != null) {
-            option.setValue(optionValue);
-            add(option);
-        }
-    }
-
-    public boolean contains(KOption option) {
-        return options.containsKey(option);
-    }
-
-    public List<KOption> getOptions() {
-        return new ArrayList<>(options.keySet());
-    }
-
-    public KOption getOption(KOption option) {
-        if (! options.containsKey(option)) {
-            return null;
-        }
-
-        return options.get(option);
-    }
-
-    public Object getOptionValue(KOption option) {
-        if (! contains(option)) {
-            return null;
-        }
-        return options.get(option).getValue();
-    }
-
-    public String getStringOption(KOption option) {
-        Object value = getOptionValue(option);
-        if (value instanceof String) {
-            return (String) value;
-        }
-        return null;
-    }
-
-    public boolean getBooleanOption(KOption option) {
-        Object value = getOptionValue(option);
-        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(KOption option) {
-        Object value = getOptionValue(option);
-        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-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
index 29c4815..67bc7d7 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbClient.java
@@ -19,51 +19,27 @@
  */
 package org.apache.kerby.kerberos.kerb.client;
 
-import org.apache.kerby.event.Event;
-import org.apache.kerby.event.EventHub;
-import org.apache.kerby.event.EventWaiter;
-import org.apache.kerby.kerberos.kerb.KrbErrorCode;
-import org.apache.kerby.kerberos.kerb.KrbErrorException;
+import org.apache.kerby.KOptions;
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.client.event.KrbClientEvent;
-import org.apache.kerby.kerberos.kerb.client.event.KrbClientEventType;
-import org.apache.kerby.kerberos.kerb.client.request.*;
-import org.apache.kerby.kerberos.kerb.common.KrbErrorUtil;
-import org.apache.kerby.kerberos.kerb.common.KrbStreamingDecoder;
-import org.apache.kerby.kerberos.kerb.spec.base.KrbError;
-import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+import org.apache.kerby.kerberos.kerb.client.impl.blocking.BlockModeKrbClient;
+import org.apache.kerby.kerberos.kerb.client.impl.event.EventBasedKrbClient;
+import org.apache.kerby.kerberos.kerb.client.impl.InternalKrbClient;
+import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
 import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
 import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
-import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
-import org.apache.kerby.transport.Network;
-import org.apache.kerby.transport.Transport;
-import org.apache.kerby.transport.event.TransportEvent;
-import org.apache.kerby.transport.event.TransportEventType;
 
 import java.io.File;
 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
+ * 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 String kdcHost;
-    private int kdcTcpPort;
-    private Boolean allowUdp;
-    private int kdcUdpPort;
-    private KrbConfig krbConfig;
-    private File confDir;
+    private KOptions commonOptions;
+    private InternalKrbClient innerClient;
 
     /**
      * Default constructor.
@@ -73,45 +49,12 @@ public class KrbClient {
     }
 
     /**
-     * Construct a KrbClient with host and port. The port can be TCP, UDP or
-     * both, but TCP will try first.
-     * @param kdcHost
-     * @param kdcPort
-     */
-    public KrbClient(String kdcHost, int kdcPort) {
-        this(new KrbConfig());
-
-        setKdcHost(kdcHost);
-        setKdcTcpPort(kdcPort);
-        setKdcUdpPort(kdcPort);
-    }
-
-    /**
-     * Construct with prepared KrbConfig
+     * Construct with prepared KrbConfig.
      * @param krbConfig
      */
     public KrbClient(KrbConfig krbConfig) {
-        this.krbConfig = krbConfig;
-        this.context = new KrbContext();
-        context.init(krbConfig);
-    }
-
-    /**
-     * Prepare krb config, loading krb5.conf.
-     * It can be override to add more configuration resources.
-     *
-     * @throws IOException
-     */
-    protected void initConfig() throws IOException {
-        if (confDir == null) {
-            confDir = new File("/etc/"); // for Linux. TODO: fix for Win etc.
-        }
-        if (confDir != null && confDir.exists()) {
-            File kdcConfFile = new File(confDir, "krb5.conf");
-            if (kdcConfFile.exists()) {
-                krbConfig.addIniConfig(kdcConfFile);
-            }
-        }
+        commonOptions = new KOptions();
+        commonOptions.add(KrbOption.KRB_CONFIG, krbConfig);
     }
 
     /**
@@ -119,7 +62,7 @@ public class KrbClient {
      * @param file
      */
     public void setConfDir(File file) throws IOException {
-        confDir = file;
+        commonOptions.add(KrbOption.CONF_DIR, file);
     }
 
     /**
@@ -127,35 +70,7 @@ public class KrbClient {
      * @param realm
      */
     public void setKdcRealm(String realm) {
-        context.setKdcRealm(realm);
-    }
-
-    private String getKdcHost() {
-        if (kdcHost != null) {
-            return kdcHost;
-        }
-        return krbConfig.getKdcHost();
-    }
-
-    private int getKdcTcpPort() {
-        if (kdcTcpPort > 0) {
-            return kdcTcpPort;
-        }
-        return krbConfig.getKdcTcpPort();
-    }
-
-    private boolean allowUdp() {
-        if (allowUdp != null) {
-            return allowUdp;
-        }
-        return krbConfig.allowKdcUdp();
-    }
-
-    private int getKdcUdpPort() {
-        if (kdcUdpPort > 0) {
-            return kdcUdpPort;
-        }
-        return krbConfig.getKdcUdpPort();
+        commonOptions.add(KrbOption.KDC_REALM, realm);
     }
 
     /**
@@ -163,7 +78,7 @@ public class KrbClient {
      * @param kdcHost
      */
     public void setKdcHost(String kdcHost) {
-        this.kdcHost = kdcHost;
+        commonOptions.add(KrbOption.KDC_HOST, kdcHost);
     }
 
     /**
@@ -171,7 +86,7 @@ public class KrbClient {
      * @param kdcTcpPort
      */
     public void setKdcTcpPort(int kdcTcpPort) {
-        this.kdcTcpPort = kdcTcpPort;
+        commonOptions.add(KrbOption.KDC_TCP_PORT, kdcTcpPort);
     }
 
     /**
@@ -179,7 +94,7 @@ public class KrbClient {
      * @param allowUdp
      */
     public void setAllowUdp(boolean allowUdp) {
-        this.allowUdp = allowUdp;
+        commonOptions.add(KrbOption.ALLOW_UDP, allowUdp);
     }
 
     /**
@@ -187,92 +102,69 @@ public class KrbClient {
      * @param kdcUdpPort
      */
     public void setKdcUdpPort(int kdcUdpPort) {
-        this.kdcUdpPort = kdcUdpPort;
+        commonOptions.add(KrbOption.KDC_UDP_PORT, kdcUdpPort);
     }
 
     /**
      * Set time out for connection
      * @param timeout in seconds
      */
-    public void setTimeout(long timeout) {
-        context.setTimeout(timeout);
+    public void setTimeout(int timeout) {
+        commonOptions.add(KrbOption.CONN_TIMEOUT, timeout);
     }
 
-    public void init() {
-        try {
-            initConfig();
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to load config", e);
-        }
-
-        this.krbHandler = new KrbHandler();
-        krbHandler.init(context);
-
-        this.eventHub = new EventHub();
-        eventHub.register(krbHandler);
-
-        Network network = new Network();
-        network.setStreamingDecoder(new KrbStreamingDecoder());
-        eventHub.register(network);
-
-        eventWaiter = eventHub.waitEvent(
-                TransportEventType.NEW_TRANSPORT,
-                KrbClientEventType.TGT_RESULT,
-                KrbClientEventType.TKT_RESULT
-        );
-
-        eventHub.start();
-
-        network.tcpConnect(getKdcHost(), getKdcTcpPort());
-        if (allowUdp()) {
-            network.udpConnect(getKdcHost(), getKdcUdpPort());
-        }
-        Event event = eventWaiter.waitEvent(TransportEventType.NEW_TRANSPORT);
-        transport = ((TransportEvent) event).getTransport();
+    /**
+     * Use event model. By default blocking model is used.
+     */
+    public void useEventModel() {
+        commonOptions.add(KrbOption.USE_EVENT_MODEL);
     }
 
     /**
-     * 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
+     * Init the client.
      * @throws KrbException
      */
-    public TgtTicket requestTgtTicket(String principal,
-                                      KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
-        }
-
-        AsRequest asRequest;
-        if (options.contains(KrbOption.USE_KEYTAB)) {
-            asRequest = new AsRequestWithKeytab(context);
+    public void init() throws KrbException {
+        if (commonOptions.contains(KrbOption.USE_EVENT_MODEL)) {
+            innerClient = new EventBasedKrbClient();
         } else {
-            asRequest = new AsRequest(context);
+            innerClient = new BlockModeKrbClient();
         }
-
-        asRequest.setKrbOptions(options);
-        return requestTgtTicket(principal, asRequest);
+        innerClient.init(commonOptions);
     }
 
     /**
      * Request a TGT with user plain credential
      * @param principal
      * @param password
-     * @param options
      * @return
      * @throws KrbException
      */
-    public TgtTicket requestTgtTicket(String principal, String password,
-                                      KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
-        }
+    public TgtTicket requestTgtWithPassword(String principal,
+                                      String password) throws KrbException {
 
-        AsRequest asRequest = new AsRequestWithPasswd(context);
-        options.add(KrbOption.USER_PASSWD, password);
-        asRequest.setKrbOptions(options);
-        return requestTgtTicket(principal, asRequest);
+        KOptions requestOptions = new KOptions();
+        requestOptions.add(KrbOption.CLIENT_PRINCIPAL, principal);
+        requestOptions.add(KrbOption.USE_PASSWD, true);
+        requestOptions.add(KrbOption.USER_PASSWD, password);
+        return requestTgtWithOptions(requestOptions);
+    }
+
+    /**
+     * Request a TGT with user plain credential
+     * @param principal
+     * @param keytabFile
+     * @return TGT
+     * @throws KrbException
+     */
+    public TgtTicket requestTgtWithKeytab(String principal,
+                                      String keytabFile) throws KrbException {
+
+        KOptions requestOptions = new KOptions();
+        requestOptions.add(KrbOption.CLIENT_PRINCIPAL, principal);
+        requestOptions.add(KrbOption.USE_KEYTAB, true);
+        requestOptions.add(KrbOption.KEYTAB_FILE, keytabFile);
+        return requestTgtWithOptions(requestOptions);
     }
 
     /**
@@ -280,167 +172,81 @@ public class KrbClient {
      * @param principal
      * @param certificate
      * @param privateKey
-     * @param options
-     * @return
+     * @return TGT
      * @throws KrbException
      */
-    public TgtTicket requestTgtTicket(
-            String principal, Certificate certificate, PrivateKey privateKey,
-            KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
-        }
-
-        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);
+    public TgtTicket requestTgtWithCert(String principal, Certificate certificate,
+                                        PrivateKey privateKey) throws KrbException {
+        KOptions requestOptions = new KOptions();
+        requestOptions.add(KrbOption.PKINIT_X509_CERTIFICATE, certificate);
+        requestOptions.add(KrbOption.PKINIT_X509_PRIVATE_KEY, privateKey);
+        return requestTgtWithOptions(requestOptions);
     }
 
     /**
      * Request a TGT with using Anonymous PKINIT
-     * @param options
-     * @return
+     * @return TGT
      * @throws KrbException
      */
-    public TgtTicket requestTgtTicket(KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
-        }
-
-        AsRequestWithCert asRequest = new AsRequestWithCert(context);
-        options.add(KrbOption.PKINIT_X509_ANONYMOUS);
-        asRequest.setKrbOptions(options);
-
-        String principal = AsRequestWithCert.ANONYMOUS_PRINCIPAL;
-        return requestTgtTicket(principal, asRequest);
+    public TgtTicket requestTgtWithPkintAnonymous() throws KrbException {
+        KOptions requestOptions = new KOptions();
+        requestOptions.add(KrbOption.USE_PKINIT_ANONYMOUS);
+        return requestTgtWithOptions(requestOptions);
     }
 
     /**
      * Request a TGT with user token credential
-     * @param principal
      * @param token
-     * @param options
-     * @return
+     * @return TGT
      * @throws KrbException
      */
-    public TgtTicket requestTgtTicket(String principal, AuthToken token,
-                                      KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
+    public TgtTicket requestTgtWithToken(AuthToken token) throws KrbException {
+        if (! token.isIdToken()) {
+            throw new IllegalArgumentException("Identity token is expected");
         }
 
-        AsRequestWithToken asRequest = new AsRequestWithToken(context);
-        options.add(KrbOption.TOKEN_USER_ID_TOKEN, token);
-        asRequest.setKrbOptions(options);
-        return requestTgtTicket(principal, asRequest);
+        KOptions requestOptions = new KOptions();
+        requestOptions.add(KrbOption.TOKEN_USER_ID_TOKEN, token);
+        return requestTgtWithOptions(requestOptions);
     }
 
     /**
-     * Request a service ticket targeting for a server with user plain credentials
-     * @param clientPrincipal
-     * @param password
-     * @param serverPrincipal
-     * @param options
-     * @return
+     * Request a TGT with using well prepared requestOptions.
+     * @param requestOptions
+     * @return TGT
      * @throws KrbException
      */
-    public ServiceTicket requestServiceTicket(
-            String clientPrincipal, String password, String serverPrincipal,
-            KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
+    public TgtTicket requestTgtWithOptions(KOptions requestOptions) throws KrbException {
+        if (requestOptions == null) {
+            throw new IllegalArgumentException("Null KrbOptions specified");
         }
 
-        TgtTicket tgt = requestTgtTicket(clientPrincipal, password, options);
-        return requestServiceTicket(tgt, serverPrincipal, options);
+        return innerClient.requestTgtTicket(requestOptions);
     }
 
     /**
-     * Request a service ticket targeting for a server with an user Access Token
-     * @param clientPrincipal
-     * @param token
+     * Request a service ticket with a TGT targeting for a server
+     * @param tgt
      * @param serverPrincipal
-     * @param options
      * @return
      * @throws KrbException
      */
-    public ServiceTicket requestServiceTicket(
-            String clientPrincipal, AuthToken token, String serverPrincipal,
-            KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
-        }
-
-        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;
-        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();
+    public ServiceTicket requestServiceTicketWithTgt(
+            TgtTicket tgt, String serverPrincipal) throws KrbException {
+        return innerClient.requestServiceTicketWithTgt(tgt, serverPrincipal);
     }
 
     /**
-     * Request a service ticket with a TGT targeting for a server
-     * @param tgt
-     * @param serverPrincipal
-     * @return
+     * Request a service ticket using an Access Token.
+     * @return service ticket
      * @throws KrbException
      */
-    public ServiceTicket requestServiceTicket(TgtTicket tgt, String serverPrincipal,
-                                              KOptions options) throws KrbException {
-        if (options == null) {
-            options = new KOptions();
+    public ServiceTicket requestServiceTicketWithAccessToken(
+            AuthToken token, String serverPrincipal) throws KrbException {
+        if (! token.isAcToken()) {
+            throw new IllegalArgumentException("Access token is expected");
         }
-
-        TgsRequest ticketReq = new TgsRequest(context, tgt);
-        ticketReq.setServerPrincipal(new PrincipalName(serverPrincipal));
-        ticketReq.setTransport(transport);
-
-        eventHub.dispatch(KrbClientEvent.createTktIntentEvent(ticketReq));
-        Event resultEvent;
-        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();
+        return innerClient.requestServiceTicketWithAccessToken(token, serverPrincipal);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java
deleted file mode 100644
index 2037f76..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbHandler.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.client;
-
-import org.apache.kerby.event.AbstractEventHandler;
-import org.apache.kerby.event.Event;
-import org.apache.kerby.event.EventType;
-import org.apache.kerby.kerberos.kerb.client.event.KrbClientEvent;
-import org.apache.kerby.kerberos.kerb.client.event.KrbClientEventType;
-import org.apache.kerby.kerberos.kerb.client.preauth.PreauthHandler;
-import org.apache.kerby.kerberos.kerb.client.request.AsRequest;
-import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
-import org.apache.kerby.kerberos.kerb.client.request.TgsRequest;
-import org.apache.kerby.kerberos.kerb.common.KrbUtil;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.spec.base.KrbMessage;
-import org.apache.kerby.kerberos.kerb.spec.base.KrbMessageType;
-import org.apache.kerby.kerberos.kerb.spec.kdc.KdcRep;
-import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
-import org.apache.kerby.transport.Transport;
-import org.apache.kerby.transport.event.MessageEvent;
-import org.apache.kerby.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-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbOption.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbOption.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbOption.java
index 3e6740b..2eb5ad3 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbOption.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/KrbOption.java
@@ -19,8 +19,21 @@
  */
 package org.apache.kerby.kerberos.kerb.client;
 
+import org.apache.kerby.KOption;
+import org.apache.kerby.KOptionType;
+
 public enum KrbOption implements KOption {
     NONE("NONE"),
+    USE_EVENT_MODEL("use event model", KOptionType.NOV),
+    CLIENT_PRINCIPAL("client-principal", "Client principal", KOptionType.STR),
+    KRB_CONFIG("krb config", KOptionType.OBJ),
+    CONF_DIR("conf dir", KOptionType.DIR),
+    KDC_REALM("kdc realm", KOptionType.STR),
+    KDC_HOST("kdc host", KOptionType.STR),
+    KDC_TCP_PORT("kdc tcp port", KOptionType.INT),
+    ALLOW_UDP("allow udp", KOptionType.BOOL),
+    KDC_UDP_PORT("kdc udp port", KOptionType.INT),
+    CONN_TIMEOUT("connection timeout", KOptionType.INT),
     LIFE_TIME("life time", KOptionType.INT),
     START_TIME("start time", KOptionType.INT),
     RENEWABLE_TIME("renewable lifetime", KOptionType.INT),
@@ -35,24 +48,28 @@ public enum KrbOption implements KOption {
     RENEW("renew"),
     CANONICALIZE("canonicalize"),
     AS_ENTERPRISE_PN("as-enterprise-pn", "client is enterprise principal name"),
+
+    USE_PASSWD("using password", "using password"),
+    USER_PASSWD("user-passwd", "User plain password"),
+
     USE_KEYTAB("use-keytab", "use keytab"),
-    USE_DFT_KEYTAB("user-default-keytab", "use default client keytab"),
-    USER_KEYTAB_FILE("user-keytab-file", "filename of keytab to use", KOptionType.FILE),
+    USE_DFT_KEYTAB("-i", "use default client keytab (with -k)"),
+    KEYTAB_FILE("keytab-file", "filename of keytab to use", KOptionType.FILE),
+
     KRB5_CACHE("krb5-cache", "K5 cache name", KOptionType.FILE),
-    SERVICE("service", KOptionType.STR),
+    SERVICE_PRINCIPAL("service-principal", "service principal", KOptionType.STR),
     ARMOR_CACHE("armor-cache", "armor credential cache", KOptionType.STR),
 
-    CONF_DIR("conf dir", KOptionType.DIR),
-    USER_PASSWD("user-passwd", "User plain password"),
-
+    USE_PKINIT("use-pkinit", "using pkinit"),
     PKINIT_X509_IDENTITY("x509-identities", "X509 user private key and cert", KOptionType.STR),
     PKINIT_X509_PRIVATE_KEY("x509-privatekey", "X509 user private key", KOptionType.STR),
     PKINIT_X509_CERTIFICATE("x509-cert", "X509 user certificate", KOptionType.STR),
     PKINIT_X509_ANCHORS("x509-anchors", "X509 anchors", KOptionType.STR),
-    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"),
+    USE_PKINIT_ANONYMOUS("use-pkinit-anonymous", "X509 anonymous"),
+
+    USE_TOKEN("use-id-token", "Using identity token"),
     TOKEN_USER_ID_TOKEN("user-id-token", "User identity token", KOptionType.STR),
     TOKEN_USER_AC_TOKEN("user-ac-token", "User access token", KOptionType.STR),
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEvent.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEvent.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEvent.java
deleted file mode 100644
index 291b33e..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEvent.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.client.event;
-
-import org.apache.kerby.event.Event;
-import org.apache.kerby.kerberos.kerb.client.request.AsRequest;
-import org.apache.kerby.kerberos.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);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEventType.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEventType.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEventType.java
deleted file mode 100644
index 78fd424..0000000
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/event/KrbClientEventType.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.client.event;
-
-import org.apache.kerby.event.EventType;
-
-public enum KrbClientEventType implements EventType {
-    TGT_INTENT,
-    TGT_RESULT,
-    TKT_INTENT,
-    TKT_RESULT
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
new file mode 100644
index 0000000..c316b15
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
@@ -0,0 +1,181 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl;
+
+import org.apache.kerby.KOptions;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.client.KrbConfig;
+import org.apache.kerby.kerberos.kerb.client.KrbContext;
+import org.apache.kerby.kerberos.kerb.client.KrbOption;
+import org.apache.kerby.kerberos.kerb.client.request.*;
+import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
+import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * A krb client API for applications to interact with KDC
+ */
+public abstract class AbstractInternalKrbClient implements InternalKrbClient {
+    private KrbContext context;
+    private KrbConfig krbConfig;
+    private KOptions commonOptions;
+
+    protected KrbContext getContext() {
+        return context;
+    }
+
+    /**
+     * Prepare krb config, loading krb5.conf.
+     * It can be override to add more configuration resources.
+     *
+     * @throws java.io.IOException
+     */
+    protected void initConfig() throws IOException {
+        this.krbConfig = (KrbConfig) commonOptions.getOptionValue(KrbOption.KRB_CONFIG);
+        if (krbConfig == null) {
+            krbConfig = new KrbConfig();
+        }
+
+        File confDir = getConfDir();
+        if (confDir == null) {
+            confDir = new File("/etc/"); // for Linux. TODO: fix for Win etc.
+        }
+        if (confDir != null && confDir.exists()) {
+            File kdcConfFile = new File(confDir, "krb5.conf");
+            if (kdcConfFile.exists()) {
+                krbConfig.addIniConfig(kdcConfFile);
+            }
+        }
+    }
+
+    protected File getConfDir() {
+        return  commonOptions.getDirOption(KrbOption.CONF_DIR);
+    }
+
+    protected String getKdcHost() {
+        String kdcHost = commonOptions.getStringOption(KrbOption.KDC_HOST);
+        if (kdcHost == null) {
+            return krbConfig.getKdcHost();
+        }
+        return kdcHost;
+    }
+
+    protected int getKdcTcpPort() {
+        int tcpPort = commonOptions.getIntegerOption(KrbOption.KDC_TCP_PORT);
+        if (tcpPort > 0) {
+            return tcpPort;
+        }
+        return krbConfig.getKdcTcpPort();
+    }
+
+    protected boolean allowUdp() {
+        Boolean allowUdp = commonOptions.getBooleanOption(KrbOption.ALLOW_UDP);
+        if (allowUdp != null) {
+            return allowUdp;
+        }
+        return krbConfig.allowKdcUdp();
+    }
+
+    protected int getKdcUdpPort() {
+        int udpPort = commonOptions.getIntegerOption(KrbOption.KDC_UDP_PORT);
+        if (udpPort > 0) {
+            return udpPort;
+        }
+        return krbConfig.getKdcUdpPort();
+    }
+
+    protected int getTimeout() {
+        int timeout = commonOptions.getIntegerOption(KrbOption.CONN_TIMEOUT);
+        if (timeout > 0) {
+            return timeout;
+        }
+        return 1000; // by default
+    }
+
+    @Override
+    public void init(KOptions commonOptions) throws KrbException {
+        this.commonOptions = commonOptions;
+
+        try {
+            initConfig();
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to load config", e);
+        }
+
+        this.context = new KrbContext();
+        context.init(krbConfig);
+    }
+
+    @Override
+    public TgtTicket requestTgtTicket(KOptions requestOptions) throws KrbException {
+        AsRequest asRequest = null;
+
+        if (requestOptions.contains(KrbOption.USE_PASSWD)) {
+            asRequest = new AsRequestWithPasswd(context);
+        } else if (requestOptions.contains(KrbOption.USE_KEYTAB)) {
+            asRequest = new AsRequestWithKeytab(context);
+        } else if (requestOptions.contains(KrbOption.USE_PKINIT_ANONYMOUS)) {
+            asRequest = new AsRequestWithCert(context);
+        } else if (requestOptions.contains(KrbOption.USE_PKINIT)) {
+            asRequest = new AsRequestWithCert(context);
+        } else if (requestOptions.contains(KrbOption.USE_TOKEN)) {
+            asRequest = new AsRequestWithToken(context);
+        }
+
+        if (asRequest == null) {
+            throw new IllegalArgumentException(
+                    "No valid krb client request option found");
+        }
+        if (requestOptions.contains(KrbOption.CLIENT_PRINCIPAL)) {
+            String principal = requestOptions.getStringOption(
+                    KrbOption.CLIENT_PRINCIPAL);
+            asRequest.setClientPrincipal(new PrincipalName(principal));
+        }
+        asRequest.setKrbOptions(requestOptions);
+
+        return doRequestTgtTicket(asRequest);
+    }
+
+    @Override
+    public ServiceTicket requestServiceTicketWithTgt(
+            TgtTicket tgt, String serverPrincipal) throws KrbException {
+
+        TgsRequest ticketReq = new TgsRequest(context, tgt);
+        ticketReq.setServerPrincipal(new PrincipalName(serverPrincipal));
+        return doRequestServiceTicket(ticketReq);
+    }
+
+    @Override
+    public ServiceTicket requestServiceTicketWithAccessToken(
+            AuthToken token, String serverPrincipal) throws KrbException {
+        TgsRequest tgsRequest = new TgsRequestWithToken(context);
+        return doRequestServiceTicket(tgsRequest);
+    }
+
+    protected abstract TgtTicket doRequestTgtTicket(
+            AsRequest tgtTktReq) throws KrbException;
+
+    protected abstract ServiceTicket doRequestServiceTicket(
+            TgsRequest tgsRequest) throws KrbException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/InternalKrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/InternalKrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/InternalKrbClient.java
new file mode 100644
index 0000000..89ef8ac
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/InternalKrbClient.java
@@ -0,0 +1,62 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.KOptions;
+import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
+import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
+
+/**
+ * An internal krb client interface.
+ */
+public interface InternalKrbClient {
+
+    /**
+     * Init with all the necessary options.
+     * @param options
+     */
+    public void init(KOptions options) throws KrbException;
+
+    /**
+     * Request a Ticket Granting Ticket.
+     * @param requestOptions
+     * @return a TGT
+     * @throws KrbException
+     */
+    public TgtTicket requestTgtTicket(KOptions requestOptions) throws KrbException;
+
+    /**
+     * Request a service ticket using a TGT.
+     * @return service ticket
+     * @throws KrbException
+     */
+    public ServiceTicket requestServiceTicketWithTgt(TgtTicket tgt,
+                                              String serverPrincipal) throws KrbException;
+
+    /**
+     * Request a service ticket using an Access Token.
+     * @return service ticket
+     * @throws KrbException
+     */
+    public ServiceTicket requestServiceTicketWithAccessToken(AuthToken token,
+                                              String serverPrincipal) throws KrbException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockModeKrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockModeKrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockModeKrbClient.java
new file mode 100644
index 0000000..db32186
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockModeKrbClient.java
@@ -0,0 +1,80 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.blocking;
+
+import org.apache.kerby.KOptions;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.client.KrbConfig;
+import org.apache.kerby.kerberos.kerb.client.impl.AbstractInternalKrbClient;
+import org.apache.kerby.kerberos.kerb.client.request.AsRequest;
+import org.apache.kerby.kerberos.kerb.client.request.TgsRequest;
+import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+/**
+ * An event based krb client implementation.
+ */
+public class BlockModeKrbClient extends AbstractInternalKrbClient {
+
+    private BlockingKrbHandler krbHandler;
+    private KrbTransport transport;
+
+    @Override
+    public void init(KOptions commonOptions) throws KrbException {
+        super.init(commonOptions);
+
+        this.krbHandler = new BlockingKrbHandler();
+        krbHandler.init(getContext());
+
+        InetSocketAddress tcpAddress, udpAddress = null;
+        tcpAddress=  new InetSocketAddress(getKdcHost(), getKdcTcpPort());
+        if (allowUdp()) {
+            udpAddress = new InetSocketAddress(getKdcHost(), getKdcUdpPort());
+        }
+        try {
+            transport = new KrbCombinedTransport(tcpAddress, udpAddress);
+        } catch (IOException e) {
+            throw new KrbException("Failed to create transport", e);
+        }
+    }
+
+    @Override
+    protected TgtTicket doRequestTgtTicket(AsRequest tgtTktReq) throws KrbException {
+        tgtTktReq.setTransport(transport);
+
+        krbHandler.handleRequest(tgtTktReq);
+
+        return tgtTktReq.getTicket();
+    }
+
+    @Override
+    protected ServiceTicket doRequestServiceTicket(TgsRequest ticketReq) throws KrbException {
+        ticketReq.setTransport(transport);
+
+        krbHandler.handleRequest(ticketReq);
+
+        return ticketReq.getServiceTicket();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockingKrbHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockingKrbHandler.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockingKrbHandler.java
new file mode 100644
index 0000000..2e9287b
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/BlockingKrbHandler.java
@@ -0,0 +1,72 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.blocking;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.client.KrbContext;
+import org.apache.kerby.kerberos.kerb.client.preauth.PreauthHandler;
+import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
+import org.apache.kerby.kerberos.kerb.common.KrbUtil;
+import org.apache.kerby.kerberos.kerb.spec.base.KrbMessage;
+import org.apache.kerby.kerberos.kerb.spec.base.KrbMessageType;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcRep;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class BlockingKrbHandler {
+
+    private PreauthHandler preauthHandler;
+
+    public void init(KrbContext context) {
+        preauthHandler = new PreauthHandler();
+        preauthHandler.init(context);
+    }
+
+    public void handleRequest(KdcRequest kdcRequest) throws KrbException {
+        kdcRequest.process();
+        KdcReq kdcReq = kdcRequest.getKdcReq();
+        KrbTransport transport = kdcRequest.getTransport();
+        transport.setAttachment(kdcRequest);
+        KrbMessage kdcRep = null;
+
+        try {
+            KrbUtil.sendMessage(kdcReq, transport);
+
+            ByteBuffer message = transport.receiveMessage();
+            if (message != null) {
+                kdcRep = KrbUtil.decodeMessage(message);
+            } else {
+                throw new KrbException("No valid response recved");
+            }
+        } catch (IOException e) {
+            throw new KrbException("Transport or decoding error occurred", e);
+        }
+
+        KrbMessageType messageType = kdcRep.getMsgType();
+        if (messageType == KrbMessageType.AS_REP) {
+            kdcRequest.processResponse((KdcRep) kdcRep);
+        } else if (messageType == KrbMessageType.TGS_REP) {
+            kdcRequest.processResponse((KdcRep) kdcRep);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbCombinedTransport.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbCombinedTransport.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbCombinedTransport.java
new file mode 100644
index 0000000..3e882fa
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbCombinedTransport.java
@@ -0,0 +1,74 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.blocking;
+
+import org.apache.kerby.kerberos.kerb.transport.AbstractKrbTransport;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * Default implementation of {@Link KrbTransport} combining TCP and UDP.
+ */
+public class KrbCombinedTransport
+        extends AbstractKrbTransport implements KrbTransport {
+    private KrbTransport tcpTransport;
+    private KrbTransport udpTransport;
+
+    private InetSocketAddress tcpAddress;
+    private InetSocketAddress udpAddress;
+
+    public KrbCombinedTransport(InetSocketAddress tcpAddress,
+                                InetSocketAddress udpAddress) throws IOException {
+        this.tcpAddress = tcpAddress;
+        this.udpAddress = udpAddress;
+
+        /**
+         * Try TCP first.
+         */
+        try {
+            this.tcpTransport = new KrbTcpTransport(tcpAddress);
+        } catch (IOException e) {
+            this.tcpTransport = null;
+            this.udpTransport = new KrbUdpTransport(udpAddress);
+        }
+    }
+
+    @Override
+    public void sendMessage(ByteBuffer message) throws IOException {
+        if (tcpTransport != null) {
+            tcpTransport.sendMessage(message);
+        } else if (udpTransport != null) {
+            udpTransport.sendMessage(message);
+        }
+    }
+
+    @Override
+    public ByteBuffer receiveMessage() throws IOException {
+        if (tcpTransport != null) {
+            return tcpTransport.receiveMessage();
+        } else if (udpTransport != null) {
+            return udpTransport.receiveMessage();
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbTcpTransport.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbTcpTransport.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbTcpTransport.java
new file mode 100644
index 0000000..4fb76ad
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbTcpTransport.java
@@ -0,0 +1,91 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.blocking;
+
+import org.apache.kerby.kerberos.kerb.transport.AbstractKrbTransport;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.SocketChannel;
+
+/**
+ * Default implementation of {@Link KrbTransport} using TCP in block mode.
+ */
+public class KrbTcpTransport
+        extends AbstractKrbTransport implements KrbTransport {
+    private SocketChannel socketChannel;
+    private ReadableByteChannel wrappedChannel; // for timeout stuff.
+    private InetSocketAddress remoteAddress;
+    private ByteBuffer headerBuffer; // for message length
+    private ByteBuffer messageBuffer; // for message body
+
+    public KrbTcpTransport(InetSocketAddress remoteAddress) throws IOException {
+        this.remoteAddress = remoteAddress;
+        this.headerBuffer = ByteBuffer.allocate(4);
+        this.messageBuffer = ByteBuffer.allocate(1024 * 1024); // TODO.
+        doConnect();
+    }
+
+    private void doConnect() throws IOException {
+        socketChannel = SocketChannel.open();
+        socketChannel.configureBlocking(true);
+        socketChannel.socket().setSoTimeout(100); // TODO.
+        socketChannel.connect(remoteAddress);
+
+        InputStream inStream = socketChannel.socket().getInputStream();
+        wrappedChannel = Channels.newChannel(inStream);
+    }
+
+    @Override
+    public void sendMessage(ByteBuffer message) throws IOException {
+        socketChannel.write(message);
+    }
+
+    @Override
+    public ByteBuffer receiveMessage() {
+        try {
+            headerBuffer.clear();
+            headerBuffer.position(0);
+            headerBuffer.limit(4);
+            wrappedChannel.read(headerBuffer);
+            headerBuffer.flip();
+
+            int msgLen = headerBuffer.getInt();
+            if (msgLen > 0) {
+                messageBuffer.clear();
+                messageBuffer.position(0);
+                messageBuffer.limit(msgLen);
+                wrappedChannel.read(messageBuffer);
+                messageBuffer.flip();
+
+                return messageBuffer;
+            }
+        } catch (IOException e) {
+            return null;
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbUdpTransport.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbUdpTransport.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbUdpTransport.java
new file mode 100644
index 0000000..8ef7a94
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/blocking/KrbUdpTransport.java
@@ -0,0 +1,57 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.blocking;
+
+import org.apache.kerby.kerberos.kerb.transport.AbstractKrbTransport;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.DatagramChannel;
+
+/**
+ * Default implementation of {@Link KrbTransport} using UDP.
+ */
+public class KrbUdpTransport
+        extends AbstractKrbTransport implements KrbTransport {
+    private DatagramChannel channel;
+    private InetSocketAddress remoteAddress;
+    private ByteBuffer recvBuffer;
+
+    public KrbUdpTransport(InetSocketAddress remoteAddress) throws IOException {
+        this.remoteAddress = remoteAddress;
+        this.channel = DatagramChannel.open();
+        this.recvBuffer = ByteBuffer.allocate(1024 * 1024); // TODO.
+        channel.connect(remoteAddress);
+    }
+
+    @Override
+    public void sendMessage(ByteBuffer message) throws IOException {
+        channel.send(message, remoteAddress);
+    }
+
+    @Override
+    public ByteBuffer receiveMessage() throws IOException {
+        recvBuffer.reset();
+        channel.receive(recvBuffer);
+        return recvBuffer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventBasedKrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventBasedKrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventBasedKrbClient.java
new file mode 100644
index 0000000..8c3cdbd
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventBasedKrbClient.java
@@ -0,0 +1,142 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.event;
+
+import org.apache.kerby.KOptions;
+import org.apache.kerby.event.Event;
+import org.apache.kerby.event.EventHub;
+import org.apache.kerby.event.EventWaiter;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.client.KrbConfig;
+import org.apache.kerby.kerberos.kerb.client.impl.AbstractInternalKrbClient;
+import org.apache.kerby.kerberos.kerb.client.request.AsRequest;
+import org.apache.kerby.kerberos.kerb.client.request.TgsRequest;
+import org.apache.kerby.kerberos.kerb.common.KrbStreamingDecoder;
+import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+import org.apache.kerby.transport.Network;
+import org.apache.kerby.transport.Transport;
+import org.apache.kerby.transport.event.TransportEvent;
+import org.apache.kerby.transport.event.TransportEventType;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * An event based krb client implementation.
+ */
+public class EventBasedKrbClient extends AbstractInternalKrbClient {
+
+    private EventKrbHandler krbHandler;
+    private EventHub eventHub;
+    private EventWaiter eventWaiter;
+    private Transport eventTransport;
+    private KrbTransport transport;
+
+    @Override
+    public void init(KOptions commonOptions) throws KrbException {
+        super.init(commonOptions);
+
+        this.krbHandler = new EventKrbHandler();
+        krbHandler.init(getContext());
+
+        this.eventHub = new EventHub();
+        eventHub.register(krbHandler);
+
+        Network network = new Network();
+        network.setStreamingDecoder(new KrbStreamingDecoder());
+        eventHub.register(network);
+
+        eventWaiter = eventHub.waitEvent(
+                TransportEventType.NEW_TRANSPORT,
+                KrbClientEventType.TGT_RESULT,
+                KrbClientEventType.TKT_RESULT
+        );
+
+        eventHub.start();
+
+        network.tcpConnect(getKdcHost(), getKdcTcpPort());
+        if (allowUdp()) {
+            network.udpConnect(getKdcHost(), getKdcUdpPort());
+        }
+        final Event event = eventWaiter.waitEvent(TransportEventType.NEW_TRANSPORT);
+        eventTransport = ((TransportEvent) event).getTransport();
+
+        transport = new KrbTransport() {
+            @Override
+            public void sendMessage(ByteBuffer message) throws IOException {
+                eventTransport.sendMessage(message);
+            }
+
+            @Override
+            public ByteBuffer receiveMessage() throws IOException {
+                return null; // NOOP, should not be here, since event based.
+            }
+
+            @Override
+            public void setAttachment(Object attachment) {
+                eventTransport.setAttachment(attachment);
+            }
+
+            @Override
+            public Object getAttachment() {
+                return eventTransport.getAttachment();
+            }
+        };
+    }
+
+    @Override
+    protected TgtTicket doRequestTgtTicket(AsRequest tgtTktReq) throws KrbException {
+        tgtTktReq.setTransport(transport);
+
+        eventHub.dispatch(KrbClientEvent.createTgtIntentEvent(tgtTktReq));
+        Event resultEvent;
+        try {
+            resultEvent = eventWaiter.waitEvent(KrbClientEventType.TGT_RESULT,
+                    getTimeout(), TimeUnit.SECONDS);
+        } catch (TimeoutException e) {
+            throw new KrbException("Network timeout", e);
+        }
+        AsRequest asResponse = (AsRequest) resultEvent.getEventData();
+
+        return asResponse.getTicket();
+    }
+
+    @Override
+    protected ServiceTicket doRequestServiceTicket(TgsRequest ticketReq) throws KrbException {
+        ticketReq.setTransport(transport);
+
+        eventHub.dispatch(KrbClientEvent.createTktIntentEvent(ticketReq));
+        Event resultEvent;
+        try {
+            resultEvent = eventWaiter.waitEvent(KrbClientEventType.TKT_RESULT,
+                    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-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventKrbHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventKrbHandler.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventKrbHandler.java
new file mode 100644
index 0000000..f7c7642
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/EventKrbHandler.java
@@ -0,0 +1,97 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.event;
+
+import org.apache.kerby.event.AbstractEventHandler;
+import org.apache.kerby.event.Event;
+import org.apache.kerby.event.EventType;
+import org.apache.kerby.kerberos.kerb.client.KrbContext;
+import org.apache.kerby.kerberos.kerb.client.preauth.PreauthHandler;
+import org.apache.kerby.kerberos.kerb.client.request.AsRequest;
+import org.apache.kerby.kerberos.kerb.client.request.KdcRequest;
+import org.apache.kerby.kerberos.kerb.client.request.TgsRequest;
+import org.apache.kerby.kerberos.kerb.common.KrbUtil;
+import org.apache.kerby.kerberos.kerb.spec.base.KrbMessage;
+import org.apache.kerby.kerberos.kerb.spec.base.KrbMessageType;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcRep;
+import org.apache.kerby.kerberos.kerb.spec.kdc.KdcReq;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+import org.apache.kerby.transport.event.MessageEvent;
+import org.apache.kerby.transport.event.TransportEventType;
+
+import java.nio.ByteBuffer;
+
+public class EventKrbHandler 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 Exception {
+        kdcRequest.process();
+        KdcReq kdcReq = kdcRequest.getKdcReq();
+        KrbTransport transport = kdcRequest.getTransport();
+        transport.setAttachment(kdcRequest);
+        KrbUtil.sendMessage(kdcReq, transport);
+    }
+
+    protected void handleMessage(MessageEvent event) throws Exception {
+        ByteBuffer message = event.getMessage();
+        KrbMessage kdcRep = KrbUtil.decodeMessageOld(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-kerby/blob/ff0200f8/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEvent.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEvent.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEvent.java
new file mode 100644
index 0000000..574e2d0
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/event/KrbClientEvent.java
@@ -0,0 +1,43 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.client.impl.event;
+
+import org.apache.kerby.event.Event;
+import org.apache.kerby.kerberos.kerb.client.request.AsRequest;
+import org.apache.kerby.kerberos.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);
+    }
+}