directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dran...@apache.org
Subject [03/42] directory-kerberos git commit: Initially import Haox codebase (https://github.com/drankye/haox)
Date Sat, 10 Jan 2015 13:30:47 GMT
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/java/org/apache/kerberos/kerb/server/TestKdcServer.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/java/org/apache/kerberos/kerb/server/TestKdcServer.java b/haox-kerb/kerb-kdc-test/src/main/java/org/apache/kerberos/kerb/server/TestKdcServer.java
new file mode 100644
index 0000000..fd1435f
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/java/org/apache/kerberos/kerb/server/TestKdcServer.java
@@ -0,0 +1,103 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerberos.kerb.identity.KrbIdentity;
+import org.apache.kerberos.kerb.keytab.Keytab;
+import org.apache.kerberos.kerb.keytab.KeytabEntry;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.EncryptionType;
+import org.apache.kerberos.kerb.spec.common.PrincipalName;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+
+public class TestKdcServer extends SimpleKdcServer {
+
+    public static final String ORG_DOMAIN = KdcConfigKey.KDC_DOMAIN.getPropertyKey();
+    public static final String KDC_REALM = KdcConfigKey.KDC_REALM.getPropertyKey();
+    public static final String KDC_HOST = KdcConfigKey.KDC_HOST.getPropertyKey();
+    public static final String KDC_PORT = KdcConfigKey.KDC_PORT.getPropertyKey();
+    public static final String WORK_DIR = KdcConfigKey.WORK_DIR.getPropertyKey();
+
+    private static final Properties DEFAULT_CONFIG = new Properties();
+    static {
+        DEFAULT_CONFIG.setProperty(KDC_HOST, "localhost");
+        DEFAULT_CONFIG.setProperty(KDC_PORT, "8018");
+        DEFAULT_CONFIG.setProperty(ORG_DOMAIN, "test.com");
+        DEFAULT_CONFIG.setProperty(KDC_REALM, "TEST.COM");
+    }
+
+    public static Properties createConf() {
+        return (Properties) DEFAULT_CONFIG.clone();
+    }
+
+    public TestKdcServer() {
+        this(createConf());
+    }
+
+    public TestKdcServer(Properties conf) {
+        super();
+        getConfig().getConf().addPropertiesConfig(conf);
+    }
+
+    @Override
+    public void init() {
+        super.init();
+
+        createPrincipals("krbtgt");
+    }
+
+    public String getKdcRealm() {
+        return getConfig().getKdcRealm();
+    }
+
+    public synchronized void createPrincipal(String principal, String password) {
+        KrbIdentity identity = new KrbIdentity(principal);
+        List<EncryptionType> encTypes = getConfig().getEncryptionTypes();
+        List<EncryptionKey> encKeys = null;
+        try {
+            encKeys = EncryptionUtil.generateKeys(fixPrincipal(principal), password, encTypes);
+        } catch (KrbException e) {
+            throw new RuntimeException("Failed to generate encryption keys", e);
+        }
+        identity.addKeys(encKeys);
+        getIdentityService().addIdentity(identity);
+    }
+
+    public void createPrincipals(String ... principals) {
+        String passwd;
+        for (String principal : principals) {
+            passwd = UUID.randomUUID().toString();
+            createPrincipal(fixPrincipal(principal), passwd);
+        }
+    }
+
+    private String fixPrincipal(String principal) {
+        if (! principal.contains("@")) {
+            principal += "@" + getKdcRealm();
+        }
+        return principal;
+    }
+
+    public void exportPrincipals(File keytabFile) throws IOException {
+        Keytab keytab = new Keytab();
+
+        List<KrbIdentity> identities = getIdentityService().getIdentities();
+        for (KrbIdentity identity : identities) {
+            PrincipalName principal = identity.getPrincipal();
+            KerberosTime timestamp = new KerberosTime();
+            for (EncryptionType encType : identity.getKeys().keySet()) {
+                EncryptionKey ekey = identity.getKeys().get(encType);
+                int keyVersion = ekey.getKvno();
+                keytab.addEntry(new KeytabEntry(principal, timestamp, keyVersion, ekey));
+            }
+        }
+
+        keytab.store(keytabFile);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/cacert.pem
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/cacert.pem b/haox-kerb/kerb-kdc-test/src/main/resources/cacert.pem
new file mode 100644
index 0000000..6b91561
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/cacert.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID6zCCAtOgAwIBAgIJAMrZoeDxTzwWMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
+VQQGEwJjaDERMA8GA1UECAwIc2hhbmdoYWkxETAPBgNVBAcMCHNoYW5naGFpMQ4w
+DAYDVQQKDAVpbnRlbDEQMA4GA1UECwwHYmlnZGF0YTEQMA4GA1UEAwwHYmlnZGF0
+YTEiMCAGCSqGSIb3DQEJARYTa2FpLnpoZW5nQGludGVsLmNvbTAeFw0xNDA1MTMx
+MzEzMjdaFw0yNDA1MTAxMzEzMjdaMIGLMQswCQYDVQQGEwJjaDERMA8GA1UECAwI
+c2hhbmdoYWkxETAPBgNVBAcMCHNoYW5naGFpMQ4wDAYDVQQKDAVpbnRlbDEQMA4G
+A1UECwwHYmlnZGF0YTEQMA4GA1UEAwwHYmlnZGF0YTEiMCAGCSqGSIb3DQEJARYT
+a2FpLnpoZW5nQGludGVsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAMCznJJ02ZUjCPvAwnBmfPs0akb5QRc/NKu8kCtAPWzgHS2JPTQfJhkDbTAD
+eIlg8IeJpOdrYnzdaBCzgxqjSkls+vxjYotOU0Zbrpy2bj0lRDqdYbNsiuConKgT
+MeuDEd/4ZI0X9NWLAi06Iv1F4mHXf36c6uqiUWTtXiofogrFUoTRwACKR2qeC95X
+Py+FDmpS9lz0mo0vDWjetLQC2IBngjjPFdR16n87QDIWfRBkk66rn7rEA6Li66b/
+cToajMSA/n+2Ud1mntSY4RdDdd0TBtAq9RrXtUOfzGaE7S6t+FtYyEprvT4FdOTU
+uyYgSNaI9ANVP1zhQ9LACKuudOECAwEAAaNQME4wHQYDVR0OBBYEFD91SVOejfwx
+u33+5N0TdYbHJbgAMB8GA1UdIwQYMBaAFD91SVOejfwxu33+5N0TdYbHJbgAMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADsONtUqGNBPBXnRowcJwv+Y
+F1Vea+4dkBwYbhkiO6H5XMKr+waOnOD2eAvgP4aeYg/a0xOzzETRD9wi1Z1P1ZMy
+d/NzHQjj4egPENwDv1PH2voZgsXXzXIqUMOtz9t12TuJUrSA2SBW1tz/evckHhNY
+fHg4ThvTIgwEdV/yvrOEBLV9dXG5IhhF+NW1MegTGkt4SpOoH1pi3o9VekVRnix9
+xrIdaC4Ee6vQaR603HwDS9Y+a1c2KU7QoLX8Vaa904cQ+rxhGsTAkocnZXeo6Hl5
+V8BlDYXxeP86fzcWi04ll2BmEEw/RimHEOLpGqxTVHJ5p5BVSCHP8aCD0VJheaU=
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/cakey.pem
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/cakey.pem b/haox-kerb/kerb-kdc-test/src/main/resources/cakey.pem
new file mode 100644
index 0000000..66dc806
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/cakey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAwLOcknTZlSMI+8DCcGZ8+zRqRvlBFz80q7yQK0A9bOAdLYk9
+NB8mGQNtMAN4iWDwh4mk52tifN1oELODGqNKSWz6/GNii05TRluunLZuPSVEOp1h
+s2yK4KicqBMx64MR3/hkjRf01YsCLToi/UXiYdd/fpzq6qJRZO1eKh+iCsVShNHA
+AIpHap4L3lc/L4UOalL2XPSajS8NaN60tALYgGeCOM8V1HXqfztAMhZ9EGSTrquf
+usQDouLrpv9xOhqMxID+f7ZR3Wae1JjhF0N13RMG0Cr1Gte1Q5/MZoTtLq34W1jI
+Smu9PgV05NS7JiBI1oj0A1U/XOFD0sAIq6504QIDAQABAoIBAHqFeMax3unxBbQ0
+Aiy/LTX3RJ9tuZITUOTklnG5fZStBkA+oxhxuaJryE+f1VLbvPMgdCXj5BHqIFGG
+IZSdQA1hak9wzWYvXck9X88qOvtLp47xI/6Vw9NFwZ0n3zST+JiD8UK4eaYQpUim
+Tzrj5SU6hEi3crHOlJvsRFPaGwhnA9wycoOo4o22XBj3C8Hwzi4vWcKXH/RCSwZQ
+zFuYbe77Pn9Sv5q5zdglkmm7wngoVt/aKQke/Vk+Eincx1V12b05DNLjugo6FWQh
+0f2MmHpvqNSHs9USC5+y2lKQ1JNHh7mnpPCXkZEH4V7q+3mKVzl9tXzj9Gul20pw
+tneD6WUCgYEA9QUrQoWHKeVMjeukHjDJa2KjRLMmg9YRQyVABH9+nQTp1jYUjMRA
+GUoUx91gG6gjjJD/xvor/U0Fh3vKtZE93c+avrcaYDwf3q/L4gh+3b87lVDfzjrp
+L+MPTpEzWiyyLfr/kLA0TgUjnrj9bav5uDps8mJpNf8s9ZP1/QDhF5sCgYEAyVZA
+pHSIyBI2GT0+92JXvYDK/ZfV5m4RGHaG/PMDoU4IbGbjHVyzzsyzDUgvOASXwfF8
+YzwX7Tf95RZw12P/Jepxt0vqBJPKUCsMLUrmANQvN1Pz8+Vk6UADLM7kNc06MqB9
+/U3GKCFZZuedEhbgXnEV9gzelhILImJGZMxG0zMCgYApymnofLHjGXMHOcvSQmv4
+XuiODShikB59n1rd6YkE6xOfL7YtlEOCjLoipMWBshnuHcUigQUDvSFWTGz0rwMo
+VAKGyOA8zcR5zO4vbVeGJtnYy+SAXlfrjQTNV8K0fK8fXJI+cW9aZ1H9/ntrO0vq
+ejye0t4zEYTvlf782iuKRQKBgQCnTQ7mGRfX+JoPmv8JniR+idkjpNnPYsK96y/8
+XQs1LJx/R3eN3IxlWV+nt8XU7KwWMs5Dv5m6Ov61MFKQCL3qCch4oZJSP2Sr/Tlf
+IY/CPI8HkLF0h7e0wsZgo4Kq2mBz1T0cEVaJ3jxl8Cxq7at/jsTK8qK7XT73UWZh
+OAXaVQKBgDmg2QTX7c0/dbDMOuw18g3xfE/oqU+VWT784wtvpcdjHR+KAVLWHG8l
+oc/bm8Bs0o0f5dfH7uUvWdP6JMvbgYZBgIMqw+iH8P2lFCLzIRf0me/l+r0Oi64U
+5jp9K+7Ggc7S0SSnCLmBLMN5lXQZbhzks1La7DZmFeAz8rOEnlUB
+-----END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/extensions.kdc
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/extensions.kdc b/haox-kerb/kerb-kdc-test/src/main/resources/extensions.kdc
new file mode 100644
index 0000000..e0d1578
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/extensions.kdc
@@ -0,0 +1,20 @@
+[kdc_cert]
+basicConstraints=CA:FALSE
+keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
+extendedKeyUsage=1.3.6.1.5.2.3.5
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+issuerAltName=issuer:copy
+subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name
+
+[kdc_princ_name]
+realm=EXP:0,GeneralString:${ENV::REALM}
+principal_name=EXP:1,SEQUENCE:kdc_principal_seq
+
+[kdc_principal_seq]
+name_type=EXP:0,INTEGER:1
+name_string=EXP:1,SEQUENCE:kdc_principals
+
+[kdc_principals]
+princ1=GeneralString:krbtgt
+princ2=GeneralString:${ENV::REALM}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/kdc-krb5.conf
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/kdc-krb5.conf b/haox-kerb/kerb-kdc-test/src/main/resources/kdc-krb5.conf
new file mode 100644
index 0000000..d118dd1
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/kdc-krb5.conf
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+[libdefaults]
+    default_realm = {0}
+    udp_preference_limit = 1
+
+[realms]
+    {0} = '{'
+        kdc = {1}:{2}
+    '}'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/kdc.ldiff
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/kdc.ldiff b/haox-kerb/kerb-kdc-test/src/main/resources/kdc.ldiff
new file mode 100644
index 0000000..e344131
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/kdc.ldiff
@@ -0,0 +1,30 @@
+dn: ou=users,dc=${0},dc=${1}
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: uid=krbtgt,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3}
+krb5KeyVersionNumber: 0
+
+dn: uid=ldap,ou=users,dc=${0},dc=${1}
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: LDAP
+sn: Service
+uid: ldap
+userPassword: secret
+krb5PrincipalName: ldap/${4}@${2}.${3}
+krb5KeyVersionNumber: 0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/kdccert.pem
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/kdccert.pem b/haox-kerb/kerb-kdc-test/src/main/resources/kdccert.pem
new file mode 100644
index 0000000..67e538c
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/kdccert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEYjCCA0qgAwIBAgIJAL2ZFUkXCgK2MA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
+VQQGEwJjaDERMA8GA1UECAwIc2hhbmdoYWkxETAPBgNVBAcMCHNoYW5naGFpMQ4w
+DAYDVQQKDAVpbnRlbDEQMA4GA1UECwwHYmlnZGF0YTEQMA4GA1UEAwwHYmlnZGF0
+YTEiMCAGCSqGSIb3DQEJARYTa2FpLnpoZW5nQGludGVsLmNvbTAeFw0xNDA1MTMx
+MzI3MjFaFw0xNTA1MTMxMzI3MjFaMIGLMQswCQYDVQQGEwJjaDERMA8GA1UECAwI
+c2hhbmdoYWkxETAPBgNVBAcMCHNoYW5naGFpMQ4wDAYDVQQKDAVpbnRlbDEQMA4G
+A1UECwwHYmlnZGF0YTEQMA4GA1UEAwwHYmlnZGF0YTEiMCAGCSqGSIb3DQEJARYT
+a2FpLnpoZW5nQGludGVsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAMs0jF1fi5AVMunQ/jpxgSjRlpmVQyT//LrwBmyI77C+hCD4z/InoG4q2tl5
+fAH+2n7HHgon4E0QXyRxAz0+Ugun7qHW9oT2pnxoc1l8seyGNMK9adsxLpCv7RXK
+quqLcj34UQCzRDKxgkH5UBwxGY0kId0W1MqPh1LZRZIk1hakREC4DBj+slnDkN0s
+nh8pC/8q/hTPJ9QrqWT6oc1FjMVKz3FxFbxXELYxg4M6SXnzGzdWa3xSe4Ou0QO2
+EwncQUoo8N6plOKX5lncDhC2usT//AZHvKdcVmOwX0ByxZqGQIXk7g1kbsbG5m45
+JMjt/HnOQcfg88iSLKJZu+ODw00CAwEAAaOBxjCBwzAJBgNVHRMEAjAAMAsGA1Ud
+DwQEAwID6DASBgNVHSUECzAJBgcrBgEFAgMFMB0GA1UdDgQWBBS8Bmb9kTUkw61e
+Is+9KDV5U6JjyjAfBgNVHSMEGDAWgBQ/dUlTno38Mbt9/uTdE3WGxyW4ADAJBgNV
+HRIEAjAAMEoGA1UdEQRDMEGgPwYGKwYBBQICoDUwM6AOGwxTSC5JTlRFTC5DT02h
+ITAfoAMCAQGhGDAWGwZrcmJ0Z3QbDFNILklOVEVMLkNPTTANBgkqhkiG9w0BAQUF
+AAOCAQEAS/I0zH9ByFcXTF56I5aPmPdzYKpIpFF6Kkwyw0M2EuIcTcpDl74/xmq9
+YPHS6TSDAt3wHzs9JQlSWah04L0R+IgHVacLRgdXfTWqglFFH/pve3p49WCrYmWz
+txQeRV5dxzaE3oTdDq15DRkUJmt0GIk1x6ehrGZOpIL8oTFmVmnR7EgrKWlIMYCs
+R/GkEuCH15wadom/Hw5Db1KLPEjxCdwy947guOh4SO0fcW3h55V3troS/46TbVFF
+FvNSqGD+19/QM/MhLIy5OnTxOio8M9zp+yfDlzLnpbMi0ZO6tLvB4XhjvP0as34c
+5vCA/8HPfaearSyAYi2Ir9vT3O9J/w==
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/kdckey.pem
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/kdckey.pem b/haox-kerb/kerb-kdc-test/src/main/resources/kdckey.pem
new file mode 100644
index 0000000..c9e75e2
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/kdckey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyzSMXV+LkBUy6dD+OnGBKNGWmZVDJP/8uvAGbIjvsL6EIPjP
+8iegbira2Xl8Af7afsceCifgTRBfJHEDPT5SC6fuodb2hPamfGhzWXyx7IY0wr1p
+2zEukK/tFcqq6otyPfhRALNEMrGCQflQHDEZjSQh3RbUyo+HUtlFkiTWFqREQLgM
+GP6yWcOQ3SyeHykL/yr+FM8n1CupZPqhzUWMxUrPcXEVvFcQtjGDgzpJefMbN1Zr
+fFJ7g67RA7YTCdxBSijw3qmU4pfmWdwOELa6xP/8Bke8p1xWY7BfQHLFmoZAheTu
+DWRuxsbmbjkkyO38ec5Bx+DzyJIsolm744PDTQIDAQABAoIBAQC4Byb3iQgDvK8X
+QcZ7dz/Zj7Yr8RmV8J8ZTTcEJB+umVtf4PWyAGEyZG0+dt7vj7ahCgMSf3qLUEBZ
+6F9en4n+NF/RAbTQRfAQyydr65nW8tPlaVTsxWW+cxTrn1eagh88MB5r2+3vWwL0
+bK04Wt8hC4//giXELKgJR+vRprqcVRgy11nYaTP59IDdg4YscbHfc/LYa7ABQ1G5
+5NKtjMy13UvtD/4C3TS1NpL2xtzAgQRe3XFDIyOmv476Ts1boqSHBFX+MXmLBAfi
+8Qhaj1DO8A0HS/c4egcL6esCe4kcgtCuq66n8JzOlVbCDGOYIUkUyQ9Nfo31M5i5
+XhqF9CsBAoGBAP7PqkncLAvyjHQKPpDyWCBtkV7z+DWRZRPz4w8tit+TiAv6hRF7
+kK+NUhP1mBuS4duyEV58B8LWOR0ir7ftbL0/unxR1XWMOvTEHr/9lG1sKZoI0dJS
+Ee+VvuVFwdm/ABxfnveGCRrSHY7GAvFln3gC1Cst3NPPKbpznb3FiH/JAoGBAMwn
+P1Labt/OuzB70Vxve3TCeFA6jYzcYdA3riv1V0FIWoNgcQ742b0+6HDpEQgn4Rdb
+KiKz8hSplM1nx8NyWwS9r7gRQ9HIc0qC5S4A0A9QEbdKrkUiQDlwHgdDKPPCWih9
+qH05etiQ044BtOq7uXsWYqiIomOW/XyDUEhbRRFlAoGALmVnj01Mo9xFILfgzomh
+7D2nE4/+qNpRekGVHWVgfPci9XNnGVjTbnOf90xnptWm1Fbm/Lo+u4ZAHgL71dSg
+UREyhoJsCJxA++Jd6v1kMkxYgtiKQ+53n5U3jg2Wj2xMu93ZVx6Lt9t8UEvTq1qi
+n7p8IWSXaeW1pmJ43V4DTakCgYAFcSpj+ASqnKUqxrIvB52/4As7AESTs7A7z7Ap
+5dFcoSQgimqZHpMXU1z43Y2hrQZ4C+sUn71dRaP80b5mfF7mwnOzsWogZnqESvb3
+AfiJ3/WI8Emy+BXEMjPqt6SY0t56Y9cg925J5ZpuF6eN9lEccd1RZssFYpoBPrLe
+KuitbQKBgQC3DNejUqol2max6rf4h/GnwLE2BOTmFLnswexlw76p/63Jo1SaVpk7
+9nAltsqNCl4L/eAJ8hJdeTE5YVjYsgAVJrXZbiRfxHBMeHj9g0d1VafGqdomKf0R
+7Qytlcvsw8jn96ckEMPPLJF0bX5cu9S6lMyEbb6Ih41P13uvgP6ufg==
+-----END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/usercert.pem
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/usercert.pem b/haox-kerb/kerb-kdc-test/src/main/resources/usercert.pem
new file mode 100644
index 0000000..67e538c
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/usercert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEYjCCA0qgAwIBAgIJAL2ZFUkXCgK2MA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
+VQQGEwJjaDERMA8GA1UECAwIc2hhbmdoYWkxETAPBgNVBAcMCHNoYW5naGFpMQ4w
+DAYDVQQKDAVpbnRlbDEQMA4GA1UECwwHYmlnZGF0YTEQMA4GA1UEAwwHYmlnZGF0
+YTEiMCAGCSqGSIb3DQEJARYTa2FpLnpoZW5nQGludGVsLmNvbTAeFw0xNDA1MTMx
+MzI3MjFaFw0xNTA1MTMxMzI3MjFaMIGLMQswCQYDVQQGEwJjaDERMA8GA1UECAwI
+c2hhbmdoYWkxETAPBgNVBAcMCHNoYW5naGFpMQ4wDAYDVQQKDAVpbnRlbDEQMA4G
+A1UECwwHYmlnZGF0YTEQMA4GA1UEAwwHYmlnZGF0YTEiMCAGCSqGSIb3DQEJARYT
+a2FpLnpoZW5nQGludGVsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAMs0jF1fi5AVMunQ/jpxgSjRlpmVQyT//LrwBmyI77C+hCD4z/InoG4q2tl5
+fAH+2n7HHgon4E0QXyRxAz0+Ugun7qHW9oT2pnxoc1l8seyGNMK9adsxLpCv7RXK
+quqLcj34UQCzRDKxgkH5UBwxGY0kId0W1MqPh1LZRZIk1hakREC4DBj+slnDkN0s
+nh8pC/8q/hTPJ9QrqWT6oc1FjMVKz3FxFbxXELYxg4M6SXnzGzdWa3xSe4Ou0QO2
+EwncQUoo8N6plOKX5lncDhC2usT//AZHvKdcVmOwX0ByxZqGQIXk7g1kbsbG5m45
+JMjt/HnOQcfg88iSLKJZu+ODw00CAwEAAaOBxjCBwzAJBgNVHRMEAjAAMAsGA1Ud
+DwQEAwID6DASBgNVHSUECzAJBgcrBgEFAgMFMB0GA1UdDgQWBBS8Bmb9kTUkw61e
+Is+9KDV5U6JjyjAfBgNVHSMEGDAWgBQ/dUlTno38Mbt9/uTdE3WGxyW4ADAJBgNV
+HRIEAjAAMEoGA1UdEQRDMEGgPwYGKwYBBQICoDUwM6AOGwxTSC5JTlRFTC5DT02h
+ITAfoAMCAQGhGDAWGwZrcmJ0Z3QbDFNILklOVEVMLkNPTTANBgkqhkiG9w0BAQUF
+AAOCAQEAS/I0zH9ByFcXTF56I5aPmPdzYKpIpFF6Kkwyw0M2EuIcTcpDl74/xmq9
+YPHS6TSDAt3wHzs9JQlSWah04L0R+IgHVacLRgdXfTWqglFFH/pve3p49WCrYmWz
+txQeRV5dxzaE3oTdDq15DRkUJmt0GIk1x6ehrGZOpIL8oTFmVmnR7EgrKWlIMYCs
+R/GkEuCH15wadom/Hw5Db1KLPEjxCdwy947guOh4SO0fcW3h55V3troS/46TbVFF
+FvNSqGD+19/QM/MhLIy5OnTxOio8M9zp+yfDlzLnpbMi0ZO6tLvB4XhjvP0as34c
+5vCA/8HPfaearSyAYi2Ir9vT3O9J/w==
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/main/resources/userkey.pem
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/main/resources/userkey.pem b/haox-kerb/kerb-kdc-test/src/main/resources/userkey.pem
new file mode 100644
index 0000000..c9e75e2
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/main/resources/userkey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyzSMXV+LkBUy6dD+OnGBKNGWmZVDJP/8uvAGbIjvsL6EIPjP
+8iegbira2Xl8Af7afsceCifgTRBfJHEDPT5SC6fuodb2hPamfGhzWXyx7IY0wr1p
+2zEukK/tFcqq6otyPfhRALNEMrGCQflQHDEZjSQh3RbUyo+HUtlFkiTWFqREQLgM
+GP6yWcOQ3SyeHykL/yr+FM8n1CupZPqhzUWMxUrPcXEVvFcQtjGDgzpJefMbN1Zr
+fFJ7g67RA7YTCdxBSijw3qmU4pfmWdwOELa6xP/8Bke8p1xWY7BfQHLFmoZAheTu
+DWRuxsbmbjkkyO38ec5Bx+DzyJIsolm744PDTQIDAQABAoIBAQC4Byb3iQgDvK8X
+QcZ7dz/Zj7Yr8RmV8J8ZTTcEJB+umVtf4PWyAGEyZG0+dt7vj7ahCgMSf3qLUEBZ
+6F9en4n+NF/RAbTQRfAQyydr65nW8tPlaVTsxWW+cxTrn1eagh88MB5r2+3vWwL0
+bK04Wt8hC4//giXELKgJR+vRprqcVRgy11nYaTP59IDdg4YscbHfc/LYa7ABQ1G5
+5NKtjMy13UvtD/4C3TS1NpL2xtzAgQRe3XFDIyOmv476Ts1boqSHBFX+MXmLBAfi
+8Qhaj1DO8A0HS/c4egcL6esCe4kcgtCuq66n8JzOlVbCDGOYIUkUyQ9Nfo31M5i5
+XhqF9CsBAoGBAP7PqkncLAvyjHQKPpDyWCBtkV7z+DWRZRPz4w8tit+TiAv6hRF7
+kK+NUhP1mBuS4duyEV58B8LWOR0ir7ftbL0/unxR1XWMOvTEHr/9lG1sKZoI0dJS
+Ee+VvuVFwdm/ABxfnveGCRrSHY7GAvFln3gC1Cst3NPPKbpznb3FiH/JAoGBAMwn
+P1Labt/OuzB70Vxve3TCeFA6jYzcYdA3riv1V0FIWoNgcQ742b0+6HDpEQgn4Rdb
+KiKz8hSplM1nx8NyWwS9r7gRQ9HIc0qC5S4A0A9QEbdKrkUiQDlwHgdDKPPCWih9
+qH05etiQ044BtOq7uXsWYqiIomOW/XyDUEhbRRFlAoGALmVnj01Mo9xFILfgzomh
+7D2nE4/+qNpRekGVHWVgfPci9XNnGVjTbnOf90xnptWm1Fbm/Lo+u4ZAHgL71dSg
+UREyhoJsCJxA++Jd6v1kMkxYgtiKQ+53n5U3jg2Wj2xMu93ZVx6Lt9t8UEvTq1qi
+n7p8IWSXaeW1pmJ43V4DTakCgYAFcSpj+ASqnKUqxrIvB52/4As7AESTs7A7z7Ap
+5dFcoSQgimqZHpMXU1z43Y2hrQZ4C+sUn71dRaP80b5mfF7mwnOzsWogZnqESvb3
+AfiJ3/WI8Emy+BXEMjPqt6SY0t56Y9cg925J5ZpuF6eN9lEccd1RZssFYpoBPrLe
+KuitbQKBgQC3DNejUqol2max6rf4h/GnwLE2BOTmFLnswexlw76p/63Jo1SaVpk7
+9nAltsqNCl4L/eAJ8hJdeTE5YVjYsgAVJrXZbiRfxHBMeHj9g0d1VafGqdomKf0R
+7Qytlcvsw8jn96ckEMPPLJF0bX5cu9S6lMyEbb6Ih41P13uvgP6ufg==
+-----END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTest.java b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTest.java
new file mode 100644
index 0000000..c199c44
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTest.java
@@ -0,0 +1,30 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerberos.kerb.spec.ticket.TgtTicket;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class KdcTest extends KdcTestBase {
+
+    private String password = "123456";
+
+    @Override
+    protected void setUpKdcServer() throws Exception {
+        super.setUpKdcServer();
+        kdcServer.createPrincipal(clientPrincipal, password);
+    }
+
+    @Test
+    public void testKdc() throws Exception {
+        kdcServer.start();
+        Assert.assertTrue(kdcServer.isStarted());
+
+        krbClnt.init();
+        TgtTicket tgt = krbClnt.requestTgtTicket(clientPrincipal, password, null);
+        Assert.assertNotNull(tgt);
+
+        ServiceTicket tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+        Assert.assertNotNull(tkt);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTestBase.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTestBase.java b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTestBase.java
new file mode 100644
index 0000000..56f7741
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/KdcTestBase.java
@@ -0,0 +1,49 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.client.KrbClient;
+import org.apache.kerberos.kerb.server.TestKdcServer;
+import org.junit.After;
+import org.junit.Before;
+
+public abstract class KdcTestBase {
+
+    protected String kdcRealm;
+    protected String clientPrincipal;
+    protected String serverPrincipal;
+
+    protected String hostname = "localhost";
+    protected short port = 8088;
+
+    protected TestKdcServer kdcServer;
+    protected KrbClient krbClnt;
+
+    @Before
+    public void setUp() throws Exception {
+        setUpKdcServer();
+        setUpClient();
+    }
+
+    protected void setUpKdcServer() throws Exception {
+        kdcServer = new TestKdcServer();
+        kdcServer.setKdcHost(hostname);
+        kdcServer.setKdcPort(port);
+        kdcServer.init();
+
+        kdcRealm = kdcServer.getKdcRealm();
+        clientPrincipal = "drankye@" + kdcRealm;
+
+        serverPrincipal = "test-service/localhost@" + kdcRealm;
+        kdcServer.createPrincipals(serverPrincipal);
+    }
+
+    protected void setUpClient() throws Exception {
+        krbClnt = new KrbClient(hostname, port);
+        krbClnt.setTimeout(5);
+        krbClnt.setKdcRealm(kdcServer.getKdcRealm());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        kdcServer.stop();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithCertKdcTest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithCertKdcTest.java b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithCertKdcTest.java
new file mode 100644
index 0000000..b72237d
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithCertKdcTest.java
@@ -0,0 +1,71 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerberos.kerb.spec.ticket.TgtTicket;
+import org.haox.pki.Pkix;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+
+/**
+ openssl genrsa -out cakey.pem 2048
+ openssl req -key cakey.pem -new -x509 -out cacert.pem -days 3650
+ vi extensions.kdc
+ openssl genrsa -out kdckey.pem 2048
+ openssl req -new -out kdc.req -key kdckey.pem
+ env REALM=SH.INTEL.COM openssl x509 -req -in kdc.req -CAkey cakey.pem \
+ -CA cacert.pem -out kdc.pem -days 365 -extfile extensions.kdc -extensions kdc_cert -CAcreateserial
+ */
+public class WithCertKdcTest extends KdcTestBase {
+
+    private Certificate userCert;
+    private PrivateKey userKey;
+
+    @Override
+    protected void setUpClient() throws Exception {
+        super.setUpClient();
+
+        loadCredentials();
+    }
+
+    @Override
+    protected void setUpKdcServer() throws Exception {
+        super.setUpKdcServer();
+        kdcServer.createPrincipals(clientPrincipal);
+    }
+
+    //@Test
+    public void testKdc() throws Exception {
+        Assert.assertNotNull(userCert);
+
+        kdcServer.start();
+        Assert.assertTrue(kdcServer.isStarted());
+        krbClnt.init();
+
+        TgtTicket tgt = null;
+        try {
+            tgt = krbClnt.requestTgtTicket(clientPrincipal, userCert, userKey, null);
+        } catch (KrbException te) {
+            Assert.assertTrue(te.getMessage().contains("timeout"));
+            return;
+        }
+        Assert.assertNull(tgt);
+
+        ServiceTicket tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+        Assert.assertNull(tkt);
+    }
+
+    private void loadCredentials() throws IOException, GeneralSecurityException {
+        InputStream res = getClass().getResourceAsStream("/usercert.pem");
+        userCert = Pkix.getCerts(res).iterator().next();
+
+        res = getClass().getResourceAsStream("/userkey.pem");
+        userKey = Pkix.getPrivateKey(res, null);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithTokenKdcTest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithTokenKdcTest.java b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithTokenKdcTest.java
new file mode 100644
index 0000000..efbdf16
--- /dev/null
+++ b/haox-kerb/kerb-kdc-test/src/test/java/org/apache/kerberos/kerb/server/WithTokenKdcTest.java
@@ -0,0 +1,38 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.ticket.ServiceTicket;
+import org.apache.kerberos.kerb.spec.ticket.TgtTicket;
+import org.haox.token.KerbToken;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class WithTokenKdcTest extends KdcTestBase {
+
+    private KerbToken token;
+
+    @Override
+    protected void setUpKdcServer() throws Exception {
+        super.setUpKdcServer();
+        kdcServer.createPrincipals(clientPrincipal);
+    }
+
+    //@Test
+    public void testKdc() throws Exception {
+        kdcServer.start();
+        Assert.assertTrue(kdcServer.isStarted());
+        krbClnt.init();
+
+        TgtTicket tgt = null;
+        try {
+            tgt = krbClnt.requestTgtTicket(clientPrincipal, token, null);
+        } catch (KrbException te) {
+            Assert.assertTrue(te.getMessage().contains("timeout"));
+            return;
+        }
+        Assert.assertNull(tgt);
+
+        ServiceTicket tkt = krbClnt.requestServiceTicket(tgt, serverPrincipal, null);
+        Assert.assertNull(tkt);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/pom.xml
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/pom.xml b/haox-kerb/kerb-server/pom.xml
new file mode 100644
index 0000000..dfc8738
--- /dev/null
+++ b/haox-kerb/kerb-server/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.haox</groupId>
+        <artifactId>haox-kerb</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>kerb-server</artifactId>
+
+    <name>Haox-kerb Server</name>
+    <description>Haox-kerb Server</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>haox-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>kerb-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>kerb-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>kerb-identity</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>haox-event</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.haox</groupId>
+            <artifactId>haox-pkix</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

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

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

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcContext.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcContext.java
new file mode 100644
index 0000000..3b090f7
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcContext.java
@@ -0,0 +1,72 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.identity.IdentityService;
+import org.apache.kerberos.kerb.server.preauth.PreauthHandler;
+import org.apache.kerberos.kerb.server.replay.ReplayCheckService;
+
+import java.util.List;
+
+public class KdcContext {
+    private KdcConfig config;
+    private List<String> supportedKdcRealms;
+    private String kdcRealm;
+    private IdentityService identityService;
+    private ReplayCheckService replayCache;
+    private PreauthHandler preauthHandler;
+
+    public void init(KdcConfig config) {
+        this.config = config;
+    }
+
+    public KdcConfig getConfig() {
+        return config;
+    }
+
+    public void setPreauthHandler(PreauthHandler preauthHandler) {
+        this.preauthHandler = preauthHandler;
+    }
+
+    public PreauthHandler getPreauthHandler() {
+        return this.preauthHandler;
+    }
+
+    public List<String> getSupportedKdcRealms() {
+        return supportedKdcRealms;
+    }
+
+    public void setSupportedKdcRealms(List<String> supportedKdcRealms) {
+        this.supportedKdcRealms = supportedKdcRealms;
+    }
+
+    public void setKdcRealm(String realm) {
+        this.kdcRealm = realm;
+    }
+
+    public String getServerRealm() {
+        return config.getKdcRealm();
+    }
+
+    public String getKdcRealm() {
+        if (kdcRealm != null) {
+            return kdcRealm;
+        }
+        return config.getKdcRealm();
+    }
+
+    public void setReplayCache(ReplayCheckService replayCache) {
+        this.replayCache = replayCache;
+    }
+
+    public ReplayCheckService getReplayCache() {
+        return replayCache;
+    }
+
+    public void setIdentityService(IdentityService identityService) {
+        this.identityService = identityService;
+    }
+
+
+    public IdentityService getIdentityService() {
+        return identityService;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcHandler.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcHandler.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcHandler.java
new file mode 100644
index 0000000..fc0ebc5
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcHandler.java
@@ -0,0 +1,129 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.common.KrbUtil;
+import org.apache.kerberos.kerb.identity.IdentityService;
+import org.apache.kerberos.kerb.server.preauth.PreauthHandler;
+import org.apache.kerberos.kerb.server.replay.ReplayCheckService;
+import org.apache.kerberos.kerb.server.request.AsRequest;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.server.request.TgsRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.KrbMessage;
+import org.apache.kerberos.kerb.spec.common.KrbMessageType;
+import org.apache.kerberos.kerb.spec.kdc.AsReq;
+import org.apache.kerberos.kerb.spec.kdc.KdcReq;
+import org.apache.kerberos.kerb.spec.kdc.TgsReq;
+import org.apache.haox.transport.MessageHandler;
+import org.apache.haox.transport.Transport;
+import org.apache.haox.transport.event.MessageEvent;
+import org.apache.haox.transport.tcp.TcpTransport;
+
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class KdcHandler extends MessageHandler {
+
+    private List<String> kdcRealms = new ArrayList<String>(1);
+    private Map<String, KdcContext> kdcContexts;
+
+    private KdcConfig kdcConfig;
+    private PreauthHandler preauthHandler;
+
+    // TODO: per realm for below
+    private IdentityService identityService;
+    private ReplayCheckService replayCheckService;
+
+    /**
+     * Should be called when all the necessary properties are set
+     */
+    public void init() {
+        loadKdcRealms();
+
+        preauthHandler = new PreauthHandler();
+        preauthHandler.init(kdcConfig);
+
+        kdcContexts = new HashMap<String, KdcContext>(1);
+        for (String realm : kdcRealms) {
+            initRealmContext(realm);
+        }
+    }
+
+    private void initRealmContext(String kdcRealm) {
+        KdcContext kdcContext = new KdcContext();
+        kdcContext.init(kdcConfig);
+        kdcContext.setKdcRealm(kdcRealm);
+        kdcContext.setPreauthHandler(preauthHandler);
+        kdcContext.setIdentityService(identityService);
+        kdcContext.setReplayCache(replayCheckService);
+
+        kdcContexts.put(kdcRealm, kdcContext);
+    }
+
+    public void setKdcRealm(String realm) {
+        this.kdcRealms.add(realm);
+    }
+
+    public void setConfig(KdcConfig config) {
+        this.kdcConfig = config;
+    }
+
+    public void setIdentityService(IdentityService identityService) {
+        this.identityService = identityService;
+    }
+
+    @Override
+    protected void handleMessage(MessageEvent event) throws Exception {
+        ByteBuffer message = event.getMessage();
+        Transport transport = event.getTransport();
+
+        KrbMessage krbRequest = KrbUtil.decodeMessage(message);
+        KdcRequest kdcRequest = null;
+
+        KrbMessageType messageType = krbRequest.getMsgType();
+        if (messageType == KrbMessageType.TGS_REQ || messageType == KrbMessageType.AS_REQ) {
+            KdcReq kdcReq = (KdcReq) krbRequest;
+            String realm = getRequestRealm(kdcReq);
+            if (realm == null || !kdcContexts.containsKey(realm)) {
+                throw new KrbException("Invalid realm from kdc request: " + realm);
+            }
+
+            KdcContext kdcContext = kdcContexts.get(realm);
+            if (messageType == KrbMessageType.TGS_REQ) {
+                kdcRequest = new TgsRequest((TgsReq) kdcReq, kdcContext);
+            } else if (messageType == KrbMessageType.AS_REQ) {
+                kdcRequest = new AsRequest((AsReq) kdcReq, kdcContext);
+            }
+        }
+
+        InetSocketAddress clientAddress = transport.getRemoteAddress();
+        kdcRequest.setClientAddress(clientAddress.getAddress());
+        boolean isTcp = (transport instanceof TcpTransport);
+        kdcRequest.isTcp(isTcp);
+
+        kdcRequest.process();
+
+        KrbMessage krbResponse = kdcRequest.getReply();
+        KrbUtil.sendMessage(krbResponse, transport);
+    }
+
+    private void loadKdcRealms() {
+        if (kdcRealms.isEmpty()) {
+            kdcRealms.add(kdcConfig.getKdcRealm());
+        }
+    }
+
+    private String getRequestRealm(KdcReq kdcReq) {
+        String realm = kdcReq.getReqBody().getRealm();
+        if (realm == null && kdcReq.getReqBody().getCname() != null) {
+            realm = kdcReq.getReqBody().getCname().getRealm();
+        }
+        if (realm == null || realm.isEmpty()) {
+            realm = "NULL-KDC-REALM";
+        }
+        return realm;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcServer.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcServer.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcServer.java
new file mode 100644
index 0000000..41ce0de
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/KdcServer.java
@@ -0,0 +1,164 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.haox.event.EventHub;
+import org.apache.kerberos.kerb.common.KrbStreamingDecoder;
+import org.apache.kerberos.kerb.identity.IdentityService;
+import org.apache.haox.transport.Acceptor;
+import org.apache.haox.transport.tcp.TcpAcceptor;
+
+import java.io.File;
+
+public class KdcServer {
+    private String kdcHost;
+    private short kdcPort;
+    private String kdcRealm;
+
+    private boolean started;
+    private String serviceName = "HaoxKdc";
+
+    private KdcHandler kdcHandler;
+    private EventHub eventHub;
+
+    protected KdcConfig kdcConfig;
+    protected IdentityService identityService;
+    protected File workDir;
+
+    public KdcServer() {
+        kdcConfig = new KdcConfig();
+    }
+
+    public void init() {
+        initConfig();
+
+        initWorkDir();
+    }
+
+    protected void initWorkDir() {
+        String path = kdcConfig.getWorkDir();
+        File file;
+        if (path != null) {
+            file = new File(path);
+            file.mkdirs();
+        } else {
+            file = new File(".");
+        }
+
+        this.workDir = file;
+    }
+
+    protected void initConfig() {}
+
+    public void start() {
+        try {
+            doStart();
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to start " + getServiceName(), e);
+        }
+
+        started = true;
+    }
+
+    public String getKdcRealm() {
+        if (kdcRealm != null) {
+            return kdcRealm;
+        }
+        return kdcConfig.getKdcRealm();
+    }
+
+    private String getKdcHost() {
+        if (kdcHost != null) {
+            return kdcHost;
+        }
+        return kdcConfig.getKdcHost();
+    }
+
+    private short getKdcPort() {
+        if (kdcPort > 0) {
+            return kdcPort;
+        }
+        return kdcConfig.getKdcPort();
+    }
+
+    public void setKdcHost(String kdcHost) {
+        this.kdcHost = kdcHost;
+    }
+
+    public void setKdcPort(short kdcPort) {
+        this.kdcPort = kdcPort;
+    }
+
+    public void setKdcRealm(String realm) {
+        this.kdcRealm = realm;
+    }
+
+    public boolean enableDebug() {
+        return kdcConfig.enableDebug();
+    }
+
+    protected void doStart() throws Exception {
+        prepareHandler();
+
+        this.eventHub = new EventHub();
+
+        eventHub.register(kdcHandler);
+
+        Acceptor acceptor = new TcpAcceptor(new KrbStreamingDecoder());
+        eventHub.register(acceptor);
+
+        eventHub.start();
+        acceptor.listen(getKdcHost(), getKdcPort());
+    }
+
+    private void prepareHandler() {
+        this.kdcHandler = new KdcHandler();
+        kdcHandler.setConfig(kdcConfig);
+        kdcHandler.setIdentityService(identityService);
+        if (kdcRealm != null) {
+            kdcHandler.setKdcRealm(kdcRealm);
+        }
+        kdcHandler.init();
+    }
+
+    public void stop() {
+        try {
+            doStop();
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to stop " + getServiceName());
+        }
+    }
+
+    protected void doStop() throws Exception {
+        eventHub.stop();
+    }
+
+    public KdcConfig getConfig() {
+        return kdcConfig;
+    }
+
+    public boolean isStarted() {
+        return started;
+    }
+
+    protected void setStarted( boolean started ) {
+        this.started = started;
+    }
+
+    protected void setServiceName( String name ) {
+        this.serviceName = name;
+    }
+
+    protected String getServiceName() {
+        if (serviceName != null) {
+            return serviceName;
+        }
+        return kdcConfig.getKdcServiceName();
+    }
+
+    public IdentityService getIdentityService() {
+        return identityService;
+    }
+
+    protected void setIdentityService(IdentityService identityService) {
+        this.identityService = identityService;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/SimpleKdcServer.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/SimpleKdcServer.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/SimpleKdcServer.java
new file mode 100644
index 0000000..cf85161
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/SimpleKdcServer.java
@@ -0,0 +1,24 @@
+package org.apache.kerberos.kerb.server;
+
+import org.apache.kerberos.kerb.identity.IdentityService;
+import org.apache.kerberos.kerb.identity.backend.SimpleIdentityBackend;
+
+import java.io.File;
+
+public class SimpleKdcServer extends KdcServer {
+
+    public SimpleKdcServer() {
+        super();
+    }
+
+    public void init() {
+        super.init();
+        initIdentityService();
+    }
+
+    protected void initIdentityService() {
+        File identityFile = new File(workDir, "simplekdb.dat");
+        IdentityService identityService = new SimpleIdentityBackend(identityFile);
+        setIdentityService(identityService);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/AbstractPreauthPlugin.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/AbstractPreauthPlugin.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/AbstractPreauthPlugin.java
new file mode 100644
index 0000000..d23a7e3
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/AbstractPreauthPlugin.java
@@ -0,0 +1,72 @@
+package org.apache.kerberos.kerb.server.preauth;
+
+import org.apache.kerberos.kerb.preauth.PaFlags;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.PreauthPluginMeta;
+import org.apache.kerberos.kerb.server.KdcContext;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+public class AbstractPreauthPlugin implements KdcPreauth {
+
+    private PreauthPluginMeta pluginMeta;
+
+    public AbstractPreauthPlugin(PreauthPluginMeta meta) {
+        this.pluginMeta = meta;
+    }
+
+    @Override
+    public String getName() {
+        return pluginMeta.getName();
+    }
+
+    public int getVersion() {
+        return pluginMeta.getVersion();
+    }
+
+    public PaDataType[] getPaTypes() {
+        return pluginMeta.getPaTypes();
+    }
+
+    @Override
+    public void initWith(KdcContext kdcContext) {
+
+    }
+
+    @Override
+    public PluginRequestContext initRequestContext(KdcRequest kdcRequest) {
+        return null;
+    }
+
+    @Override
+    public void provideEdata(KdcRequest kdcRequest, PluginRequestContext requestContext,
+            PaData outPaData) throws KrbException {
+
+    }
+
+    @Override
+    public boolean verify(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                          PaDataEntry paData) throws KrbException {
+        return false;
+    }
+
+    @Override
+    public void providePaData(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                              PaData paData) {
+
+    }
+
+    @Override
+    public PaFlags getFlags(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                            PaDataType paType) {
+        return null;
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/FastContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/FastContext.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/FastContext.java
new file mode 100644
index 0000000..e367fbf
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/FastContext.java
@@ -0,0 +1,17 @@
+package org.apache.kerberos.kerb.server.preauth;
+
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.fast.FastOptions;
+import org.apache.kerberos.kerb.spec.fast.KrbFastArmor;
+import org.apache.kerberos.kerb.spec.kdc.KdcReq;
+
+public class FastContext {
+
+    public KdcReq fastOuterRequest;
+    public EncryptionKey armorKey;
+    public KrbFastArmor fastArmor;
+    public FastOptions fastOptions;
+    public int nonce;
+    public int fastFlags;
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/KdcPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/KdcPreauth.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/KdcPreauth.java
new file mode 100644
index 0000000..691a581
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/KdcPreauth.java
@@ -0,0 +1,62 @@
+package org.apache.kerberos.kerb.server.preauth;
+
+import org.apache.kerberos.kerb.preauth.PaFlags;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.PreauthPluginMeta;
+import org.apache.kerberos.kerb.server.KdcContext;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+/**
+ * KDC side preauth plugin module
+ */
+public interface KdcPreauth extends PreauthPluginMeta {
+
+    /**
+     * Initializing plugin context for each realm
+     */
+    public void initWith(KdcContext context);
+
+    /**
+     * Initializing request context
+     */
+    public PluginRequestContext initRequestContext(KdcRequest kdcRequest);
+
+    /**
+     * Optional: provide pa_data to send to the client as part of the "you need to
+     * use preauthentication" error.
+     */
+    public void provideEdata(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                             PaData outPaData) throws KrbException;
+
+    /**
+     * Optional: verify preauthentication data sent by the client, setting the
+     * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
+     * field as appropriate.
+     */
+    public boolean verify(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                          PaDataEntry paData) throws KrbException;
+
+    /**
+     * Optional: generate preauthentication response data to send to the client as
+     * part of the AS-REP.
+     */
+    public void providePaData(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                              PaData paData);
+
+    /**
+     * Return PA_REAL if pa_type is a real preauthentication type or PA_INFO if it is
+     * an informational type.
+     */
+    public PaFlags getFlags(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                            PaDataType paType);
+
+    /**
+     * When exiting...
+     */
+    public void destroy();
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthContext.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthContext.java
new file mode 100644
index 0000000..67aa7f7
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthContext.java
@@ -0,0 +1,25 @@
+package org.apache.kerberos.kerb.server.preauth;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PreauthContext {
+    private boolean preauthRequired = true;
+    private List<PreauthHandle> handles = new ArrayList<PreauthHandle>(5);
+
+    public PreauthContext() {
+
+    }
+
+    public boolean isPreauthRequired() {
+        return preauthRequired;
+    }
+
+    public void setPreauthRequired(boolean preauthRequired) {
+        this.preauthRequired = preauthRequired;
+    }
+
+    public List<PreauthHandle> getHandles() {
+        return handles;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandle.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandle.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandle.java
new file mode 100644
index 0000000..88ff628
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandle.java
@@ -0,0 +1,37 @@
+package org.apache.kerberos.kerb.server.preauth;
+
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+
+public class PreauthHandle {
+
+    public KdcPreauth preauth;
+    public PluginRequestContext requestContext;
+
+    public PreauthHandle(KdcPreauth preauth) {
+        this.preauth = preauth;
+    }
+
+    public void initRequestContext(KdcRequest kdcRequest) {
+        requestContext = preauth.initRequestContext(kdcRequest);
+    }
+
+    public void provideEdata(KdcRequest kdcRequest, PaData outPaData) throws KrbException {
+        preauth.provideEdata(kdcRequest, requestContext, outPaData);
+    }
+
+    public void verify(KdcRequest kdcRequest, PaDataEntry paData) throws KrbException {
+        preauth.verify(kdcRequest, requestContext, paData);
+    }
+
+    public void providePaData(KdcRequest kdcRequest, PaData paData) {
+        preauth.providePaData(kdcRequest, requestContext, paData);
+    }
+
+    public void destroy() {
+        preauth.destroy();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandler.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandler.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandler.java
new file mode 100644
index 0000000..2e2464f
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/PreauthHandler.java
@@ -0,0 +1,105 @@
+package org.apache.kerberos.kerb.server.preauth;
+
+import org.apache.kerberos.kerb.server.KdcConfig;
+import org.apache.kerberos.kerb.server.KdcContext;
+import org.apache.kerberos.kerb.server.preauth.builtin.EncTsPreauth;
+import org.apache.kerberos.kerb.server.preauth.builtin.TgtPreauth;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaData;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PreauthHandler {
+
+    private List<KdcPreauth> preauths;
+
+    /**
+     * Should be called only once, for global
+     */
+    public void init(KdcConfig kdcConfig) {
+        loadPreauthPlugins(kdcConfig);
+    }
+
+    private void loadPreauthPlugins(KdcConfig kdcConfig) {
+        preauths = new ArrayList<KdcPreauth>();
+
+        KdcPreauth preauth = new EncTsPreauth();
+        preauths.add(preauth);
+
+        preauth = new TgtPreauth();
+        preauths.add(preauth);
+    }
+
+    /**
+     * Should be called per realm
+     * @param context
+     */
+    public void initWith(KdcContext context) {
+        for (KdcPreauth preauth : preauths) {
+            preauth.initWith(context);
+        }
+    }
+
+    public PreauthContext preparePreauthContext(KdcRequest kdcRequest) {
+        PreauthContext preauthContext = new PreauthContext();
+
+        KdcContext kdcContext = kdcRequest.getKdcContext();
+        preauthContext.setPreauthRequired(kdcContext.getConfig().isPreauthRequired());
+
+        for (KdcPreauth preauth : preauths) {
+            PreauthHandle handle = new PreauthHandle(preauth);
+            handle.initRequestContext(kdcRequest);
+            preauthContext.getHandles().add(handle);
+        }
+
+        return preauthContext;
+    }
+
+    public void provideEdata(KdcRequest kdcRequest, PaData outPaData) throws KrbException {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        for (PreauthHandle handle : preauthContext.getHandles()) {
+            handle.provideEdata(kdcRequest, outPaData);
+        }
+    }
+
+    public void verify(KdcRequest kdcRequest, PaData paData) throws KrbException {
+        for (PaDataEntry paEntry : paData.getElements()) {
+            PreauthHandle handle = findHandle(kdcRequest, paEntry.getPaDataType());
+            if (handle != null) {
+                handle.verify(kdcRequest, paEntry);
+            }
+        }
+    }
+
+    public void providePaData(KdcRequest kdcRequest, PaData paData) {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        for (PreauthHandle handle : preauthContext.getHandles()) {
+            handle.providePaData(kdcRequest, paData);
+        }
+    }
+
+    private PreauthHandle findHandle(KdcRequest kdcRequest, PaDataType paType) {
+        PreauthContext preauthContext = kdcRequest.getPreauthContext();
+
+        for (PreauthHandle handle : preauthContext.getHandles()) {
+            for (PaDataType pt : handle.preauth.getPaTypes()) {
+                if (pt == paType) {
+                    return handle;
+                }
+            }
+        }
+        return null;
+    }
+
+    public void destroy() {
+        for (KdcPreauth preauth : preauths) {
+            preauth.destroy();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/EncTsPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/EncTsPreauth.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/EncTsPreauth.java
new file mode 100644
index 0000000..77a6c59
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/EncTsPreauth.java
@@ -0,0 +1,41 @@
+package org.apache.kerberos.kerb.server.preauth.builtin;
+
+import org.apache.kerberos.kerb.KrbErrorCode;
+import org.apache.kerberos.kerb.codec.KrbCodec;
+import org.apache.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.builtin.EncTsPreauthMeta;
+import org.apache.kerberos.kerb.server.KdcContext;
+import org.apache.kerberos.kerb.server.preauth.AbstractPreauthPlugin;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.EncryptedData;
+import org.apache.kerberos.kerb.spec.common.EncryptionKey;
+import org.apache.kerberos.kerb.spec.common.KeyUsage;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaEncTsEnc;
+
+public class EncTsPreauth extends AbstractPreauthPlugin {
+
+    public EncTsPreauth() {
+        super(new EncTsPreauthMeta());
+    }
+
+    @Override
+    public boolean verify(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                          PaDataEntry paData) throws KrbException {
+        EncryptedData encData = KrbCodec.decode(paData.getPaDataValue(), EncryptedData.class);
+        EncryptionKey clientKey = kdcRequest.getClientKey(encData.getEType());
+        PaEncTsEnc timestamp = EncryptionUtil.unseal(encData, clientKey,
+                KeyUsage.AS_REQ_PA_ENC_TS, PaEncTsEnc.class);
+
+        KdcContext kdcContext = kdcRequest.getKdcContext();
+        long clockSkew = kdcContext.getConfig().getAllowableClockSkew() * 1000;
+        if (!timestamp.getAllTime().isInClockSkew(clockSkew)) {
+            throw new KrbException(KrbErrorCode.KDC_ERR_PREAUTH_FAILED);
+        }
+
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/TgtPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/TgtPreauth.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/TgtPreauth.java
new file mode 100644
index 0000000..03bd54c
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/builtin/TgtPreauth.java
@@ -0,0 +1,26 @@
+package org.apache.kerberos.kerb.server.preauth.builtin;
+
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.builtin.TgtPreauthMeta;
+import org.apache.kerberos.kerb.server.preauth.AbstractPreauthPlugin;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.server.request.TgsRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+
+public class TgtPreauth extends AbstractPreauthPlugin {
+
+    public TgtPreauth() {
+        super(new TgtPreauthMeta());
+    }
+
+    @Override
+    public boolean verify(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                          PaDataEntry paData) throws KrbException {
+
+        TgsRequest tgsRequest = (TgsRequest) kdcRequest;
+        tgsRequest.verifyAuthenticator(paData);
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java
new file mode 100644
index 0000000..01bb6cb
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitKdcContext.java
@@ -0,0 +1,11 @@
+package org.apache.kerberos.kerb.server.preauth.pkinit;
+
+import org.apache.kerberos.kerb.preauth.pkinit.IdentityOpts;
+import org.apache.kerberos.kerb.preauth.pkinit.PluginOpts;
+
+public class PkinitKdcContext {
+
+    public PluginOpts pluginOpts;
+    public IdentityOpts identityOpts;
+    public String realm;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
new file mode 100644
index 0000000..8c2f6cc
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitPreauth.java
@@ -0,0 +1,74 @@
+package org.apache.kerberos.kerb.server.preauth.pkinit;
+
+import org.apache.kerberos.kerb.codec.KrbCodec;
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.preauth.pkinit.PkinitPreauthMeta;
+import org.apache.kerberos.kerb.server.KdcContext;
+import org.apache.kerberos.kerb.server.preauth.AbstractPreauthPlugin;
+import org.apache.kerberos.kerb.server.request.KdcRequest;
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.spec.common.PrincipalName;
+import org.apache.kerberos.kerb.spec.pa.PaDataEntry;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.kerberos.kerb.spec.pa.pkinit.PaPkAsReq;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PkinitPreauth extends AbstractPreauthPlugin {
+
+    private Map<String, PkinitKdcContext> pkinitContexts;
+
+    public PkinitPreauth() {
+        super(new PkinitPreauthMeta());
+
+        pkinitContexts = new HashMap<String, PkinitKdcContext>(1);
+    }
+
+    @Override
+    public void initWith(KdcContext kdcContext) {
+        super.initWith(kdcContext);
+
+        PkinitKdcContext tmp = new PkinitKdcContext();
+        tmp.realm = kdcContext.getKdcRealm();
+        pkinitContexts.put(kdcContext.getKdcRealm(), tmp);
+    }
+
+    @Override
+    public PluginRequestContext initRequestContext(KdcRequest kdcRequest) {
+        PkinitRequestContext reqCtx = new PkinitRequestContext();
+
+        //reqCtx.updateRequestOpts(pkinitContext.pluginOpts);
+
+        return reqCtx;
+    }
+
+    @Override
+    public boolean verify(KdcRequest kdcRequest, PluginRequestContext requestContext,
+                          PaDataEntry paData) throws KrbException {
+
+        PkinitRequestContext reqCtx = (PkinitRequestContext) requestContext;
+        PkinitKdcContext pkinitContext = findContext(kdcRequest.getServerPrincipal());
+        if (pkinitContext == null) {
+            return false;
+        }
+
+        reqCtx.paType = paData.getPaDataType();
+        if (paData.getPaDataType() == PaDataType.PK_AS_REQ) {
+            PaPkAsReq paPkAsReq = KrbCodec.decode(paData.getPaDataValue(), PaPkAsReq.class);
+            if (paPkAsReq == null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private PkinitKdcContext findContext(PrincipalName principal) {
+        String realm = principal.getRealm();
+        if (pkinitContexts.containsKey(realm)) {
+            return pkinitContexts.get(realm);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitRequestContext.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitRequestContext.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitRequestContext.java
new file mode 100644
index 0000000..b1e1631
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/preauth/pkinit/PkinitRequestContext.java
@@ -0,0 +1,11 @@
+package org.apache.kerberos.kerb.server.preauth.pkinit;
+
+import org.apache.kerberos.kerb.preauth.PluginRequestContext;
+import org.apache.kerberos.kerb.spec.pa.PaDataType;
+import org.apache.kerberos.kerb.spec.pa.pkinit.AuthPack;
+
+public class PkinitRequestContext implements PluginRequestContext {
+
+    public AuthPack authPack;
+    public PaDataType paType;
+}

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

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/CacheService.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/CacheService.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/CacheService.java
new file mode 100644
index 0000000..5b7daf9
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/CacheService.java
@@ -0,0 +1,7 @@
+package org.apache.kerberos.kerb.server.replay;
+
+public interface CacheService
+{
+    boolean checkAndCache(RequestRecord request);
+    void clear();
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckService.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckService.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckService.java
new file mode 100644
index 0000000..c9325df
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckService.java
@@ -0,0 +1,6 @@
+package org.apache.kerberos.kerb.server.replay;
+
+public interface ReplayCheckService
+{
+    boolean checkReplay(String clientPrincipal, String serverPrincipal, long requestTime, int microseconds);
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckServiceImpl.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckServiceImpl.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckServiceImpl.java
new file mode 100644
index 0000000..fa7057e
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/ReplayCheckServiceImpl.java
@@ -0,0 +1,21 @@
+package org.apache.kerberos.kerb.server.replay;
+
+public class ReplayCheckServiceImpl implements ReplayCheckService
+{
+    private CacheService cacheService;
+
+    public ReplayCheckServiceImpl(CacheService cacheService) {
+        this.cacheService = cacheService;
+    }
+
+    public ReplayCheckServiceImpl() {
+        this(new SimpleCacheService());
+    }
+
+    @Override
+    public boolean checkReplay(String clientPrincipal, String serverPrincipal,
+                               long requestTime, int microseconds) {
+        RequestRecord record = new RequestRecord(clientPrincipal, serverPrincipal, requestTime, microseconds);
+        return cacheService.checkAndCache(record);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/RequestRecord.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/RequestRecord.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/RequestRecord.java
new file mode 100644
index 0000000..a89cee4
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/RequestRecord.java
@@ -0,0 +1,39 @@
+package org.apache.kerberos.kerb.server.replay;
+
+public class RequestRecord {
+    private String clientPrincipal;
+    private String serverPrincipal;
+    private long requestTime;
+    private int microseconds;
+
+    public RequestRecord(String clientPrincipal, String serverPrincipal, long requestTime, int microseconds) {
+        this.clientPrincipal = clientPrincipal;
+        this.serverPrincipal = serverPrincipal;
+        this.requestTime = requestTime;
+        this.microseconds = microseconds;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        RequestRecord that = (RequestRecord) o;
+
+        if (microseconds != that.microseconds) return false;
+        if (requestTime != that.requestTime) return false;
+        if (!clientPrincipal.equals(that.clientPrincipal)) return false;
+        if (!serverPrincipal.equals(that.serverPrincipal)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = clientPrincipal.hashCode();
+        result = 31 * result + serverPrincipal.hashCode();
+        result = 31 * result + (int) (requestTime ^ (requestTime >>> 32));
+        result = 31 * result + microseconds;
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/SimpleCacheService.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/SimpleCacheService.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/SimpleCacheService.java
new file mode 100644
index 0000000..fd7bd13
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/replay/SimpleCacheService.java
@@ -0,0 +1,27 @@
+package org.apache.kerberos.kerb.server.replay;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class SimpleCacheService implements CacheService {
+    private Set<RequestRecord> requests;
+
+    public SimpleCacheService() {
+        requests = new HashSet<RequestRecord>();
+    }
+
+    @Override
+    public boolean checkAndCache(RequestRecord request) {
+        if (requests.contains(request)) {
+            return true;
+        } else {
+            requests.add(request);
+        }
+        return false;
+    }
+
+    @Override
+    public void clear() {
+        requests.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/request/AsRequest.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/request/AsRequest.java b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/request/AsRequest.java
new file mode 100644
index 0000000..b54c849
--- /dev/null
+++ b/haox-kerb/kerb-server/src/main/java/org/apache/kerberos/kerb/server/request/AsRequest.java
@@ -0,0 +1,72 @@
+package org.apache.kerberos.kerb.server.request;
+
+import org.apache.kerberos.kerb.KrbException;
+import org.apache.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerberos.kerb.server.KdcContext;
+import org.apache.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerberos.kerb.spec.common.*;
+import org.apache.kerberos.kerb.spec.kdc.*;
+import org.apache.kerberos.kerb.spec.ticket.Ticket;
+import org.apache.kerberos.kerb.spec.ticket.TicketFlag;
+
+public class AsRequest extends KdcRequest {
+
+    public AsRequest(AsReq asReq, KdcContext kdcContext) {
+        super(asReq, kdcContext);
+    }
+
+    @Override
+    protected void makeReply() throws KrbException {
+        Ticket ticket = getTicket();
+
+        AsRep reply = new AsRep();
+
+        reply.setCname(getClientEntry().getPrincipal());
+        reply.setCrealm(kdcContext.getServerRealm());
+        reply.setTicket(ticket);
+
+        EncKdcRepPart encKdcRepPart = makeEncKdcRepPart();
+        reply.setEncPart(encKdcRepPart);
+
+        EncryptionKey clientKey = getClientKey();
+        EncryptedData encryptedData = EncryptionUtil.seal(encKdcRepPart,
+                clientKey, KeyUsage.AS_REP_ENCPART);
+        reply.setEncryptedEncPart(encryptedData);
+
+        setReply(reply);
+    }
+
+    protected EncKdcRepPart makeEncKdcRepPart() {
+        KdcReq request = getKdcReq();
+        Ticket ticket = getTicket();
+
+        EncKdcRepPart encKdcRepPart = new EncAsRepPart();
+
+        //session key
+        encKdcRepPart.setKey(ticket.getEncPart().getKey());
+
+        LastReq lastReq = new LastReq();
+        LastReqEntry entry = new LastReqEntry();
+        entry.setLrType(LastReqType.THE_LAST_INITIAL);
+        entry.setLrValue(new KerberosTime());
+        lastReq.add(entry);
+        encKdcRepPart.setLastReq(lastReq);
+
+        encKdcRepPart.setNonce(request.getReqBody().getNonce());
+
+        encKdcRepPart.setFlags(ticket.getEncPart().getFlags());
+        encKdcRepPart.setAuthTime(ticket.getEncPart().getAuthTime());
+        encKdcRepPart.setStartTime(ticket.getEncPart().getStartTime());
+        encKdcRepPart.setEndTime(ticket.getEncPart().getEndTime());
+
+        if (ticket.getEncPart().getFlags().isFlagSet(TicketFlag.RENEWABLE)) {
+            encKdcRepPart.setRenewTill(ticket.getEncPart().getRenewtill());
+        }
+
+        encKdcRepPart.setSname(ticket.getSname());
+        encKdcRepPart.setSrealm(ticket.getRealm());
+        encKdcRepPart.setCaddr(ticket.getEncPart().getClientAddresses());
+
+        return encKdcRepPart;
+    }
+}


Mime
View raw message