You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by co...@apache.org on 2017/07/21 15:03:19 UTC

[02/18] directory-kerby git commit: DIRKRB-555 - Implement GSSNameSpi interface. Thanks to Wei Zhou.

DIRKRB-555 - Implement GSSNameSpi interface. Thanks to Wei Zhou.


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

Branch: refs/heads/trunk
Commit: b81a39bfdaa7903eb5588ae395b3fe133ff04464
Parents: d58e342
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Fri Jul 21 14:45:27 2017 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Fri Jul 21 14:45:51 2017 +0100

----------------------------------------------------------------------
 build-tools/kerby-checkstyle.xml                |   2 +-
 .../kerberos/kerb/gssapi/KerbyMechFactory.java  | 150 +++++++++++++++++++
 .../kerby/kerberos/kerb/gssapi/Provider.java    |  46 ++++++
 .../kerberos/kerb/gssapi/krb5/CredUtils.java    |  91 +++++++++++
 .../kerb/gssapi/krb5/KerbyAcceptCred.java       |  72 +++++++++
 .../kerb/gssapi/krb5/KerbyCredElement.java      |  80 ++++++++++
 .../kerb/gssapi/krb5/KerbyInitCred.java         |  53 +++++++
 .../kerb/gssapi/krb5/KerbyNameElement.java      | 134 +++++++++++++++++
 8 files changed, 627 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/build-tools/kerby-checkstyle.xml
----------------------------------------------------------------------
diff --git a/build-tools/kerby-checkstyle.xml b/build-tools/kerby-checkstyle.xml
index ff9f5de..714a86f 100644
--- a/build-tools/kerby-checkstyle.xml
+++ b/build-tools/kerby-checkstyle.xml
@@ -67,7 +67,7 @@
         <!-- Checks for imports                              -->
         <!-- See http://checkstyle.sf.net/config_import.html -->
         <!-- module name="AvoidStarImport"/ -->
