1 28 29 package HTTPClient; 30 31 import java.io.IOException ; 32 import java.net.ProtocolException ; 33 import java.util.Hashtable ; 34 35 36 45 46 class AuthorizationModule implements HTTPClientModule, GlobalConstants 47 { 48 50 private static Hashtable proxy_cntxt_list = new Hashtable (); 51 52 53 private int auth_lst_idx, 54 prxy_lst_idx, 55 auth_scm_idx, 56 prxy_scm_idx; 57 58 59 private AuthorizationInfo auth_sent; 60 private AuthorizationInfo prxy_sent; 61 62 63 private boolean auth_from_4xx; 64 private boolean prxy_from_4xx; 65 66 67 private int num_tries; 68 69 70 72 75 AuthorizationModule() 76 { 77 auth_lst_idx = 0; 78 prxy_lst_idx = 0; 79 auth_scm_idx = 0; 80 prxy_scm_idx = 0; 81 82 auth_sent = null; 83 prxy_sent = null; 84 85 auth_from_4xx = false; 86 prxy_from_4xx = false; 87 88 num_tries = 0; 89 } 90 91 92 94 97 public int requestHandler(Request req, Response[] resp) 98 { 99 HTTPConnection con = req.getConnection(); 100 AuthorizationHandler auth_handler = AuthorizationInfo.getAuthHandler(); 101 AuthorizationInfo guess; 102 103 104 106 Proxy: if (con.getProxyHost() != null && !prxy_from_4xx) 107 { 108 Hashtable proxy_auth_list = Util.getList(proxy_cntxt_list, 109 req.getConnection().getContext()); 110 guess = (AuthorizationInfo) proxy_auth_list.get( 111 con.getProxyHost()+":"+con.getProxyPort()); 112 if (guess == null) break Proxy; 113 114 if (auth_handler != null) 115 { 116 try 117 { guess = auth_handler.fixupAuthInfo(guess, req, null, null); } 118 catch (AuthSchemeNotImplException atnie) 119 { break Proxy; } 120 if (guess == null) break Proxy; 121 } 122 123 int idx; 124 NVPair[] hdrs = req.getHeaders(); 125 for (idx=0; idx<hdrs.length; idx++) 126 { 127 if (hdrs[idx].getName().equalsIgnoreCase("Proxy-Authorization")) 128 break; } 130 if (idx == hdrs.length) { 132 hdrs = Util.resizeArray(hdrs, idx+1); 133 req.setHeaders(hdrs); 134 } 135 136 hdrs[idx] = new NVPair("Proxy-Authorization", guess.toString()); 137 138 prxy_sent = guess; 139 prxy_from_4xx = false; 140 141 if (DebugMods) 142 System.err.println("AuthM: Preemptively sending " + 143 "Proxy-Authorization '" + guess + "'"); 144 } 145 146 147 149 Auth: if (!auth_from_4xx) 150 { 151 guess = AuthorizationInfo.findBest(req); 152 if (guess == null) break Auth; 153 154 if (auth_handler != null) 155 { 156 try 157 { guess = auth_handler.fixupAuthInfo(guess, req, null, null); } 158 catch (AuthSchemeNotImplException atnie) 159 { break Auth; } 160 if (guess == null) break Auth; 161 } 162 163 int idx; 164 NVPair[] hdrs = req.getHeaders(); 165 for (idx=0; idx<hdrs.length; idx++) 166 { 167 if (hdrs[idx].getName().equalsIgnoreCase("Authorization")) 168 break; } 170 if (idx == hdrs.length) { 172 hdrs = Util.resizeArray(hdrs, idx+1); 173 req.setHeaders(hdrs); 174 } 175 176 hdrs[idx] = new NVPair("Authorization", guess.toString()); 177 178 auth_sent = guess; 179 auth_from_4xx = false; 180 181 if (DebugMods) 182 System.err.println("AuthM: Preemptively sending Authorization '" 183 + guess + "'"); 184 } 185 186 return REQ_CONTINUE; 187 } 188 189 190 193 public void responsePhase1Handler(Response resp, RoRequest req) 194 throws IOException 195 { 196 204 if (resp.getStatusCode() != 401 && resp.getStatusCode() != 407) 205 { 206 if (auth_sent != null && auth_from_4xx) 207 { 208 try 209 { 210 AuthorizationInfo.getAuthorization(auth_sent, req, resp, 211 false).addPath(req.getRequestURI()); 212 } 213 catch (AuthSchemeNotImplException asnie) 214 { } 215 } 216 217 num_tries = 0; 219 } 220 221 auth_from_4xx = false; 222 prxy_from_4xx = false; 223 224 if (resp.getHeader("WWW-Authenticate") == null) 225 { 226 auth_lst_idx = 0; 227 auth_scm_idx = 0; 228 } 229 230 if (resp.getHeader("Proxy-Authenticate") == null) 231 { 232 prxy_lst_idx = 0; 233 prxy_scm_idx = 0; 234 } 235 } 236 237 238 241 public int responsePhase2Handler(Response resp, Request req) 242 throws IOException , AuthSchemeNotImplException 243 { 244 246 AuthorizationHandler h = AuthorizationInfo.getAuthHandler(); 247 if (h != null) 248 h.handleAuthHeaders(resp, req, auth_sent, prxy_sent); 249 250 251 253 int sts = resp.getStatusCode(); 254 switch(sts) 255 { 256 case 401: case 407: 259 261 num_tries++; 262 if (num_tries > 10) 263 throw new ProtocolException ("Bug in authorization handling: server refused the given info 10 times"); 264 265 266 if (DebugMods) System.err.println("AuthM: Handling status: " + 267 sts + " " + resp.getReasonLine()); 268 269 270 272 int[] idx_arr = { auth_lst_idx, auth_scm_idx}; 274 auth_sent = setAuthHeaders(resp.getHeader("WWW-Authenticate"), 275 req, resp, "Authorization", idx_arr, 276 auth_sent); 277 if (auth_sent != null) 278 auth_from_4xx = true; 279 auth_lst_idx = idx_arr[0]; 280 auth_scm_idx = idx_arr[1]; 281 282 283 285 idx_arr[0] = prxy_lst_idx; idx_arr[1] = prxy_scm_idx; 287 prxy_sent = setAuthHeaders(resp.getHeader("Proxy-Authenticate"), 288 req, resp, "Proxy-Authorization", 289 idx_arr, prxy_sent); 290 if (prxy_sent != null) 291 prxy_from_4xx = true; 292 prxy_lst_idx = idx_arr[0]; 293 prxy_scm_idx = idx_arr[1]; 294 295 if (prxy_sent != null) 296 { 297 HTTPConnection con = req.getConnection(); 298 Util.getList(proxy_cntxt_list, con.getContext()) 299 .put(con.getProxyHost()+":"+con.getProxyPort(), 300 prxy_sent); 301 } 302 303 304 if (req.getStream() == null && 305 (auth_sent != null || prxy_sent != null)) 306 { 307 try { resp.getInputStream().close(); } 308 catch (IOException ioe) { } 309 310 if (DebugMods) 311 { 312 if (auth_sent != null) 313 System.err.println("AuthM: Resending request " + 314 "with Authorization '" + 315 auth_sent + "'"); 316 else 317 System.err.println("AuthM: Resending request " + 318 "with Proxy-Authorization '" + 319 prxy_sent + "'"); 320 } 321 322 return RSP_REQUEST; 323 } 324 325 326 328 if (auth_sent == null && prxy_sent == null && 329 resp.getHeader("WWW-Authenticate") == null && 330 resp.getHeader("Proxy-Authenticate") == null) 331 { 332 if (resp.getStatusCode() == 401) 333 throw new ProtocolException ("Missing WWW-Authenticate header"); 334 else 335 throw new ProtocolException ("Missing Proxy-Authenticate header"); 336 } 337 338 if (DebugMods) 339 { 340 if (req.getStream() == null) 341 System.err.println("AuthM: status " + sts + " not " + 342 "handled - request has an output " + 343 "stream"); 344 else 345 System.err.println("AuthM: No Auth Info found - " + 346 "status " + sts + " not handled"); 347 } 348 349 return RSP_CONTINUE; 350 351 default: 352 353 return RSP_CONTINUE; 354 } 355 } 356 357 358 361 public void responsePhase3Handler(Response resp, RoRequest req) 362 { 363 } 364 365 366 369 public void trailerHandler(Response resp, RoRequest req) throws IOException 370 { 371 373 AuthorizationHandler h = AuthorizationInfo.getAuthHandler(); 374 if (h != null) 375 h.handleAuthTrailers(resp, req, auth_sent, prxy_sent); 376 } 377 378 379 396 private AuthorizationInfo setAuthHeaders(String auth_str, Request req, 397 RoResponse resp, String header, 398 int[] idx_arr, 399 AuthorizationInfo prev) 400 throws ProtocolException , AuthSchemeNotImplException 401 { 402 if (auth_str == null) return null; 403 404 AuthorizationInfo[] challenge = 406 AuthorizationInfo.parseAuthString(auth_str, req, resp); 407 408 if (DebugMods) 409 { 410 System.err.println("AuthM: parsed " + challenge.length + 411 " challenges:"); 412 for (int idx=0; idx<challenge.length; idx++) 413 System.err.println("AuthM: Challenge " + challenge[idx]); 414 } 415 416 417 421 if (prev != null && prev.getScheme().equalsIgnoreCase("Basic")) 422 { 423 for (int idx=0; idx<challenge.length; idx++) 424 if (prev.getRealm().equals(challenge[idx].getRealm()) && 425 prev.getScheme().equalsIgnoreCase(challenge[idx].getScheme())) 426 AuthorizationInfo.removeAuthorization(prev, 427 req.getConnection().getContext()); 428 } 429 430 AuthorizationInfo credentials = null; 431 AuthorizationHandler auth_handler = AuthorizationInfo.getAuthHandler(); 432 433 while (credentials == null && idx_arr[0] != -1) 435 { 436 credentials = 437 AuthorizationInfo.getAuthorization(challenge[idx_arr[0]], req, 438 resp, false); 439 if (auth_handler != null && credentials != null) 440 credentials = auth_handler.fixupAuthInfo(credentials, req, 441 challenge[idx_arr[0]], resp); 442 if (++idx_arr[0] == challenge.length) 443 idx_arr[0] = -1; 444 } 445 446 447 if (credentials == null) 449 { 450 for (int idx=0; idx<challenge.length; idx++) 451 { 452 try 453 { 454 credentials = AuthorizationInfo.queryAuthHandler( 455 challenge[idx_arr[1]], req, resp); 456 } 457 catch (AuthSchemeNotImplException atnie) 458 { 459 if (idx == challenge.length-1) 460 throw atnie; 461 continue; 462 } 463 break; 464 } 465 if (++idx_arr[1] == challenge.length) 466 idx_arr[1] = 0; 467 } 468 469 if (credentials == null) 471 return null; 472 473 int auth_idx; 475 NVPair[] hdrs = req.getHeaders(); 476 for (auth_idx=0; auth_idx<hdrs.length; auth_idx++) 477 { 478 if (hdrs[auth_idx].getName().equalsIgnoreCase(header)) 479 break; 480 } 481 482 if (auth_idx == hdrs.length) 484 { 485 hdrs = Util.resizeArray(hdrs, auth_idx+1); 486 req.setHeaders(hdrs); 487 } 488 hdrs[auth_idx] = new NVPair(header, credentials.toString()); 489 490 return credentials; 491 } 492 } 493 494 | Popular Tags |