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