You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2017/10/18 08:29:01 UTC

[3/9] directory-kerby git commit: DIRKRB-648 Cross realm client side implementation. Contributed by Frank.

DIRKRB-648 Cross realm client side implementation. Contributed by Frank.


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

Branch: refs/heads/trunk
Commit: fdfc559a2e573cd2ee993b91904665f7045eb026
Parents: 56ca72b
Author: plusplusjiajia <ji...@intel.com>
Authored: Fri Sep 22 16:05:07 2017 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Wed Oct 18 16:27:18 2017 +0800

----------------------------------------------------------------------
 .../kerby/kerberos/kerb/client/ClientUtil.java  |  3 +-
 .../client/impl/AbstractInternalKrbClient.java  | 62 ++++++++++++++------
 .../client/impl/DefaultInternalKrbClient.java   |  8 ++-
 .../kerb/client/request/KdcRequest.java         | 12 ++--
 .../kerb/client/request/TgsRequest.java         | 10 ++--
 .../kerb/client/request/TgsRequestWithTgt.java  | 35 +++++++----
 .../kerby/kerberos/kerb/common/KrbUtil.java     | 11 ++++
 .../kerby/kerberos/tool/kinit/KinitTool.java    |  6 +-
 8 files changed, 100 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/ClientUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/ClientUtil.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/ClientUtil.java
