jdk/src/share/classes/sun/security/krb5/KdcComm.java
changeset 20818 da638a97c27a
parent 20804 18285d130365
parent 18549 66e6e111be22
child 20827 29e3da385ed2
equal deleted inserted replaced
20816:b44a353664b8 20818:da638a97c27a
    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         Iterator<String> tempKdc = KdcAccessibility.list(kdcList).iterator();
       
   223         if (!tempKdc.hasNext()) {
       
   224             throw new KrbException("Cannot get kdc for realm " + realm);
       
   225         }
   222         byte[] ibuf = null;
   226         byte[] ibuf = null;
   223         for (String tmp: KdcAccessibility.list(kdcList)) {
   227         try {
   224             tempKdc = tmp;
   228             ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP);
       
   229         } catch(Exception first) {
       
   230             while(tempKdc.hasNext()) {
       
   231                 try {
       
   232                     ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP);
       
   233                     if (ibuf != null) {
       
   234                         return ibuf;
       
   235                     }
       
   236                 } catch(Exception ignore) {}
       
   237             }
       
   238             throw first;
       
   239         }
       
   240         if (ibuf == null) {
       
   241             throw new IOException("Cannot get a KDC reply");
       
   242         }
       
   243         return ibuf;
       
   244     }
       
   245 
       
   246     // send the AS Request to the specified KDC
       
   247     // failover to using TCP if useTCP is not set and response is too big
       
   248     private byte[] sendIfPossible(byte[] obuf, String tempKdc, boolean useTCP)
       
   249         throws IOException, KrbException {
       
   250 
       
   251         try {
       
   252             byte[] ibuf = send(obuf, tempKdc, useTCP);
       
   253             KRBError ke = null;
   225             try {
   254             try {
   226                 ibuf = send(obuf,tempKdc,useTCP);
   255                 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) {
   256             } catch (Exception e) {
   240                 if (DEBUG) {
   257                 // OK
   241                     System.out.println(">>> KrbKdcReq send: error trying " +
   258             }
   242                             tempKdc);
   259             if (ke != null && ke.getErrorCode() ==
   243                     e.printStackTrace(System.out);
   260                     Krb5.KRB_ERR_RESPONSE_TOO_BIG) {
   244                 }
   261                 ibuf = send(obuf, tempKdc, true);
   245                 KdcAccessibility.addBad(tempKdc);
   262             }
   246                 savedException = e;
   263             KdcAccessibility.removeBad(tempKdc);
   247             }
   264             return ibuf;
   248         }
   265         } catch(Exception e) {
   249         if (ibuf == null) {
   266             if (DEBUG) {
   250             if (savedException != null) {
   267                 System.out.println(">>> KrbKdcReq send: error trying " +
   251                 if (savedException instanceof IOException) {
   268                         tempKdc);
   252                     throw (IOException) savedException;
   269                 e.printStackTrace(System.out);
   253                 } else {
   270             }
   254                     throw (KrbException) savedException;
   271             KdcAccessibility.addBad(tempKdc);
   255                 }
   272             throw e;
   256             } else {
   273         }
   257                 throw new IOException("Cannot get a KDC reply");
       
   258             }
       
   259         }
       
   260         return ibuf;
       
   261     }
   274     }
   262 
   275 
   263     // send the AS Request to the specified KDC
   276     // send the AS Request to the specified KDC
   264 
   277 
   265     private byte[] send(byte[] obuf, String tempKdc, boolean useTCP)
   278     private byte[] send(byte[] obuf, String tempKdc, boolean useTCP)
   498             }
   511             }
   499             bads.clear();
   512             bads.clear();
   500         }
   513         }
   501 
   514 
   502         // Returns a preferred KDC list by putting the bad ones at the end
   515         // Returns a preferred KDC list by putting the bad ones at the end
   503         private static synchronized String[] list(String kdcList) {
   516         private static synchronized List<String> list(String kdcList) {
   504             StringTokenizer st = new StringTokenizer(kdcList);
   517             StringTokenizer st = new StringTokenizer(kdcList);
   505             List<String> list = new ArrayList<>();
   518             List<String> list = new ArrayList<>();
   506             if (badPolicy == BpType.TRY_LAST) {
   519             if (badPolicy == BpType.TRY_LAST) {
   507                 List<String> badkdcs = new ArrayList<>();
   520                 List<String> badkdcs = new ArrayList<>();
   508                 while (st.hasMoreTokens()) {
   521                 while (st.hasMoreTokens()) {
   517                 // This include TRY_LESS and NONE
   530                 // This include TRY_LESS and NONE
   518                 while (st.hasMoreTokens()) {
   531                 while (st.hasMoreTokens()) {
   519                     list.add(st.nextToken());
   532                     list.add(st.nextToken());
   520                 }
   533                 }
   521             }
   534             }
   522             return list.toArray(new String[list.size()]);
   535             return list;
   523         }
   536         }
   524     }
   537     }
   525 }
   538 }
   526 
   539