jdk/src/share/classes/sun/security/krb5/KdcComm.java
changeset 18549 66e6e111be22
parent 16504 1e8ff2df7152
child 20818 da638a97c27a
equal deleted inserted replaced
18548:0b6ca9785d8c 18549:66e6e111be22
    44 import java.security.PrivilegedActionException;
    44 import java.security.PrivilegedActionException;
    45 import java.util.ArrayList;
    45 import java.util.ArrayList;
    46 import java.util.List;
    46 import java.util.List;
    47 import java.util.Set;
    47 import java.util.Set;
    48 import java.util.HashSet;
    48 import java.util.HashSet;
       
    49 import java.util.Iterator;
    49 import sun.security.krb5.internal.KRBError;
    50 import sun.security.krb5.internal.KRBError;
    50 
    51 
    51 /**
    52 /**
    52  * KDC-REQ/KDC-REP communication. No more base class for KrbAsReq and
    53  * KDC-REQ/KDC-REP communication. No more base class for KrbAsReq and
    53  * KrbTgsReq. This class is now communication only.
    54  * KrbTgsReq. This class is now communication only.
   201     private byte[] send(byte[] obuf, boolean useTCP)
   202     private byte[] send(byte[] obuf, boolean useTCP)
   202         throws IOException, KrbException {
   203         throws IOException, KrbException {
   203 
   204 
   204         if (obuf == null)
   205         if (obuf == null)
   205             return null;
   206             return null;
   206         Exception savedException = null;
       
   207         Config cfg = Config.getInstance();
   207         Config cfg = Config.getInstance();
   208 
   208 
   209         if (realm == null) {
   209         if (realm == null) {
   210             realm = cfg.getDefaultRealm();
   210             realm = cfg.getDefaultRealm();
   211             if (realm == null) {
   211             if (realm == null) {
   216 
   216 
   217         String kdcList = cfg.getKDCList(realm);
   217         String kdcList = cfg.getKDCList(realm);
   218         if (kdcList == null) {
   218         if (kdcList == null) {
   219             throw new KrbException("Cannot get kdc for realm " + realm);
   219             throw new KrbException("Cannot get kdc for realm " + realm);
   220         }
   220         }
   221         String tempKdc = null; // may include the port number also
   221         // tempKdc may include the port number also
   222         byte[] ibuf = null;
   222         Iterator<String> tempKdc = KdcAccessibility.list(kdcList).iterator();
   223         for (String tmp: KdcAccessibility.list(kdcList)) {
   223         if (!tempKdc.hasNext()) {
   224             tempKdc = tmp;
   224             throw new KrbException("Cannot get kdc for realm " + realm);
       
   225         }
       
   226         try {
       
   227             return sendIfPossible(obuf, tempKdc.next(), useTCP);
       
   228         } catch(Exception first) {
       
   229             while(tempKdc.hasNext()) {
       
   230                 try {
       
   231                     return sendIfPossible(obuf, tempKdc.next(), useTCP);
       
   232                 } catch(Exception ignore) {}
       
   233             }
       
   234             throw first;
       
   235         }
       
   236     }
       
   237 
       
   238     // send the AS Request to the specified KDC
       
   239     // failover to using TCP if useTCP is not set and response is too big
       
   240     private byte[] sendIfPossible(byte[] obuf, String tempKdc, boolean useTCP)
       
   241         throws IOException, KrbException {
       
   242 
       
   243         try {
       
   244             byte[] ibuf = send(obuf, tempKdc, useTCP);
       
   245             KRBError ke = null;
   225             try {
   246             try {
   226                 ibuf = send(obuf,tempKdc,useTCP);
   247                 ke = new KRBError(ibuf);
   227                 KRBError ke = null;
       
   228                 try {
       
   229                     ke = new KRBError(ibuf);
       
   230                 } catch (Exception e) {
       
   231                     // OK
       
   232                 }
       
   233                 if (ke != null && ke.getErrorCode() ==
       
   234                         Krb5.KRB_ERR_RESPONSE_TOO_BIG) {
       
   235                     ibuf = send(obuf, tempKdc, true);
       
   236                 }
       
   237                 KdcAccessibility.removeBad(tempKdc);
       
   238                 break;
       
   239             } catch (Exception e) {
   248             } catch (Exception e) {
   240                 if (DEBUG) {
   249                 // OK
   241                     System.out.println(">>> KrbKdcReq send: error trying " +
   250             }
   242                             tempKdc);
   251             if (ke != null && ke.getErrorCode() ==
   243                     e.printStackTrace(System.out);
   252                     Krb5.KRB_ERR_RESPONSE_TOO_BIG) {
   244                 }
   253                 ibuf = send(obuf, tempKdc, true);
   245                 KdcAccessibility.addBad(tempKdc);
   254             }
   246                 savedException = e;
   255             KdcAccessibility.removeBad(tempKdc);
   247             }
   256             return ibuf;
   248         }
   257         } catch(Exception e) {
   249         if (ibuf == null && savedException != null) {
   258             if (DEBUG) {
   250             if (savedException instanceof IOException) {
   259                 System.out.println(">>> KrbKdcReq send: error trying " +
   251                 throw (IOException) savedException;
   260                         tempKdc);
   252             } else {
   261                 e.printStackTrace(System.out);
   253                 throw (KrbException) savedException;
   262             }
   254             }
   263             KdcAccessibility.addBad(tempKdc);
   255         }
   264             throw e;
   256         return ibuf;
   265         }
   257     }
   266     }
   258 
   267 
   259     // send the AS Request to the specified KDC
   268     // send the AS Request to the specified KDC
   260 
   269 
   261     private byte[] send(byte[] obuf, String tempKdc, boolean useTCP)
   270     private byte[] send(byte[] obuf, String tempKdc, boolean useTCP)
   494             }
   503             }
   495             bads.clear();
   504             bads.clear();
   496         }
   505         }
   497 
   506 
   498         // Returns a preferred KDC list by putting the bad ones at the end
   507         // Returns a preferred KDC list by putting the bad ones at the end
   499         private static synchronized String[] list(String kdcList) {
   508         private static synchronized List<String> list(String kdcList) {
   500             StringTokenizer st = new StringTokenizer(kdcList);
   509             StringTokenizer st = new StringTokenizer(kdcList);
   501             List<String> list = new ArrayList<>();
   510             List<String> list = new ArrayList<>();
   502             if (badPolicy == BpType.TRY_LAST) {
   511             if (badPolicy == BpType.TRY_LAST) {
   503                 List<String> badkdcs = new ArrayList<>();
   512                 List<String> badkdcs = new ArrayList<>();
   504                 while (st.hasMoreTokens()) {
   513                 while (st.hasMoreTokens()) {
   513                 // This include TRY_LESS and NONE
   522                 // This include TRY_LESS and NONE
   514                 while (st.hasMoreTokens()) {
   523                 while (st.hasMoreTokens()) {
   515                     list.add(st.nextToken());
   524                     list.add(st.nextToken());
   516                 }
   525                 }
   517             }
   526             }
   518             return list.toArray(new String[list.size()]);
   527             return list;
   519         }
   528         }
   520     }
   529     }
   521 }
   530 }
   522 
   531