-        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+        <!-- module name="IllegalImport"/ --> <!-- defaults to sun.* packages -->
         <module name="RedundantImport"/>
         <module name="UnusedImports"/>
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/KerbyMechFactory.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/KerbyMechFactory.java b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/KerbyMechFactory.java
new file mode 100644
index 0000000..a897c29
--- /dev/null
+++ b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/KerbyMechFactory.java
@@ -0,0 +1,150 @@
+/**
+ *  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.gssapi;
+
+import org.apache.kerby.kerberos.kerb.gssapi.krb5.KerbyAcceptCred;
+import org.apache.kerby.kerberos.kerb.gssapi.krb5.KerbyCredElement;
+import org.apache.kerby.kerberos.kerb.gssapi.krb5.KerbyInitCred;
+import org.apache.kerby.kerberos.kerb.gssapi.krb5.KerbyNameElement;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+import sun.security.jgss.GSSCaller;
+import sun.security.jgss.spi.GSSContextSpi;
+import sun.security.jgss.spi.GSSCredentialSpi;
+import sun.security.jgss.spi.GSSNameSpi;
+import sun.security.jgss.spi.MechanismFactory;
+
+import java.security.Provider;
+
+/**
+ * Kerby Kerberos V5 plugin for JGSS
+ */
+public class KerbyMechFactory implements MechanismFactory {
+    private static final Provider PROVIDER =
+            new org.apache.kerby.kerberos.kerb.gssapi.Provider();
+
+    private static final String KRB5_OID_STRING = "1.2.840.113554.1.2.2";
+    private static final Oid KRB5_OID = createOid(KRB5_OID_STRING);
+
+    private static Oid[] nameTypes =
+            new Oid[] {
+                    GSSName.NT_USER_NAME,
+                    GSSName.NT_EXPORT_NAME,
+                    GSSName.NT_HOSTBASED_SERVICE
+            };
+
+    private final GSSCaller caller;
+
+    public Oid getMechanismOid() {
+        return KRB5_OID;
+    }
+
+    public Provider getProvider() {
+        return PROVIDER;
+    }
+
+    public Oid[] getNameTypes() throws GSSException {
+        return nameTypes;
+    }
+
+    public KerbyMechFactory(GSSCaller caller) {
+        this.caller = caller;
+    }
+
+    public GSSNameSpi getNameElement(String nameStr, Oid nameType)
+            throws GSSException {
+        return KerbyNameElement.getInstance(nameStr, nameType);
+    }
+
+    public GSSNameSpi getNameElement(byte[] name, Oid nameType)
+            throws GSSException {
+        return KerbyNameElement.getInstance(name.toString(), nameType);
+    }
+
+    // Used by initiator
+    public GSSContextSpi getMechanismContext(GSSNameSpi peer,
+                                             GSSCredentialSpi myInitiatorCred,
+                                             int lifetime) throws GSSException {
+        if (peer != null && !(peer instanceof KerbyNameElement)) {
+            peer = KerbyNameElement.getInstance(peer.toString(), peer.getStringNameType());
+        }
+        if (myInitiatorCred == null) {
+            myInitiatorCred = getCredentialElement(null, lifetime, 0, GSSCredential.INITIATE_ONLY);
+        }
+        return null;
+        //For convenience of making patch, return null instead of introduce in KerbyContext
+        //return new KerbyContext(caller, (KerbyNameElement)peer, (KerbyInitCred)myInitiatorCred, lifetime);
+    }
+
+    public GSSContextSpi getMechanismContext(GSSCredentialSpi myAcceptorCred)
+            throws GSSException {
+        if (myAcceptorCred == null) {
+            myAcceptorCred = getCredentialElement(null, 0,
+                    GSSCredential.INDEFINITE_LIFETIME, GSSCredential.ACCEPT_ONLY);
+        }
+        return null; //return new KerbyContext(caller, (KerbyAcceptCred)myAcceptorCred);
+    }
+
+    // Reconstruct from previously exported context
+    public GSSContextSpi getMechanismContext(byte[] exportedContext)
+            throws GSSException {
+        return null; //return new KerbyContext(caller, exportedContext);
+    }
+
+    public GSSCredentialSpi getCredentialElement(GSSNameSpi name,
+                                                 int initLifetime,
+                                                 int acceptLifetime,
+                                                 int usage)
+            throws GSSException {
+        if (name != null && !(name instanceof KerbyNameElement)) {
+            name = KerbyNameElement.getInstance(name.toString(), name.getStringNameType());
+        }
+
+        KerbyCredElement credElement;
+
+        if (usage == GSSCredential.INITIATE_ONLY) {
+            credElement = KerbyInitCred.getInstance(caller, (KerbyNameElement) name, initLifetime);
+        } else if (usage == GSSCredential.ACCEPT_ONLY) {
+            credElement = KerbyAcceptCred.getInstance(caller, (KerbyNameElement) name, acceptLifetime);
+        } else if (usage == GSSCredential.INITIATE_AND_ACCEPT) {
+            throw new GSSException(GSSException.FAILURE, -1, "Unsupported usage mode: INITIATE_AND_ACCEPT");
+        } else {
+            throw new GSSException(GSSException.FAILURE, -1, "Unknown usage mode: " + usage);
+        }
+
+        return credElement;
+    }
+
+    private static Oid createOid(String oidStr) {
+        Oid retVal;
+        try {
+            retVal = new Oid(oidStr);
+        } catch (GSSException e) {
+            retVal = null;
+        }
+        return retVal;
+    }
+
+    public static Oid getOid() {
+        return KRB5_OID;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/Provider.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/Provider.java b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/Provider.java
new file mode 100644
index 0000000..ad3a614
--- /dev/null
+++ b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/Provider.java
@@ -0,0 +1,46 @@
+/**
+ *  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.gssapi;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Proivder is used to register the implementation of gssapi mechanism into the system
+ */
+public final class Provider extends java.security.Provider {
+    private static final long serialVersionUID = 3787378212107821987L;
+    private static final String INFO = "Kerby GssApi Provider";
+    private static final String MECHANISM_GSSAPI = "GssApiMechanism.1.2.840.113554.1.2.2";
+    private static final String MECHANISM_GSSAPI_CLASS = "org.apache.kerby.kerberos.kerb.gssapi.KerbyMechFactory";
+
+    public Provider() {
+        super("KerbyGssApi", 0.01d, INFO);
+
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+
+                put(MECHANISM_GSSAPI, MECHANISM_GSSAPI_CLASS);
+
+                return null;
+            }
+        });
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/CredUtils.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/CredUtils.java b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/CredUtils.java
new file mode 100644
index 0000000..6d066db
--- /dev/null
+++ b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/CredUtils.java
@@ -0,0 +1,91 @@
+package org.apache.kerby.kerberos.kerb.gssapi.krb5;
+
+import org.ietf.jgss.GSSException;
+import sun.security.jgss.GSSCaller;
+
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.kerberos.KeyTab;
+import javax.security.auth.kerberos.ServicePermission;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Set;
+
+/**
+ * Utility functions to deal with credentials in Context
+ */
+public class CredUtils {
+
+    public static <T> Set<T> getContextPrivateCredentials(Class<T> credentialType, AccessControlContext acc) {
+        Subject subject = Subject.getSubject(acc);
+        Set<T> creds = subject.getPrivateCredentials(credentialType);
+        return creds;
+    }
+
+    public static <T> Set<T> getContextCredentials(final Class<T> credentialType) throws GSSException {
+        final AccessControlContext acc = AccessController.getContext();
+        try {
+            return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Set<T>>() {
+                        public Set<T> run() throws Exception {
+                            return CredUtils.getContextPrivateCredentials(credentialType, acc);
+                        }
+                    });
+        } catch (PrivilegedActionException e) {
+            throw new GSSException(GSSException.NO_CRED, -1, "Get credential from context failed");
+        }
+    }
+
+    public static KerberosTicket getKerberosTicketFromContext(GSSCaller caller,
+                                                              final String clientName,
+                                                              final String serverName) throws GSSException {
+        Set<KerberosTicket> tickets = getContextCredentials(KerberosTicket.class);
+        for (KerberosTicket ticket : tickets) {
+            if (ticket.isCurrent() && (serverName == null || ticket.getServer().getName().equals(serverName))
+                    && (clientName == null || ticket.getClient().getName().equals(clientName))) {
+                return ticket;
+            }
+        }
+        return null;
+    }
+
+    public static KeyTab getKeyTabFromContext(KerberosPrincipal principal) throws GSSException {
+        Set<KeyTab> tabs = getContextCredentials(KeyTab.class);
+        for (KeyTab tab : tabs) {
+            if (tab.getPrincipal().equals(principal)) {
+                return tab;
+            }
+        }
+        return null;
+    }
+
+    public static void addCredentialToSubject(final KerberosTicket ticket) throws GSSException {
+        final AccessControlContext acc = AccessController.getContext();
+
+        final Subject subject = AccessController.doPrivileged(
+                new java.security.PrivilegedAction<Subject>() {
+                    public Subject run() {
+                        return Subject.getSubject(acc);
+                    }
+                });
+
+        AccessController.doPrivileged(
+                new java.security.PrivilegedAction<Void>() {
+                    public Void run() {
+                        subject.getPrivateCredentials().add(ticket);
+                        return null;
+                    }
+                });
+    }
+
+    public static void checkPrincipalPermission(String principalName, String action) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            ServicePermission sp = new ServicePermission(principalName, action);
+            sm.checkPermission(sp);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyAcceptCred.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyAcceptCred.java b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyAcceptCred.java
new file mode 100644
index 0000000..a7331fa
--- /dev/null
+++ b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyAcceptCred.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.gssapi.krb5;
+
+
+import org.ietf.jgss.GSSException;
+import sun.security.jgss.GSSCaller;
+
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KeyTab;
+
+public final class KerbyAcceptCred extends KerbyCredElement {
+
+    private final KeyTab keyTab;
+
+    public static KerbyAcceptCred getInstance(final GSSCaller caller,
+                                              KerbyNameElement name, int lifeTime) throws GSSException {
+
+        KerberosPrincipal princ = new KerberosPrincipal(name.getPrincipalName().getName(),
+                name.getPrincipalName().getNameType().getValue());
+        KeyTab keyTab = CredUtils.getKeyTabFromContext(princ);
+
+        if (keyTab == null) {
+            throw new GSSException(GSSException.NO_CRED, -1,
+                    "Failed to find any Kerberos credential for " + name.getPrincipalName().getName());
+        }
+
+        return new KerbyAcceptCred(caller, name, keyTab, lifeTime);
+    }
+
+    private KerbyAcceptCred(GSSCaller caller, KerbyNameElement name, KeyTab keyTab, int lifeTime) {
+        super(caller, name);
+        this.keyTab = keyTab;
+        this.accLifeTime = lifeTime;
+    }
+
+    public boolean isInitiatorCredential() throws GSSException {
+        return false;
+    }
+
+    public boolean isAcceptorCredential() throws GSSException {
+        return true;
+    }
+
+    public KeyTab getKeyTab() {
+        return this.keyTab;
+    }
+
+    public KerberosKey[] getKeys() {
+        KerberosPrincipal princ = new KerberosPrincipal(name.getPrincipalName().getName(),
+                name.getPrincipalName().getNameType().getValue());
+        return keyTab.getKeys(princ);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyCredElement.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyCredElement.java b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyCredElement.java
new file mode 100644
index 0000000..c52b3ea
--- /dev/null
+++ b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyCredElement.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.gssapi.krb5;
+
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.Oid;
+import sun.security.jgss.GSSCaller;
+import sun.security.jgss.spi.GSSCredentialSpi;
+import sun.security.jgss.spi.GSSNameSpi;
+
+import java.security.Provider;
+
+public abstract class KerbyCredElement implements GSSCredentialSpi {
+
+    static final Oid KRB5_OID = createOid("1.2.840.113554.1.2.2");
+
+    protected GSSCaller caller;
+    protected KerbyNameElement name;
+    protected int initLifeTime;
+    protected int accLifeTime;
+
+    KerbyCredElement(GSSCaller caller, KerbyNameElement name) {
+        this.caller = caller;
+        this.name = name;
+    }
+
+    public Provider getProvider() {
+        return new org.apache.kerby.kerberos.kerb.gssapi.Provider();
+    }
+
+    public void dispose() throws GSSException {
+    }
+
+    public GSSNameSpi getName() throws GSSException {
+        return name;
+    }
+
+    public int getInitLifetime() throws GSSException {
+        return initLifeTime;
+    }
+
+    public int getAcceptLifetime() throws GSSException {
+        return accLifeTime;
+    }
+
+    public Oid getMechanism() {
+        return KRB5_OID;
+    }
+
+    public GSSCredentialSpi impersonate(GSSNameSpi name) throws GSSException {
+        throw new GSSException(GSSException.FAILURE, -1, "Unsupported feature");  // TODO:
+    }
+
+    private static Oid createOid(String oidStr) {
+        Oid retVal;
+        try {
+            retVal = new Oid(oidStr);
+        } catch (GSSException e) {
+            retVal = null; // get rid of blank catch block warning
+        }
+        return retVal;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyInitCred.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyInitCred.java b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyInitCred.java
new file mode 100644
index 0000000..d04f915
--- /dev/null
+++ b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyInitCred.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.gssapi.krb5;
+
+import org.ietf.jgss.GSSException;
+import sun.security.jgss.GSSCaller;
+
+import javax.security.auth.kerberos.KerberosTicket;
+
+public final class KerbyInitCred extends KerbyCredElement {
+
+    public KerberosTicket ticket;
+
+    private KerbyInitCred(GSSCaller caller, KerbyNameElement name, KerberosTicket ticket, int lifeTime) {
+        super(caller, name);
+        this.ticket = ticket;
+        this.initLifeTime = lifeTime;
+    }
+
+    public static KerbyInitCred getInstance(GSSCaller caller, KerbyNameElement name, int lifeTime) throws GSSException {
+        KerberosTicket ticket = CredUtils.getKerberosTicketFromContext(caller, name.getPrincipalName().getName(), null);
+        return new KerbyInitCred(caller, name, ticket, lifeTime);
+    }
+
+    public boolean isInitiatorCredential() throws GSSException {
+        return true;
+    }
+
+    public boolean isAcceptorCredential() throws GSSException {
+        return false;
+    }
+
+    public KerberosTicket getKerberosTicket() {
+        return ticket;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b81a39bf/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyNameElement.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyNameElement.java b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyNameElement.java
new file mode 100644
index 0000000..9c93143
--- /dev/null
+++ b/kerby-kerb/kerb-gssapi/src/main/java/org/apache/kerby/kerberos/kerb/gssapi/krb5/KerbyNameElement.java
@@ -0,0 +1,134 @@
+/**
+ *  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.gssapi.krb5;
+
+import org.apache.kerby.kerberos.kerb.gssapi.KerbyMechFactory;
+import org.apache.kerby.kerberos.kerb.type.base.NameType;
+import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+import sun.security.jgss.spi.GSSNameSpi;
+import java.io.UnsupportedEncodingException;
+import java.security.Provider;
+
+public class KerbyNameElement implements GSSNameSpi {
+
+    private PrincipalName principalName;
+    private Oid nameType = null;
+
+    KerbyNameElement(PrincipalName principalName,
+                     Oid nameType) {
+        this.principalName = principalName;
+        this.nameType = nameType;
+    }
+
+    public PrincipalName toKerbyPrincipalName(sun.security.krb5.PrincipalName name) {
+        return new PrincipalName(name.getNameString(), toKerbyNameType(name.getNameType()));
+    }
+
+    private NameType toKerbyNameType(int intNameType) {
+        return NameType.fromValue(intNameType);
+    }
+
+    public static NameType toKerbyNameType(Oid nameType) throws GSSException {
+        NameType kerbyNameType;
+
+        if (nameType == null) {
+            throw new GSSException(GSSException.BAD_NAMETYPE);
+        }
+
+        if (nameType.equals(GSSName.NT_EXPORT_NAME) || nameType.equals(GSSName.NT_USER_NAME)) {
+            kerbyNameType = NameType.NT_PRINCIPAL;
+        } else if (nameType.equals(GSSName.NT_HOSTBASED_SERVICE)) {
+            kerbyNameType = NameType.NT_SRV_HST;
+        } else {
+            throw new GSSException(GSSException.BAD_NAMETYPE, 0, "Unsupported Oid name type");
+        }
+        return kerbyNameType;
+    }
+
+    public static KerbyNameElement getInstance(String name, Oid oidNameType)
+            throws GSSException {
+        PrincipalName principalName = new PrincipalName(name, toKerbyNameType(oidNameType));
+        return new KerbyNameElement(principalName, oidNameType);
+    }
+
+    public Provider getProvider() {
+        return new org.apache.kerby.kerberos.kerb.gssapi.Provider();
+    }
+
+    public boolean equals(GSSNameSpi name) throws GSSException {
+        if (name == null || name.isAnonymousName() || isAnonymousName()) {
+            return false;
+        }
+        return this.toString().equals(name.toString()) && this.getStringNameType().equals(name.getStringNameType());
+    }
+
+    public final PrincipalName getPrincipalName() {
+        return principalName;
+    }
+
+    public boolean equals(Object another) {
+        if (another == null) {
+            return false;
+        }
+
+        try {
+            if (another instanceof GSSNameSpi) {
+                return equals((GSSNameSpi) another);
+            }
+        } catch (GSSException e) {
+            return false;
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        return principalName.hashCode();
+    }
+
+    public byte[] export() throws GSSException {
+        byte[] retVal;
+        try {
+            retVal = principalName.getName().getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new GSSException(GSSException.BAD_NAME, -1, e.getMessage());
+        }
+        return retVal;
+    }
+
+    public Oid getMechanism() {
+        return KerbyMechFactory.getOid();
+    }
+
+    public String toString() {
+        return principalName.toString();
+    }
+
+    public Oid getStringNameType() {
+        return nameType;
+    }
+
+    public boolean isAnonymousName() {
+        return nameType.equals(GSSName.NT_ANONYMOUS);
+    }
+}