index 35a2ed8..b2a1122 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/ClientUtil.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/ClientUtil.java
@@ -213,7 +213,8 @@ public final class ClientUtil {
             }
 
             if (kdcList.isEmpty()) {
-                LOG.error("Cannot get kdc for realm " + realm);
+                LOG.warn("Cannot get kdc for realm " + realm);
+                kdcList.add(krbSetting.getKdcHost());
             }
         } else {
             throw new KrbException("Can't get the realm");

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
index 27ecd5e..8c8d6ed 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/AbstractInternalKrbClient.java
@@ -25,6 +25,7 @@ import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.client.KrbContext;
 import org.apache.kerby.kerberos.kerb.client.KrbOption;
 import org.apache.kerby.kerberos.kerb.client.KrbSetting;
+import org.apache.kerby.kerberos.kerb.client.KrbConfig;
 import org.apache.kerby.kerberos.kerb.client.PkinitOption;
 import org.apache.kerby.kerberos.kerb.client.TokenOption;
 import org.apache.kerby.kerberos.kerb.client.request.AsRequest;
@@ -41,6 +42,8 @@ import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
 import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
 import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
 
+import java.util.LinkedList;
+
 /**
  * A krb client API for applications to interact with KDC
  */
@@ -79,7 +82,7 @@ public abstract class AbstractInternalKrbClient implements InternalKrbClient {
     @Override
     public TgtTicket requestTgt(KOptions requestOptions) throws KrbException {
         AsRequest asRequest = null;
-        PrincipalName clientPrincipal = null;
+        PrincipalName clientPrincipalName = null;
 
         if (requestOptions.contains(KrbOption.USE_PASSWD)) {
             asRequest = new AsRequestWithPasswd(context);
@@ -101,24 +104,24 @@ public abstract class AbstractInternalKrbClient implements InternalKrbClient {
         }
 
         if (requestOptions.contains(KrbOption.CLIENT_PRINCIPAL)) {
-            String clientPrincipalName = requestOptions.getStringOption(KrbOption.CLIENT_PRINCIPAL);
-            clientPrincipalName = fixPrincipal(clientPrincipalName);
-            clientPrincipal = new PrincipalName(clientPrincipalName);
+            String clientPrincipalString = requestOptions.getStringOption(KrbOption.CLIENT_PRINCIPAL);
+            clientPrincipalString = fixPrincipal(clientPrincipalString);
+            clientPrincipalName = new PrincipalName(clientPrincipalString);
             if (requestOptions.contains(PkinitOption.USE_ANONYMOUS)) {
-                clientPrincipal.setNameType(NameType.NT_WELLKNOWN);
+                clientPrincipalName.setNameType(NameType.NT_WELLKNOWN);
             }
-            asRequest.setClientPrincipal(clientPrincipal);
+            asRequest.setClientPrincipal(clientPrincipalName);
         }
 
         if (requestOptions.contains(KrbOption.SERVER_PRINCIPAL)) {
-            String serverPrincipalName = requestOptions.getStringOption(KrbOption.SERVER_PRINCIPAL);
-            serverPrincipalName = fixPrincipal(serverPrincipalName);
-            PrincipalName serverPrincipal = new PrincipalName(serverPrincipalName, NameType.NT_PRINCIPAL);
-            asRequest.setServerPrincipal(serverPrincipal);
-        } else if (clientPrincipal != null) {
-            String realm = clientPrincipal.getRealm();
-            PrincipalName serverPrincipal = KrbUtil.makeTgsPrincipal(realm);
-            asRequest.setServerPrincipal(serverPrincipal);
+            String serverPrincipalString = requestOptions.getStringOption(KrbOption.SERVER_PRINCIPAL);
+            serverPrincipalString = fixPrincipal(serverPrincipalString);
+            PrincipalName serverPrincipalName = new PrincipalName(serverPrincipalString, NameType.NT_PRINCIPAL);
+            asRequest.setServerPrincipal(serverPrincipalName);
+        } else if (clientPrincipalName != null) {
+            String realm = clientPrincipalName.getRealm();
+            PrincipalName serverPrincipalName = KrbUtil.makeTgsPrincipal(realm);
+            asRequest.setServerPrincipal(serverPrincipalName);
         }
 
         asRequest.setRequestOptions(requestOptions);
@@ -132,12 +135,13 @@ public abstract class AbstractInternalKrbClient implements InternalKrbClient {
     @Override
     public SgtTicket requestSgt(KOptions requestOptions) throws KrbException {
         TgsRequest tgsRequest = null;
+        TgtTicket tgtTicket = null;
         if (requestOptions.contains(TokenOption.USER_AC_TOKEN)) {
             tgsRequest = new TgsRequestWithToken(context);
         } else if (requestOptions.contains(KrbOption.USE_TGT)) {
             KOption kOpt = requestOptions.getOption(KrbOption.USE_TGT);
-            tgsRequest = new TgsRequestWithTgt(context,
-                (TgtTicket) kOpt.getOptionInfo().getValue());
+            tgtTicket = (TgtTicket) kOpt.getOptionInfo().getValue();
+            tgsRequest = new TgsRequestWithTgt(context, tgtTicket);
         }
 
         if (tgsRequest == null) {
@@ -145,11 +149,31 @@ public abstract class AbstractInternalKrbClient implements InternalKrbClient {
                     "No valid krb client request option found");
         }
 
-        String serverPrincipal = fixPrincipal(requestOptions.
+        String serverPrincipalString = fixPrincipal(requestOptions.
                 getStringOption(KrbOption.SERVER_PRINCIPAL));
-        tgsRequest.setServerPrincipal(new PrincipalName(serverPrincipal));
-        tgsRequest.setRequestOptions(requestOptions);
+        PrincipalName serverPrincipalName = new PrincipalName(serverPrincipalString);
+
+        if (tgtTicket != null) {
+            String sourceRealm = tgtTicket.getRealm();
+            String destRealm = serverPrincipalName.getRealm();
+            if (!sourceRealm.equals(destRealm)) {
+                KrbConfig krbConfig = krbSetting.getKrbConfig();
+                LinkedList<String> capath = krbConfig.getCapath(sourceRealm, destRealm);
+                PrincipalName clientPrincipalName = tgtTicket.getClientPrincipal();
+                for (int i = 0; i < capath.size() - 1; i++) {
+                    PrincipalName tgsPrincipalName = KrbUtil.makeTgsPrincipal(
+                        capath.get(i), capath.get(i + 1));
+                    tgsRequest.setServerPrincipal(tgsPrincipalName);
+                    tgsRequest.setRequestOptions(requestOptions);
+                    SgtTicket sgtTicket = doRequestSgt(tgsRequest);
+                    sgtTicket.setClientPrincipal(clientPrincipalName);
+                    tgsRequest = new TgsRequestWithTgt(context, sgtTicket);
+                }
+            }
+        }
 
+        tgsRequest.setServerPrincipal(serverPrincipalName);
+        tgsRequest.setRequestOptions(requestOptions);
         return doRequestSgt(tgsRequest);
     }
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/DefaultInternalKrbClient.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/DefaultInternalKrbClient.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/DefaultInternalKrbClient.java
index e383dbe..781351f 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/DefaultInternalKrbClient.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/impl/DefaultInternalKrbClient.java
@@ -28,6 +28,7 @@ import org.apache.kerby.kerberos.kerb.client.request.TgsRequest;
 import org.apache.kerby.kerberos.kerb.transport.KrbNetwork;
 import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
 import org.apache.kerby.kerberos.kerb.transport.TransportPair;
+import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
 import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
 import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
 import org.slf4j.Logger;
@@ -63,9 +64,10 @@ public class DefaultInternalKrbClient extends AbstractInternalKrbClient {
 
     private void doRequest(KdcRequest request) throws KrbException {
 
-        String realm = request.getClientPrincipal().getRealm();
-        if (realm == null || realm.isEmpty()) {
-            realm = getSetting().getKdcRealm();
+        String realm = getSetting().getKdcRealm();
+        PrincipalName serverPrincipalName = request.getServerPrincipal();
+        if (serverPrincipalName != null && serverPrincipalName.getRealm() != null) {
+            realm = serverPrincipalName.getRealm();
         }
         List<String> kdcList = ClientUtil.getKDCList(realm, getSetting());
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
index cd473e0..be5efc4 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/KdcRequest.java
@@ -183,15 +183,15 @@ public abstract class KdcRequest {
         PrincipalName cName = getClientPrincipal();
         body.setCname(cName);
 
-        String realm = cName.getRealm();
-        if (realm == null || realm.isEmpty()) {
-            realm = getContext().getKrbSetting().getKdcRealm();
-        }
-        body.setRealm(realm);
-
         PrincipalName sName = getServerPrincipal();
         body.setSname(sName);
 
+        String realm = getContext().getKrbSetting().getKdcRealm();
+        if (sName != null && sName.getRealm() != null) {
+            realm = sName.getRealm();
+        }
+        body.setRealm(realm);
+
         long tillTime = startTime + getTicketValidTime();
         body.setTill(new KerberosTime(tillTime));
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
index 8e650b8..512bd50 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequest.java
@@ -58,11 +58,13 @@ public class TgsRequest extends KdcRequest {
 
     @Override
     public void process() throws KrbException {
-        String serverPrincipal = getRequestOptions().getStringOption(KrbOption.SERVER_PRINCIPAL);
-        if (serverPrincipal == null) {
-            LOG.warn("Server principal is null.");
+        if (getServerPrincipal() == null) {
+            String serverPrincipalString = getRequestOptions().getStringOption(KrbOption.SERVER_PRINCIPAL);
+            if (serverPrincipalString == null) {
+                LOG.warn("Server principal is null.");
+            }
+            setServerPrincipal(new PrincipalName(serverPrincipalString));
         }
-        setServerPrincipal(new PrincipalName(serverPrincipal));
         super.process();
 
         TgsReq tgsReq = new TgsReq();

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithTgt.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithTgt.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithTgt.java
index 5f2e58a..41fb0c1 100644
--- a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithTgt.java
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/request/TgsRequestWithTgt.java
@@ -35,21 +35,32 @@ import org.apache.kerby.kerberos.kerb.type.base.KeyUsage;
 import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
 import org.apache.kerby.kerberos.kerb.type.kdc.KdcReqBody;
 import org.apache.kerby.kerberos.kerb.type.pa.PaDataType;
+import org.apache.kerby.kerberos.kerb.type.ticket.KrbTicket;
+import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
 import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
 
 public class TgsRequestWithTgt extends TgsRequest {
 
-    private TgtTicket tgt;
     private ApReq apReq;
+    private KrbTicket ticket;
+    private PrincipalName clientPrincipal;
 
-     public TgsRequestWithTgt(KrbContext context, TgtTicket tgt) {
+    public TgsRequestWithTgt(KrbContext context, TgtTicket tgt) {
         super(context);
-        this.tgt = tgt;
         setAllowedPreauth(PaDataType.TGS_REQ);
+        ticket = tgt;
+        clientPrincipal = tgt.getClientPrincipal();
+    }
+
+    public TgsRequestWithTgt(KrbContext context, SgtTicket sgt) {
+        super(context);
+        setAllowedPreauth(PaDataType.TGS_REQ);
+        ticket = sgt;
+        clientPrincipal = sgt.getClientPrincipal();
     }
 
     public PrincipalName getClientPrincipal() {
-        return tgt.getClientPrincipal();
+        return clientPrincipal;
     }
 
     @Override
@@ -59,19 +70,19 @@ public class TgsRequestWithTgt extends TgsRequest {
 
     @Override
     public EncryptionKey getSessionKey() {
-        return tgt.getSessionKey();
+        return ticket.getSessionKey();
     }
 
     private ApReq makeApReq() throws KrbException {
         ApReq apReq = new ApReq();
 
         Authenticator authenticator = makeAuthenticator();
-        EncryptionKey sessionKey = tgt.getSessionKey();
+        EncryptionKey sessionKey = ticket.getSessionKey();
         EncryptedData authnData = EncryptionUtil.seal(authenticator,
             sessionKey, KeyUsage.TGS_REQ_AUTH);
         apReq.setEncryptedAuthenticator(authnData);
         apReq.setAuthenticator(authenticator);
-        apReq.setTicket(tgt.getTicket());
+        apReq.setTicket(ticket.getTicket());
         ApOptions apOptions = new ApOptions();
         apReq.setApOptions(apOptions);
 
@@ -88,20 +99,20 @@ public class TgsRequestWithTgt extends TgsRequest {
     private Authenticator makeAuthenticator() throws KrbException {
         Authenticator authenticator = new Authenticator();
         authenticator.setAuthenticatorVno(5);
-        authenticator.setCname(tgt.getClientPrincipal());
-        authenticator.setCrealm(tgt.getRealm());
+        authenticator.setCname(clientPrincipal);
+        authenticator.setCrealm(clientPrincipal.getRealm());
         authenticator.setCtime(KerberosTime.now());
         authenticator.setCusec(0);
-        authenticator.setSubKey(tgt.getSessionKey());
+        authenticator.setSubKey(ticket.getSessionKey());
         KerberosTime renewTill = null;
 
         if (getRequestOptions().contains(KrbKdcOption.RENEW)) {
-            renewTill = tgt.getEncKdcRepPart().getRenewTill();
+            renewTill = ticket.getEncKdcRepPart().getRenewTill();
         }
         KdcReqBody reqBody = getReqBody(renewTill);
 
         CheckSum checksum = CheckSumUtil.seal(reqBody, null,
-            tgt.getSessionKey(), KeyUsage.TGS_REQ_AUTH_CKSUM);
+            ticket.getSessionKey(), KeyUsage.TGS_REQ_AUTH_CKSUM);
         authenticator.setCksum(checksum);
 
         return authenticator;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
index c6e3ae7..c4d9ded 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/KrbUtil.java
@@ -43,6 +43,17 @@ public class KrbUtil {
     }
 
     /**
+     * Construct TGS principal name for cross-realm.
+     * @param sourceRealm The source realm
+     * @param destRealm The dest realm
+     * @return principal
+     */
+    public static PrincipalName makeTgsPrincipal(String sourceRealm, String destRealm) {
+        String nameString = KrbConstant.TGS_PRINCIPAL + "/" + destRealm + "@" + sourceRealm;
+        return new PrincipalName(nameString, NameType.NT_SRV_INST);
+    }
+
+    /**
      * Construct kadmin principal name.
      * @param realm The realm
      * @return principal

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/fdfc559a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
----------------------------------------------------------------------
diff --git a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
index d359f0c..e20fcaf 100644
--- a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
+++ b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitTool.java
@@ -173,13 +173,15 @@ public class KinitTool {
                 try {
                     sgtTicket = krbClient.requestSgt(ccFile, servicePrincipal);
                 } catch (KrbException e) {
-                    System.err.println("kinit: " + e.getKrbErrorCode().getMessage());
+                    System.err.println("Kinit: get service ticket failed: " + e.getMessage());
+                    System.exit(1);
                 }
 
                 try {
                     krbClient.storeTicket(sgtTicket, ccFile);
                 } catch (KrbException e) {
-                    System.err.println("kinit: " + e.getKrbErrorCode().getMessage());
+                    System.err.println("Kinit: store ticket failed: " + e.getMessage());
+                    System.exit(1);
                 }
 
                 System.out.println(sgtTicket.getEncKdcRepPart().getSname().getName() + ": knvo = "