harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From smish...@apache.org
Subject svn commit: r471985 - in /incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth: internal/kerberos/v5/ module/
Date Tue, 07 Nov 2006 05:06:57 GMT
Author: smishura
Date: Mon Nov  6 21:06:56 2006
New Revision: 471985

URL: http://svn.apache.org/viewvc?view=rev&rev=471985
Log:
Improve functionality: complete set of ASN.1 decoders for AS exchange protocol - now Krb5LoginModule
can obtain tickets

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KDCReply.java
    incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KrbClient.java
    incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/Ticket.java
    incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/module/Krb5LoginModule.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KDCReply.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KDCReply.java?view=diff&rev=471985&r1=471984&r2=471985
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KDCReply.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KDCReply.java
Mon Nov  6 21:06:56 2006
@@ -17,17 +17,25 @@
 
 package org.apache.harmony.auth.internal.kerberos.v5;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.util.Date;
+
+import javax.crypto.SecretKey;
 
 import org.apache.harmony.security.asn1.ASN1Any;
+import org.apache.harmony.security.asn1.ASN1BitString;
 import org.apache.harmony.security.asn1.ASN1Constants;
 import org.apache.harmony.security.asn1.ASN1Explicit;
 import org.apache.harmony.security.asn1.ASN1Integer;
+import org.apache.harmony.security.asn1.ASN1OctetString;
 import org.apache.harmony.security.asn1.ASN1Sequence;
 import org.apache.harmony.security.asn1.ASN1SequenceOf;
 import org.apache.harmony.security.asn1.ASN1StringType;
 import org.apache.harmony.security.asn1.ASN1Type;
 import org.apache.harmony.security.asn1.BerInputStream;
+import org.apache.harmony.security.asn1.BitString;
+import org.apache.harmony.security.asn1.DerInputStream;
 
 /**
  * @see http://www.ietf.org/rfc/rfc4120.txt
@@ -55,8 +63,28 @@
 
     private final EncryptedData encPart;
 
-    private KDCReply(int msgType, String crealm, PrincipalName cname, Ticket ticket,
-            EncryptedData encPart) {
+    //
+    //
+    //
+    private Date authtime;
+
+    private Date starttime;
+
+    private Date endtime;
+
+    private Date renewtill;
+
+    private String srealm;
+
+    private PrincipalName sname;
+
+    // session key
+    private Object[] key;
+
+    private BitString flags;
+
+    private KDCReply(int msgType, String crealm, PrincipalName cname,
+            Ticket ticket, EncryptedData encPart) {
         this.msgType = msgType;
         this.cname = cname;
         this.crealm = crealm;
@@ -64,6 +92,22 @@
         this.encPart = encPart;
     }
 
+    public void decrypt(SecretKey key) throws IOException {
+        DerInputStream in = new DerInputStream(new ByteArrayInputStream(encPart
+                .decrypt(key)));
+
+        Object[] values = (Object[]) ENC_AS_REP_PART.decode(in);
+
+        this.key = (Object[]) values[0];
+        flags = (BitString) values[4];
+        authtime = (Date) values[5];
+        starttime = (Date) values[6];
+        endtime = (Date) values[7];
+        renewtill = (Date) values[8];
+        srealm = (String) values[9];
+        sname = (PrincipalName) values[10];
+    }
+
     public int getMsgtype() {
         return msgType;
     }
@@ -84,6 +128,42 @@
         return encPart;
     }
 
+    //
+    //
+    //
+
+    public Date getAuthtime() {
+        return authtime;
+    }
+
+    public Date getStarttime() {
+        return starttime;
+    }
+
+    public Date getEndtime() {
+        return endtime;
+    }
+
+    public Date getRenewtill() {
+        return renewtill;
+    }
+
+    public String getSrealm() {
+        return srealm;
+    }
+
+    public PrincipalName getSname() {
+        return sname;
+    }
+
+    public Object[] getKey() {
+        return key;
+    }
+
+    public BitString getFlags() {
+        return flags;
+    }
+
     /**
      * <pre>
      *  KDC-REP         ::= SEQUENCE {
@@ -119,8 +199,9 @@
 
             Object[] values = (Object[]) in.content;
 
-            return new KDCReply(ASN1Integer.toIntValue(values[1]), (String) values[3],
-                    (PrincipalName) values[4], (Ticket) values[5], (EncryptedData) values[6]);
+            return new KDCReply(ASN1Integer.toIntValue(values[1]),
+                    (String) values[3], (PrincipalName) values[4],
+                    (Ticket) values[5], (EncryptedData) values[6]);
         }
 
         @Override
@@ -131,4 +212,55 @@
 
     public static final ASN1Explicit AS_REP_ASN1 = new ASN1Explicit(
             ASN1Constants.CLASS_APPLICATION, AS_REP, KDC_REP_ASN1);
+
+    private static final ASN1Sequence ENCRYPTION_KEY = new ASN1Sequence(
+            new ASN1Type[] {
+            // TODO should we define Int32 type?
+                    new ASN1Explicit(0, ASN1Integer.getInstance()), // keytype
+                    new ASN1Explicit(1, ASN1OctetString.getInstance()), // keyvalue
+            });
+
+    private static final ASN1SequenceOf LAST_REQ = new ASN1SequenceOf(
+            new ASN1Sequence(new ASN1Type[] {
+            // TODO should we define Int32 type?
+                    new ASN1Explicit(0, ASN1Integer.getInstance()), // lr-type
+                    new ASN1Explicit(1, KerberosTime.getASN1()), // lr-value
+            }));
+
+    private static final ASN1Sequence HOST_ADDRESS = new ASN1Sequence(
+            new ASN1Type[] {
+            // TODO should we define Int32 type?
+                    new ASN1Explicit(0, ASN1Integer.getInstance()), // addr-type
+                    new ASN1Explicit(1, ASN1OctetString.getInstance()), // address
+            });
+
+    private static final ASN1Sequence ENC_KDC_REP_PART = new ASN1Sequence(
+            new ASN1Type[] { new ASN1Explicit(0, ENCRYPTION_KEY), // key
+                    new ASN1Explicit(1, LAST_REQ), // last-req
+                    // TODO should we define UInt32 type?
+                    new ASN1Explicit(2, ASN1Integer.getInstance()), // nonce
+                    new ASN1Explicit(3, KerberosTime.getASN1()), // key-expiration
+                    // TODO TicketFlags type?
+                    new ASN1Explicit(4, ASN1BitString.getInstance()), // flags
+                    new ASN1Explicit(5, KerberosTime.getASN1()), // authtime
+                    new ASN1Explicit(6, KerberosTime.getASN1()), // starttime
+                    new ASN1Explicit(7, KerberosTime.getASN1()), // endtime
+                    new ASN1Explicit(8, KerberosTime.getASN1()), // renew-till
+                    // TODO should we define Realm type?
+                    new ASN1Explicit(9, ASN1StringType.GENERALSTRING), // srealm
+                    new ASN1Explicit(10, PrincipalName.ASN1), // sname
+                    new ASN1Explicit(11, HOST_ADDRESS), // caddr
+            }) {
+        {
+            setOptional(3); // key-expiration
+            setOptional(6); // starttime
+            setOptional(8); // renew-till
+            setOptional(11); // caddr
+        }
+    };
+
+    //TODO: create const ENC_AS_REP_PART=25
+    private static final ASN1Explicit ENC_AS_REP_PART = new ASN1Explicit(
+            ASN1Constants.CLASS_APPLICATION, 25, ENC_KDC_REP_PART);
+
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KrbClient.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KrbClient.java?view=diff&rev=471985&r1=471984&r2=471985
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KrbClient.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/KrbClient.java
Mon Nov  6 21:06:56 2006
@@ -23,6 +23,8 @@
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 
+import javax.crypto.SecretKey;
+
 import org.apache.harmony.auth.internal.nls.Messages;
 import org.apache.harmony.security.asn1.DerInputStream;
 
@@ -46,10 +48,12 @@
      * @param realm - client's realm
      * @return - ticket
      */
