1 16 17 package org.apache.ajp; 18 19 import java.io.IOException ; 20 import java.security.MessageDigest ; 21 22 import org.apache.tomcat.util.buf.HexUtils; 23 import org.apache.tomcat.util.http.BaseRequest; 24 25 26 36 public class NegociationHandler extends AjpHandler 37 { 38 39 private static org.apache.commons.logging.Log log= 40 org.apache.commons.logging.LogFactory.getLog(NegociationHandler.class ); 41 42 public static final byte JK_AJP14_LOGINIT_CMD=0x10; 44 45 public static final byte JK_AJP14_LOGSEED_CMD=0x11; 47 48 public static final byte JK_AJP14_LOGCOMP_CMD=0x12; 51 52 public static final byte JK_AJP14_LOGOK_CMD=0x13; 54 55 public static final byte JK_AJP14_LOGNOK_CMD=0x14; 57 58 public static final byte JK_AJP14_CONTEXT_QRY_CMD=0x15; 61 62 public static final byte JK_AJP14_CONTEXT_INFO_CMD= 0x16; 64 65 public static final byte JK_AJP14_CONTEXT_UPDATE_CMD= 0x17; 67 68 public static final byte JK_AJP14_STATUS_CMD= 0x18; 71 72 public static final byte JK_AJP14_SHUTDOWN_CMD= 0x19; 75 76 public static final byte JK_AJP14_SHUTOK_CMD= 0x1A; 78 79 public static final byte JK_AJP14_SHUTNOK_CMD= 0x1B; 81 82 public static final byte JK_AJP14_CONTEXT_STATE_CMD= 0x1C; 85 86 public static final byte JK_AJP14_CONTEXT_STATE_REP_CMD = 0x1D; 88 89 public static final byte JK_AJP14_UNKNOW_PACKET_CMD = 0x1E; 92 93 94 96 public static final int AJP14_ENTROPY_SEED_LEN= 32; 98 public static final int AJP14_COMPUTED_KEY_LEN= 32; 99 100 public static final int AJP14_CONTEXT_INFO_NEG= 0x80000000; 102 103 public static final int AJP14_CONTEXT_UPDATE_NEG= 0x40000000; 105 106 public static final int AJP14_GZIP_STREAM_NEG= 0x20000000; 108 109 public static final int AJP14_DES56_STREAM_NEG= 0x10000000; 111 112 public static final int AJP14_SSL_VSERVER_NEG= 0x08000000; 114 115 public static final int AJP14_SSL_VCLIENT_NEG= 0x04000000; 117 118 public static final int AJP14_SSL_VCRYPTO_NEG= 0x02000000; 120 121 public static final int AJP14_SSL_VMISC_NEG= 0x01000000; 123 124 public static final int AJP14_PROTO_SUPPORT_AJPXX_NEG=0x00FF0000; 126 127 public static final int AJP14_PROTO_SUPPORT_AJP14_NEG=0x00010000; 129 130 public static final int AJP14_PROTO_SUPPORT_AJP15_NEG=0x00020000; 132 133 public static final int AJP14_PROTO_SUPPORT_AJP16_NEG=0x00040000; 135 136 public static final int AJP14_BAD_KEY_ERR= 0xFFFFFFFF; 138 public static final int AJP14_ENGINE_DOWN_ERR = 0xFFFFFFFE; 139 public static final int AJP14_RETRY_LATER_ERR = 0xFFFFFFFD; 140 public static final int AJP14_SHUT_AUTHOR_FAILED_ERR = 0xFFFFFFFC; 141 142 public static final byte AJP14_CONTEXT_DOWN= 0x01; 144 public static final byte AJP14_CONTEXT_UP= 0x02; 145 public static final byte AJP14_CONTEXT_OK= 0x03; 146 147 148 String containerSignature="Ajp14-based container"; 150 String seed="seed"; String password; 152 153 int webserverNegociation=0; 154 156 public NegociationHandler() { 157 setSeed("myveryrandomentropy"); 158 setPassword("myverysecretkey"); 159 } 160 161 public void setContainerSignature( String s ) { 162 containerSignature=s; 163 } 164 165 167 171 173 176 public void setSeed(String pseed) 177 { 178 String [] credentials = new String [1]; 179 credentials[0] = pseed; 180 seed = digest(credentials, "md5"); 181 } 182 183 186 public String getSeed() 187 { 188 return seed; 189 } 190 191 194 public void setPassword(String ppwd) 195 { 196 password = ppwd; 197 } 198 199 202 public String getPassword() 203 { 204 return password; 205 } 206 207 209 public void init( Ajp13 ajp14 ) { 210 super.init(ajp14); 211 ajp14.registerMessageType( JK_AJP14_LOGINIT_CMD,"JK_AJP14_LOGINIT_CMD", 213 this, null); ajp14.registerMessageType( JK_AJP14_LOGCOMP_CMD,"JK_AJP14_LOGCOMP_CMD", 215 this, null); ajp14.registerMessageType( RequestHandler.JK_AJP13_SHUTDOWN,"JK_AJP13_SHUTDOWN", 217 this, null); ajp14.registerMessageType( JK_AJP14_CONTEXT_QRY_CMD, 219 "JK_AJP14_CONTEXT_QRY_CMD", 220 this, null); ajp14.registerMessageType( JK_AJP14_STATUS_CMD,"JK_AJP14_STATUS_CMD", 222 this, null); ajp14.registerMessageType( JK_AJP14_SHUTDOWN_CMD, 224 "JK_AJP14_SHUTDOWN_CMD", 225 this, null); ajp14.registerMessageType( JK_AJP14_CONTEXT_STATE_CMD, 227 "JK_AJP14_CONTEXT_STATE_CMD", 228 this, null); ajp14.registerMessageType( JK_AJP14_UNKNOW_PACKET_CMD, 230 "JK_AJP14_UNKNOW_PACKET_CMD", 231 this, null); 233 ajp14.registerMessageType( JK_AJP14_LOGNOK_CMD,"JK_AJP14_LOGNOK_CMD", 235 this,null ); 236 237 } 238 239 240 241 243 public int handleAjpMessage( int type, Ajp13 ch, Ajp13Packet hBuf, 244 BaseRequest req ) 245 throws IOException 246 { 247 if (log.isDebugEnabled()) 248 log.debug("handleAjpMessage: " + type ); 249 Ajp13Packet outBuf=ch.outBuf; 250 switch( type ) { 252 case JK_AJP14_LOGINIT_CMD : 253 return handleLogInit(ch, hBuf, outBuf); 254 case JK_AJP14_LOGCOMP_CMD : 255 return handleLogComp(ch, hBuf, outBuf); 256 case RequestHandler.JK_AJP13_SHUTDOWN: 257 return -2; 258 case JK_AJP14_CONTEXT_QRY_CMD : 259 return handleContextQuery(ch, hBuf, outBuf); 260 case JK_AJP14_STATUS_CMD : 261 return handleStatus(hBuf, outBuf); 262 case JK_AJP14_SHUTDOWN_CMD : 263 return handleShutdown(hBuf, outBuf); 264 case JK_AJP14_CONTEXT_STATE_CMD : 265 return handleContextState(hBuf, outBuf); 266 case JK_AJP14_UNKNOW_PACKET_CMD : 267 return handleUnknowPacket(hBuf, outBuf); 268 default: 269 log("unknown command " + type + " received"); 270 return 200; } 272 } 274 275 277 285 private int handleLogInit( Ajp13 ch, Ajp13Packet msg, 286 Ajp13Packet outBuf ) 287 throws IOException 288 { 289 webserverNegociation = msg.getLongInt(); 290 String webserverName = msg.getString(); 291 log("in handleLogInit with nego " + 292 decodeNegociation(webserverNegociation) + 293 " from webserver " + webserverName); 294 295 outBuf.reset(); 296 outBuf.appendByte(JK_AJP14_LOGSEED_CMD); 297 String [] credentials = new String [1]; 298 credentials[0] = getSeed(); 299 outBuf.appendXBytes(getSeed().getBytes(), 0, AJP14_ENTROPY_SEED_LEN); 300 log("in handleLogInit: sent entropy " + getSeed()); 301 outBuf.end(); 302 ch.send(outBuf); 303 return 304; 304 } 305 306 313 private int handleLogComp( Ajp13 ch, Ajp13Packet msg, 314 Ajp13Packet outBuf ) 315 throws IOException 316 { 317 319 byte [] rdigest = new byte[AJP14_ENTROPY_SEED_LEN]; 320 321 if (msg.getXBytes(rdigest, AJP14_ENTROPY_SEED_LEN) < 0) 322 return 200; 323 324 String [] credentials = new String [2]; 325 credentials[0] = getSeed(); 326 credentials[1] = getPassword(); 327 String computed = digest(credentials, "md5"); 328 String received = new String (rdigest); 329 330 332 if ( ! computed.equalsIgnoreCase(received)) { 333 log("in handleLogComp : authentification failure received=" + 334 received + " awaited=" + computed); 335 } 336 337 if (false ) { log("in handleLogComp : authentification failure received=" + 339 received + " awaited=" + computed); 340 341 outBuf.reset(); 345 outBuf.appendByte(JK_AJP14_LOGNOK_CMD); 346 outBuf.appendLongInt(AJP14_BAD_KEY_ERR); 347 outBuf.end(); 348 ch.send(outBuf); 349 return 200; 350 } else { 351 channel.setLogged(true); 353 outBuf.reset(); 354 outBuf.appendByte(JK_AJP14_LOGOK_CMD); 355 outBuf.appendLongInt(getProtocolFlags(webserverNegociation)); 356 outBuf.appendString( containerSignature ); 357 outBuf.end(); 358 ch.send(outBuf); 359 } 360 361 return (304); 362 } 363 364 private int handleContextQuery( Ajp13 ch, Ajp13Packet msg, 365 Ajp13Packet outBuf ) 366 throws IOException 367 { 368 log("in handleContextQuery :"); 369 String virtualHost = msg.getString(); 370 log("in handleContextQuery for virtual" + virtualHost); 371 372 outBuf.reset(); 373 outBuf.appendByte(JK_AJP14_CONTEXT_INFO_CMD); 374 outBuf.appendString( virtualHost ); 375 376 log("in handleContextQuery for virtual " + virtualHost + 377 "examples URI/MIMES"); 378 outBuf.appendString("examples"); outBuf.appendString("servlet/*"); outBuf.appendString("*.jsp"); outBuf.appendString(""); 383 log("in handleContextQuery for virtual " + virtualHost + 384 "send admin URI/MIMES"); 385 outBuf.appendString("admin"); outBuf.appendString("servlet/*"); outBuf.appendString("*.jsp"); outBuf.appendString(""); 390 outBuf.appendString(""); outBuf.end(); 392 ch.send(outBuf); 393 394 return (304); 395 } 396 397 private int handleStatus( Ajp13Packet msg, Ajp13Packet outBuf ) 398 throws IOException 399 { 400 log("in handleStatus :"); 401 return (304); 402 } 403 404 private int handleShutdown( Ajp13Packet msg, Ajp13Packet outBuf ) 405 throws IOException 406 { 407 log("in handleShutdown :"); 408 return (304); 409 } 410 411 private int handleContextState( Ajp13Packet msg , Ajp13Packet outBuf) 412 throws IOException 413 { 414 log("in handleContextState :"); 415 return (304); 416 } 417 418 private int handleUnknowPacket( Ajp13Packet msg, Ajp13Packet outBuf ) 419 throws IOException 420 { 421 log("in handleUnknowPacket :"); 422 return (304); 423 } 424 425 427 435 private int getProtocolFlags(int wanted) 436 { 437 wanted &= ~(AJP14_CONTEXT_UPDATE_NEG | 439 AJP14_GZIP_STREAM_NEG | 441 AJP14_DES56_STREAM_NEG | 443 AJP14_SSL_VSERVER_NEG | 445 AJP14_SSL_VCLIENT_NEG | 447 AJP14_SSL_VCRYPTO_NEG | 449 AJP14_SSL_VMISC_NEG | 451 AJP14_PROTO_SUPPORT_AJPXX_NEG); 453 454 return (wanted | AJP14_PROTO_SUPPORT_AJP14_NEG); 456 } 457 458 461 public final String digest(String [] credentials, String algorithm) { 462 try { 463 MessageDigest md = 465 (MessageDigest )MessageDigest.getInstance(algorithm).clone(); 466 for (int i = 0; i < credentials.length; i++) { 468 if( debug > 0 ) 469 log("Credentials : " + i + " " + credentials[i]); 470 if( credentials[i] != null ) 471 md.update(credentials[i].getBytes()); 472 } 473 byte[] dig = md.digest(); 475 return HexUtils.convert(dig); 476 } catch (Exception ex) { 477 ex.printStackTrace(); 478 return null; 479 } 480 } 481 482 485 488 private String decodeNegociation(int nego) 489 { 490 StringBuffer buf = new StringBuffer (128); 491 492 if ((nego & AJP14_CONTEXT_INFO_NEG) != 0) 493 buf.append(" CONTEXT-INFO"); 494 495 if ((nego & AJP14_CONTEXT_UPDATE_NEG) != 0) 496 buf.append(" CONTEXT-UPDATE"); 497 498 if ((nego & AJP14_GZIP_STREAM_NEG) != 0) 499 buf.append(" GZIP-STREAM"); 500 501 if ((nego & AJP14_DES56_STREAM_NEG) != 0) 502 buf.append(" DES56-STREAM"); 503 504 if ((nego & AJP14_SSL_VSERVER_NEG) != 0) 505 buf.append(" SSL-VSERVER"); 506 507 if ((nego & AJP14_SSL_VCLIENT_NEG) != 0) 508 buf.append(" SSL-VCLIENT"); 509 510 if ((nego & AJP14_SSL_VCRYPTO_NEG) != 0) 511 buf.append(" SSL-VCRYPTO"); 512 513 if ((nego & AJP14_SSL_VMISC_NEG) != 0) 514 buf.append(" SSL-VMISC"); 515 516 if ((nego & AJP14_PROTO_SUPPORT_AJP14_NEG) != 0) 517 buf.append(" AJP14"); 518 519 if ((nego & AJP14_PROTO_SUPPORT_AJP15_NEG) != 0) 520 buf.append(" AJP15"); 521 522 if ((nego & AJP14_PROTO_SUPPORT_AJP16_NEG) != 0) 523 buf.append(" AJP16"); 524 525 return (buf.toString()); 526 } 527 528 private static int debug=10; 529 void log(String s) { 530 if (log.isDebugEnabled()) 531 log.debug("Ajp14Negotiation: " + s ); 532 } 533 } 534 | Popular Tags |