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. |
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()) { |