jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
changeset 9499 f3115698a012
parent 7183 d8ccc1c73358
child 10336 0bb1999251f8
equal deleted inserted replaced
9498:c59964385a5f 9499:f3115698a012
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
   393 
   393 
   394     // the authentication status
   394     // the authentication status
   395     private boolean succeeded = false;
   395     private boolean succeeded = false;
   396     private boolean commitSucceeded = false;
   396     private boolean commitSucceeded = false;
   397     private String username;
   397     private String username;
       
   398 
       
   399     // Encryption keys calculated from password. Assigned when storekey == true
       
   400     // and useKeyTab == false (or true but not found)
   398     private EncryptionKey[] encKeys = null;
   401     private EncryptionKey[] encKeys = null;
       
   402 
       
   403     KeyTab ktab = null;
       
   404 
   399     private Credentials cred = null;
   405     private Credentials cred = null;
   400 
   406 
   401     private PrincipalName principal = null;
   407     private PrincipalName principal = null;
   402     private KerberosPrincipal kerbClientPrinc = null;
   408     private KerberosPrincipal kerbClientPrinc = null;
   403     private KerberosTicket kerbTicket = null;
   409     private KerberosTicket kerbTicket = null;
   661                     promptForName(getPasswdFromSharedState);
   667                     promptForName(getPasswdFromSharedState);
   662                     principal = new PrincipalName
   668                     principal = new PrincipalName
   663                         (krb5PrincName.toString(),
   669                         (krb5PrincName.toString(),
   664                          PrincipalName.KRB_NT_PRINCIPAL);
   670                          PrincipalName.KRB_NT_PRINCIPAL);
   665                 }
   671                 }
       
   672 
       
   673                 /*
       
   674                  * Before dynamic KeyTab support (6894072), here we check if
       
   675                  * the keytab contains keys for the principal. If no, keytab
       
   676                  * will not be used and password is prompted for.
       
   677                  *
       
   678                  * After 6894072, we normally don't check it, and expect the
       
   679                  * keys can be populated until a real connection is made. The
       
   680                  * check is still done when isInitiator == true, where the keys
       
   681                  * will be used right now.
       
   682                  *
       
   683                  * Probably tricky relations:
       
   684                  *
       
   685                  * useKeyTab is config flag, but when it's true but the ktab
       
   686                  * does not contains keys for principal, we would use password
       
   687                  * and keep the flag unchanged (for reuse?). In this method,
       
   688                  * we use (ktab != null) to check whether keytab is used.
       
   689                  * After this method (and when storeKey == true), we use
       
   690                  * (encKeys == null) to check.
       
   691                  */
   666                 if (useKeyTab) {
   692                 if (useKeyTab) {
   667                     encKeys =
   693                     ktab = (keyTabName == null)
   668                         EncryptionKey.acquireSecretKeys(principal, keyTabName);
   694                                 ? KeyTab.getInstance()
   669 
   695                                 : KeyTab.getInstance(new File(keyTabName));
   670                     if (debug) {
   696                     if (isInitiator) {
   671                         if (encKeys != null)
   697                         if (Krb5Util.keysFromJavaxKeyTab(ktab, principal).length
   672                             System.out.println
   698                                 == 0) {
   673                                 ("principal's key obtained from the keytab");
   699                             ktab = null;
   674                         else
   700                             if (debug) {
   675                             System.out.println
   701                                 System.out.println
   676                                 ("Key for the principal " +
   702                                     ("Key for the principal " +
   677                                  principal  +
   703                                      principal  +
   678                                  " not available in " +
   704                                      " not available in " +
   679                                  ((keyTabName == null) ?
   705                                      ((keyTabName == null) ?
   680                                   "default key tab" : keyTabName));
   706                                       "default key tab" : keyTabName));
       
   707                             }
       
   708                         }
   681                     }
   709                     }
   682 
       
   683                 }
   710                 }
   684 
   711 
   685                 KrbAsReqBuilder builder;
   712                 KrbAsReqBuilder builder;
   686                 // We can't get the key from the keytab so prompt
   713 
   687                 if (encKeys == null) {
   714                 if (ktab == null) {
   688                     promptForPass(getPasswdFromSharedState);
   715                     promptForPass(getPasswdFromSharedState);
   689                     builder = new KrbAsReqBuilder(principal, password);
   716                     builder = new KrbAsReqBuilder(principal, password);
   690                     if (isInitiator) {
   717                     if (isInitiator) {
   691                         // XXX Even if isInitiator=false, it might be
   718                         // XXX Even if isInitiator=false, it might be
   692                         // better to do an AS-REQ so that keys can be
   719                         // better to do an AS-REQ so that keys can be
   693                         // updated with PA info
   720                         // updated with PA info
   694                         cred = builder.action().getCreds();
   721                         cred = builder.action().getCreds();
   695                     }
   722                     }
   696                     encKeys = builder.getKeys();
   723                     if (storeKey) {
       
   724                         encKeys = builder.getKeys();
       
   725                         // When encKeys is empty, the login actually fails.
       
   726                         // For compatibility, exception is thrown in commit().
       
   727                     }
   697                 } else {
   728                 } else {
   698                     builder = new KrbAsReqBuilder(principal, encKeys);
   729                     builder = new KrbAsReqBuilder(principal, ktab);
   699                     if (isInitiator) {
   730                     if (isInitiator) {
   700                         cred = builder.action().getCreds();
   731                         cred = builder.action().getCreds();
   701                     }
   732                     }
   702                 }
   733                 }
   703                 builder.destroy();
   734                 builder.destroy();
   704 
   735 
   705                 if (debug) {
   736                 if (debug) {
   706                     System.out.println("principal is " + principal);
   737                     System.out.println("principal is " + principal);
   707                     HexDumpEncoder hd = new HexDumpEncoder();
   738                     HexDumpEncoder hd = new HexDumpEncoder();
   708                     for (int i = 0; i < encKeys.length; i++) {
   739                     if (ktab != null) {
   709                         System.out.println("EncryptionKey: keyType=" +
   740                         System.out.println("Will use keytab");
   710                             encKeys[i].getEType() + " keyBytes (hex dump)=" +
   741                     } else if (storeKey) {
   711                             hd.encodeBuffer(encKeys[i].getBytes()));
   742                         for (int i = 0; i < encKeys.length; i++) {
       
   743                             System.out.println("EncryptionKey: keyType=" +
       
   744                                 encKeys[i].getEType() +
       
   745                                 " keyBytes (hex dump)=" +
       
   746                                 hd.encodeBuffer(encKeys[i].getBytes()));
       
   747                         }
   712                     }
   748                     }
   713                 }
   749                 }
   714 
   750 
   715                 // we should hava a non-null cred
   751                 // we should hava a non-null cred
   716                 if (isInitiator && (cred == null)) {
   752                 if (isInitiator && (cred == null)) {
   987             // create Kerberos Ticket
  1023             // create Kerberos Ticket
   988             if (isInitiator) {
  1024             if (isInitiator) {
   989                 kerbTicket = Krb5Util.credsToTicket(cred);
  1025                 kerbTicket = Krb5Util.credsToTicket(cred);
   990             }
  1026             }
   991 
  1027 
   992             if (storeKey) {
  1028             if (storeKey && encKeys != null) {
   993                 if (encKeys == null || encKeys.length <= 0) {
  1029                 if (encKeys.length == 0) {
   994                     succeeded = false;
  1030                     succeeded = false;
   995                     throw new LoginException("Null Server Key ");
  1031                     throw new LoginException("Null Server Key ");
   996                 }
  1032                 }
   997 
  1033 
   998                 kerbKeys = new KerberosKey[encKeys.length];
  1034                 kerbKeys = new KerberosKey[encKeys.length];
  1004                                           (temp == null?
  1040                                           (temp == null?
  1005                                           0: temp.intValue()));
  1041                                           0: temp.intValue()));
  1006                 }
  1042                 }
  1007 
  1043 
  1008             }
  1044             }
  1009             // Let us add the kerbClientPrinc,kerbTicket and kerbKey (if
  1045             // Let us add the kerbClientPrinc,kerbTicket and KeyTab/KerbKey (if
  1010             // storeKey is true)
  1046             // storeKey is true)
  1011             if (!princSet.contains(kerbClientPrinc))
  1047             if (!princSet.contains(kerbClientPrinc)) {
  1012                 princSet.add(kerbClientPrinc);
  1048                 princSet.add(kerbClientPrinc);
       
  1049             }
  1013 
  1050 
  1014             // add the TGT
  1051             // add the TGT
  1015             if (kerbTicket != null) {
  1052             if (kerbTicket != null) {
  1016                 if (!privCredSet.contains(kerbTicket))
  1053                 if (!privCredSet.contains(kerbTicket))
  1017                     privCredSet.add(kerbTicket);
  1054                     privCredSet.add(kerbTicket);
  1018             }
  1055             }
  1019 
  1056 
  1020             if (storeKey) {
  1057             if (storeKey) {
  1021                 for (int i = 0; i < kerbKeys.length; i++) {
  1058                 if (encKeys == null) {
  1022                     if (!privCredSet.contains(kerbKeys[i])) {
  1059                     if (!privCredSet.contains(ktab)) {
  1023                         privCredSet.add(kerbKeys[i]);
  1060                         privCredSet.add(ktab);
       
  1061                         // Compatibility; also add keys to privCredSet
       
  1062                         for (KerberosKey key: ktab.getKeys(kerbClientPrinc)) {
       
  1063                             privCredSet.add(new Krb5Util.KeysFromKeyTab(key));
       
  1064                         }
  1024                     }
  1065                     }
  1025                     encKeys[i].destroy();
  1066                 } else {
  1026                     encKeys[i] = null;
  1067                     for (int i = 0; i < kerbKeys.length; i ++) {
  1027                     if (debug) {
  1068                         if (!privCredSet.contains(kerbKeys[i])) {
  1028                         System.out.println("Added server's key"
  1069                             privCredSet.add(kerbKeys[i]);
  1029                                         + kerbKeys[i]);
  1070                         }
  1030                         System.out.println("\t\t[Krb5LoginModule] " +
  1071                         encKeys[i].destroy();
  1031                                        "added Krb5Principal  " +
  1072                         encKeys[i] = null;
  1032                                        kerbClientPrinc.toString()
  1073                         if (debug) {
  1033                                        + " to Subject");
  1074                             System.out.println("Added server's key"
       
  1075                                             + kerbKeys[i]);
       
  1076                             System.out.println("\t\t[Krb5LoginModule] " +
       
  1077                                            "added Krb5Principal  " +
       
  1078                                            kerbClientPrinc.toString()
       
  1079                                            + " to Subject");
       
  1080                         }
  1034                     }
  1081                     }
  1035                 }
  1082                 }
  1036             }
  1083             }
  1037         }
  1084         }
  1038         commitSucceeded = true;
  1085         commitSucceeded = true;
  1104            // Let us remove all Kerberos credentials stored in the Subject
  1151            // Let us remove all Kerberos credentials stored in the Subject
  1105         Iterator<Object> it = subject.getPrivateCredentials().iterator();
  1152         Iterator<Object> it = subject.getPrivateCredentials().iterator();
  1106         while (it.hasNext()) {
  1153         while (it.hasNext()) {
  1107             Object o = it.next();
  1154             Object o = it.next();
  1108             if (o instanceof KerberosTicket ||
  1155             if (o instanceof KerberosTicket ||
  1109                 o instanceof KerberosKey) {
  1156                     o instanceof KerberosKey ||
       
  1157                     o instanceof KeyTab) {
  1110                 it.remove();
  1158                 it.remove();
  1111             }
  1159             }
  1112         }
  1160         }
  1113         // clean the kerberos ticket and keys
  1161         // clean the kerberos ticket and keys
  1114         cleanKerberosCred();
  1162         cleanKerberosCred();
  1159                 sharedState.put(PWD, password);
  1207                 sharedState.put(PWD, password);
  1160             }
  1208             }
  1161         } else {
  1209         } else {
  1162             // remove temp results for the next try
  1210             // remove temp results for the next try
  1163             encKeys = null;
  1211             encKeys = null;
       
  1212             ktab = null;
  1164             principal = null;
  1213             principal = null;
  1165         }
  1214         }
  1166         username = null;
  1215         username = null;
  1167         password = null;
  1216         password = null;
  1168         if (krb5PrincName != null && krb5PrincName.length() != 0)
  1217         if (krb5PrincName != null && krb5PrincName.length() != 0)