-    public static Ticket doAS(InetAddress address, int port, PrincipalName cname, String
realm,
-            PrincipalName sname) {
+    public static KDCReply doAS(InetAddress address, int port,
+            PrincipalName cname, String realm, PrincipalName sname,
+            SecretKey key) {
 
-        KDCRequest request = new KDCRequest(KDCRequest.AS_REQ, cname, realm, sname);
+        KDCRequest request = new KDCRequest(KDCRequest.AS_REQ, cname, realm,
+                sname);
 
         try {
             DatagramSocket socket = request.send(address, port);
@@ -70,11 +74,16 @@
             DerInputStream in = new DerInputStream(out.toByteArray());
 
             if (in.tag == KDCReply.AS_REP_ASN1.constrId) { //TODO AS reply
-                throw new RuntimeException();//FIXME
+                KDCReply reply = (KDCReply) KDCReply.AS_REP_ASN1.decode(in);
+
+                reply.decrypt(key);
+
+                return reply;
             } else if (in.tag == KerberosErrorMessage.ASN1.constrId) {
                 KerberosErrorMessage errMsg = KerberosErrorMessage.decode(in);
                 // auth.52=Error code: {0}
-                throw new RuntimeException(Messages.getString("auth.52", errMsg.getErrorCode()));
//$NON-NLS-1$
+                throw new RuntimeException(Messages.getString(
+                        "auth.52", errMsg.getErrorCode())); //$NON-NLS-1$
             } else {
                 new RuntimeException(); //FIXME
             }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/Ticket.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/Ticket.java?view=diff&rev=471985&r1=471984&r2=471985
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/Ticket.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/internal/kerberos/v5/Ticket.java
Mon Nov  6 21:06:56 2006
@@ -37,6 +37,9 @@
 
     private final String realm;
 
+    // ASN.1 encoding of this ticket
+    private byte[] encoded;
+    
     private Ticket(String realm, PrincipalName sname) {
         this.sname = sname;
         this.realm = realm;
@@ -50,6 +53,10 @@
         return sname;
     }
 
+    public byte[] getEncoded() {
+        return encoded;
+    }
+
     /**
      <pre>Ticket          ::= [APPLICATION 1] SEQUENCE {
      tkt-vno         [0] INTEGER (5),
@@ -72,7 +79,11 @@
 
             Object[] values = (Object[]) in.content;
 
-            return new Ticket((String) values[1], (PrincipalName) values[2]);
+            Ticket ticket = new Ticket((String) values[1],
+                    (PrincipalName) values[2]);
+            ticket.encoded = in.getEncoded();
+
+            return ticket;
         }
 
         @Override

Modified: incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/module/Krb5LoginModule.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/module/Krb5LoginModule.java?view=diff&rev=471985&r1=471984&r2=471985
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/module/Krb5LoginModule.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/auth/src/main/java/common/org/apache/harmony/auth/module/Krb5LoginModule.java
Mon Nov  6 21:06:56 2006
@@ -21,13 +21,18 @@
 import java.util.Map;
 
 import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
+import org.apache.harmony.auth.internal.kerberos.v5.KDCReply;
 import org.apache.harmony.auth.internal.kerberos.v5.KrbClient;
 import org.apache.harmony.auth.internal.kerberos.v5.PrincipalName;
-import org.apache.harmony.auth.internal.kerberos.v5.Ticket;
 
 public class Krb5LoginModule implements LoginModule {
 
@@ -40,8 +45,12 @@
     // client's principal identifier name
     private static final String PRINCIPAL = "principal";//$NON-NLS-1$
 
+    private Subject subject;
+
     private Map<String, ?> options;
 
+    private CallbackHandler callbackHandler;
+
     public boolean abort() throws LoginException {
         // TODO
         return false;
@@ -55,7 +64,9 @@
     public void initialize(Subject subject, CallbackHandler callbackHandler,
             Map<String, ?> sharedState, Map<String, ?> options) {
         // TODO
+        this.subject = subject;
         this.options = options;
+        this.callbackHandler = callbackHandler;
     }
 
     public boolean login() throws LoginException {
@@ -83,14 +94,69 @@
             kdc = kdc.substring(0, pos);
         }
 
-        PrincipalName cname = new PrincipalName(PrincipalName.NT_UNKNOWN, new String[] {
name });
+        PrincipalName cname = new PrincipalName(PrincipalName.NT_UNKNOWN,
+                new String[] { name });
 
-        PrincipalName krbtgt = new PrincipalName(PrincipalName.NT_SRV_XHST, new String[]
{
-                "krbtgt", realm }); //$NON-NLS-1$
+        PrincipalName krbtgt = new PrincipalName(PrincipalName.NT_SRV_XHST,
+                new String[] { "krbtgt", realm }); //$NON-NLS-1$
 
         try {
-            Ticket ticket = KrbClient.doAS(InetAddress.getByName(kdc), port, cname, realm,
-                    krbtgt);
+            // get client's password
+            PasswordCallback callback = new PasswordCallback("Password for "
+                    + name, false);
+            callbackHandler.handle(new Callback[] { callback });
+
+            KerberosKey key = new KerberosKey(new KerberosPrincipal(name + '@'
+                    + realm, KerberosPrincipal.KRB_NT_UNKNOWN), callback
+                    .getPassword(), "DES");
+
+            KDCReply reply = KrbClient.doAS(InetAddress.getByName(kdc), port,
+                    cname, realm, krbtgt, key);
+
+            // add principal to subject
+            String[] pName = reply.getCname().getName();
+            StringBuilder buf = new StringBuilder();
+            for (int i = 0; i < pName.length - 1; i++) {
+                buf.append(pName[i]);
+                buf.append('/');
+            }
+            buf.append(pName[pName.length - 1]);
+            buf.append('@');
+            buf.append(reply.getCrealm());
+
+            KerberosPrincipal client = new KerberosPrincipal(buf.toString(),
+                    reply.getCname().getType());
+            subject.getPrincipals().add(client);
+
+            // add ticket to private credentials
+            byte[] ticket = reply.getTicket().getEncoded();
+
+            String[] sName = reply.getSname().getName();
+            buf = new StringBuilder();
+            for (int i = 0; i < sName.length - 1; i++) {
+                buf.append(sName[i]);
+                buf.append('/');
+            }
+            buf.append(sName[sName.length - 1]);
+            buf.append('@');
+            buf.append(reply.getSrealm());
+
+            KerberosPrincipal server = new KerberosPrincipal(buf.toString(),
+                    reply.getSname().getType());
+
+            int keyType = (int) ((byte[]) reply.getKey()[0])[0];
+            byte[] sessionKey = (byte[]) reply.getKey()[1];
+
+            boolean[] flags = reply.getFlags().toBooleanArray();
+
+            KerberosTicket krbTicket = new KerberosTicket(ticket, client,
+                    server, sessionKey, keyType, flags, reply.getAuthtime(),
+                    reply.getStarttime(), reply.getEndtime(), reply
+                            .getRenewtill(),
+                    //TODO InetAddress[] clientAddresses
+                    null);
+
+            subject.getPrivateCredentials().add(krbTicket);
 
             return true; //FIXME 
         } catch (Exception e) {



Mime
View raw message