jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
changeset 2 90ce3da70b43
child 4336 4c792c19266e
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Portions Copyright 2001-2004 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     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
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 /*
       
    27  *
       
    28  *  (C) Copyright IBM Corp. 1999 All Rights Reserved.
       
    29  *  Copyright 1997 The Open Group Research Institute.  All rights reserved.
       
    30  */
       
    31 
       
    32 package sun.security.krb5.internal;
       
    33 
       
    34 import sun.security.krb5.*;
       
    35 import sun.security.krb5.internal.ccache.CredentialsCache;
       
    36 import java.util.StringTokenizer;
       
    37 import sun.security.krb5.internal.ktab.*;
       
    38 import java.io.File;
       
    39 import java.io.IOException;
       
    40 import java.util.Date;
       
    41 import java.util.Vector;
       
    42 import java.io.BufferedReader;
       
    43 import java.io.InputStreamReader;
       
    44 import java.io.UnsupportedEncodingException;
       
    45 import java.net.InetAddress;
       
    46 
       
    47 /**
       
    48  * This class is a utility that contains much of the TGS-Exchange
       
    49  * protocol. It is used by ../Credentials.java for service ticket
       
    50  * acquisition in both the normal and the x-realm case.
       
    51  */
       
    52 public class CredentialsUtil {
       
    53 
       
    54     private static boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
       
    55 
       
    56    /**
       
    57     * Acquires credentials for a specified service using initial credential. Wh
       
    58 en the service has a different realm
       
    59     * from the initial credential, we do cross-realm authentication - first, we
       
    60  use the current credential to get
       
    61     * a cross-realm credential from the local KDC, then use that cross-realm cr
       
    62 edential to request service credential
       
    63     * from the foreigh KDC.
       
    64     *
       
    65     * @param service the name of service principal using format components@real
       
    66 m
       
    67     * @param ccreds client's initial credential.
       
    68     * @exception Exception general exception will be thrown when any error occu
       
    69 rs.
       
    70     * @return a <code>Credentials</code> object.
       
    71     */
       
    72     public static Credentials acquireServiceCreds(
       
    73                 String service, Credentials ccreds)
       
    74     throws KrbException, IOException {
       
    75         ServiceName sname = new ServiceName(service);
       
    76         String serviceRealm = sname.getRealmString();
       
    77         String localRealm = ccreds.getClient().getRealmString();
       
    78         String defaultRealm = Config.getInstance().getDefaultRealm();
       
    79 
       
    80         if (localRealm == null) {
       
    81             PrincipalName temp = null;
       
    82             if ((temp = ccreds.getServer()) != null)
       
    83                 localRealm = temp.getRealmString();
       
    84         }
       
    85         if (localRealm == null) {
       
    86             localRealm = defaultRealm;
       
    87         }
       
    88         if (serviceRealm == null) {
       
    89             serviceRealm = localRealm;
       
    90             sname.setRealm(serviceRealm);
       
    91         }
       
    92 
       
    93         /*
       
    94           if (!localRealm.equalsIgnoreCase(serviceRealm)) { //do cross-realm auth entication
       
    95           if (DEBUG) {
       
    96           System.out.println(">>>DEBUG: Credentails request cross realm ticket for " + "krbtgt/" + serviceRealm + "@" + localRealm);
       
    97           }
       
    98           Credentials crossCreds = serviceCreds(new ServiceName("krbtgt/" + serviceRealm + "@" + localRealm), ccreds);
       
    99           if (DEBUG) {
       
   100           printDebug(crossCreds);
       
   101           }
       
   102           Credentials result = serviceCreds(sname, crossCreds);
       
   103           if (DEBUG) {
       
   104           printDebug(result);
       
   105           }
       
   106           return result;
       
   107           }
       
   108           else return serviceCreds(sname, ccreds);
       
   109         */
       
   110 
       
   111         if (localRealm.equals(serviceRealm))
       
   112         {
       
   113             if (DEBUG)
       
   114                 System.out.println(">>> Credentials acquireServiceCreds: same realm");
       
   115             return serviceCreds(sname, ccreds);
       
   116         }
       
   117 
       
   118         // Get a list of realms to traverse
       
   119         String[] realms = Realm.getRealmsList(localRealm, serviceRealm);
       
   120 
       
   121         if (realms == null || realms.length == 0)
       
   122         {
       
   123             if (DEBUG)
       
   124                 System.out.println(">>> Credentials acquireServiceCreds: no realms list");
       
   125             return null;
       
   126         }
       
   127 
       
   128         int i = 0, k = 0;
       
   129         Credentials cTgt = null, newTgt = null, theTgt = null;
       
   130         ServiceName tempService = null;
       
   131         String realm = null, newTgtRealm = null, theTgtRealm = null;
       
   132 
       
   133         for (cTgt = ccreds, i = 0; i < realms.length;)
       
   134         {
       
   135             tempService = new ServiceName(PrincipalName.TGS_DEFAULT_SRV_NAME,
       
   136                                           serviceRealm, realms[i]);
       
   137 
       
   138             if (DEBUG)
       
   139             {
       
   140                 System.out.println(">>> Credentials acquireServiceCreds: main loop: [" + i +"] tempService=" + tempService);
       
   141             }
       
   142 
       
   143             try {
       
   144                 newTgt = serviceCreds(tempService, cTgt);
       
   145             } catch (Exception exc) {
       
   146                 newTgt = null;
       
   147             }
       
   148 
       
   149             if (newTgt == null)
       
   150             {
       
   151                 if (DEBUG)
       
   152                 {
       
   153                     System.out.println(">>> Credentials acquireServiceCreds: no tgt; searching backwards");
       
   154                 }
       
   155 
       
   156                 /*
       
   157                  * No tgt found. Try to get one for a
       
   158                  * realm as close to the target as possible.
       
   159                  * That means traversing the realms list backwards.
       
   160                  */
       
   161 
       
   162                 for (newTgt = null, k = realms.length - 1;
       
   163                      newTgt == null && k > i; k--)
       
   164                 {
       
   165 
       
   166                     tempService = new ServiceName(
       
   167                                        PrincipalName.TGS_DEFAULT_SRV_NAME,
       
   168                                        realms[k], realms[i]);
       
   169                     if (DEBUG)
       
   170                     {
       
   171                         System.out.println(">>> Credentials acquireServiceCreds: inner loop: [" + k +"] tempService=" + tempService);
       
   172                     }
       
   173 
       
   174                     try {
       
   175                         newTgt = serviceCreds(tempService, cTgt);
       
   176                     } catch (Exception exc) {
       
   177                         newTgt = null;
       
   178                     }
       
   179                 }
       
   180             } // Ends 'if (newTgt == null)'
       
   181 
       
   182             if (newTgt == null)
       
   183             {
       
   184                 if (DEBUG)
       
   185                 {
       
   186                     System.out.println(">>> Credentials acquireServiceCreds: no tgt; cannot get creds");
       
   187                 }
       
   188                 break;
       
   189             }
       
   190 
       
   191             /*
       
   192              * We have a tgt. It may or may not be for the target.
       
   193              * If it's for the target realm, we're done looking for a tgt.
       
   194              */
       
   195 
       
   196             newTgtRealm = newTgt.getServer().getInstanceComponent();
       
   197 
       
   198             if (DEBUG)
       
   199             {
       
   200                 System.out.println(">>> Credentials acquireServiceCreds: got tgt");
       
   201                 //printDebug(newTgt);
       
   202             }
       
   203 
       
   204             if (newTgtRealm.equals(serviceRealm))
       
   205             {
       
   206                 /* We got the right tgt */
       
   207                 theTgt = newTgt;
       
   208                 theTgtRealm = newTgtRealm;
       
   209                 break;
       
   210             }
       
   211 
       
   212             /*
       
   213              * The new tgt is not for the target realm.
       
   214              * See if the realm of the new tgt is in the list of realms
       
   215              * and continue looking from there.
       
   216              */
       
   217 
       
   218             for (k = i+1; k < realms.length; k++)
       
   219             {
       
   220                 if (newTgtRealm.equals(realms[k]))
       
   221                 {
       
   222                     break;
       
   223                 }
       
   224             }
       
   225 
       
   226             if (k < realms.length)
       
   227             {
       
   228                 /*
       
   229                  * (re)set the counter so we start looking
       
   230                  * from the realm we just obtained a tgt for.
       
   231                  */
       
   232                 i = k;
       
   233                 cTgt = newTgt;
       
   234 
       
   235                 if (DEBUG)
       
   236                 {
       
   237                     System.out.println(">>> Credentials acquireServiceCreds: continuing with main loop counter reset to " + i);
       
   238                 }
       
   239 
       
   240                 continue;
       
   241             }
       
   242             else
       
   243             {
       
   244                 /*
       
   245                  * The new tgt's realm is not in the heirarchy of realms.
       
   246                  * It's probably not safe to get a tgt from
       
   247                  * a tgs that is outside the known list of realms.
       
   248                  * Give up now.
       
   249                  */
       
   250 
       
   251                 break;
       
   252             }
       
   253         } // Ends outermost/main 'for' loop
       
   254 
       
   255         Credentials theCreds = null;
       
   256 
       
   257         if (theTgt != null)
       
   258         {
       
   259             /* We have the right tgt. Let's get the service creds */
       
   260 
       
   261             if (DEBUG)
       
   262             {
       
   263                 System.out.println(">>> Credentials acquireServiceCreds: got right tgt");
       
   264 
       
   265                 //printDebug(theTgt);
       
   266 
       
   267                 System.out.println(">>> Credentials acquireServiceCreds: obtaining service creds for " + sname);
       
   268             }
       
   269 
       
   270             try {
       
   271                 theCreds = serviceCreds(sname, theTgt);
       
   272             } catch (Exception exc) {
       
   273               if (DEBUG)
       
   274                 System.out.println(exc);
       
   275               theCreds = null;
       
   276             }
       
   277         }
       
   278 
       
   279         if (theCreds != null)
       
   280         {
       
   281             if (DEBUG)
       
   282             {
       
   283                 System.out.println(">>> Credentials acquireServiceCreds: returning creds:");
       
   284                 Credentials.printDebug(theCreds);
       
   285             }
       
   286             return theCreds;
       
   287         }
       
   288         throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
       
   289                                     "No service creds");
       
   290     }
       
   291 
       
   292    /*
       
   293     * This method does the real job to request the service credential.
       
   294     */
       
   295     private static Credentials serviceCreds(
       
   296             ServiceName service, Credentials ccreds)
       
   297             throws KrbException, IOException {
       
   298         return new KrbTgsReq(ccreds, service).sendAndGetCreds();
       
   299     }
       
   300 }