1 23 24 29 30 package com.sun.appserv.management.client; 31 32 import java.util.HashMap ; 33 import java.util.Map ; 34 import java.util.logging.Logger ; 35 36 import java.io.IOException ; 37 import java.io.File ; 38 39 import java.net.MalformedURLException ; 40 41 import java.security.KeyStore ; 42 import javax.net.ssl.X509TrustManager; 43 import javax.net.ssl.HandshakeCompletedListener; 44 45 import javax.management.MBeanServerConnection ; 46 import javax.management.remote.JMXConnector ; 47 import javax.management.remote.JMXServiceURL ; 48 import javax.management.remote.JMXConnectorFactory ; 49 import javax.management.remote.JMXConnectionNotification ; 50 import javax.management.Notification ; 51 import javax.management.NotificationListener ; 52 53 54 import com.sun.appserv.management.client.ConnectionSource; 55 import com.sun.appserv.management.util.jmx.JMXConnectorConnectionSource; 56 import com.sun.appserv.management.util.misc.MapUtil; 57 58 import com.sun.appserv.management.DomainRoot; 59 60 61 106 public final class AppserverConnectionSource 107 implements NotificationListener , ConnectionSource 108 { 109 private final String mHost; 110 private final int mPort; 111 private final String mProtocol; 112 private final String mUser; 113 private final String mPassword; 114 private final TLSParams mTLSParams; 115 private final Map <String ,String > mReserved; 116 117 protected JMXConnector mJMXConnector; 118 119 123 private static final boolean DISABLE_HANDSHAKE_COMPLETED_CHECK = true; 124 125 private boolean 126 disableHandShakeCompletedCheck() 127 { 128 return( DISABLE_HANDSHAKE_COMPLETED_CHECK && mProtocol.equals( PROTOCOL_HTTP ) ); 129 } 130 131 132 135 public static boolean 136 isSupportedProtocol( final String protocol ) 137 { 138 return( protocol != null && 139 ( 140 protocol.equals( PROTOCOL_HTTP ) || 141 protocol.equals( PROTOCOL_RMI ) 142 ) 143 ); 144 } 145 146 147 150 public final static String TRUST_MANAGERS_KEY = "TRUST_MANAGER_KEY"; 151 152 155 public final static String HANDSHAKE_COMPLETED_LISTENER_KEY = "HandshakeCompletedListener"; 156 157 158 private static final String PROTOCOL_PREFIX = "sun-as-"; 159 160 165 public final static String PROTOCOL_RMI = PROTOCOL_PREFIX + "rmi"; 166 169 public final static String DEFAULT_PROTOCOL = PROTOCOL_RMI; 170 171 176 public final static String PROTOCOL_HTTP = PROTOCOL_PREFIX + "http"; 177 178 private static final String INTERNAL_HTTP = "s1ashttp"; 179 private static final String INTERNAL_HTTPS = "s1ashttps"; 180 181 184 private final static String HTTP_FACTORY_PACKAGES = 185 "com.sun.enterprise.admin.jmx.remote.protocol"; 186 187 192 public static final String DEFAULT_TRUST_STORE_NAME = ".asadmintruststore"; 193 194 197 public static final String DEFAULT_TRUST_STORE_PASSWORD = "changeit"; 198 199 208 public 209 AppserverConnectionSource( 210 String host, 211 int port, 212 String user, 213 String userPassword, 214 final Map <String ,String > reserved) 215 { 216 this( DEFAULT_PROTOCOL, host, port, user, userPassword, reserved); 217 } 218 219 220 235 public 236 AppserverConnectionSource( 237 final String protocol, 238 final String host, 239 final int port, 240 final String user, 241 final String userPassword, 242 final Map <String ,String > reserved ) 243 { 244 this ( protocol, host, port, user, userPassword, null, reserved ); 245 } 246 247 260 public 261 AppserverConnectionSource( 262 final String protocol, 263 final String host, 264 final int port, 265 final String user, 266 final String userPassword, 267 final TLSParams tlsParams, 268 final Map <String ,String > reserved ) 269 { 270 if ( reserved != null && reserved.keySet().size() != 0 ) 271 { 272 throw new IllegalArgumentException ( "No parameters may be passed in 'reserved' Map" ); 273 } 274 275 if ( isSupportedProtocol( protocol ) ) 276 { 277 mHost = host; 278 mPort = port; 279 mProtocol = protocol; 280 mUser = user; 281 mPassword = userPassword; 282 mTLSParams = tlsParams; 283 mReserved = reserved; 284 } 285 else 286 { 287 throw new IllegalArgumentException ( "unsupported protocol: " + protocol + 288 ", use either PROTOCOL_RMI or PROTOCOL_HTTP" ); 289 } 290 } 291 292 private Object 293 envGet( final String key ) 294 { 295 return( mReserved == null ? null : mReserved.get( key ) ); 296 } 297 298 private final boolean 299 useTLS() 300 { 301 return( mTLSParams != null ); 302 } 303 304 private final X509TrustManager[] 305 getTrustManagers() 306 { 307 return( mTLSParams == null ? null : mTLSParams.getTrustManagers() ); 308 } 309 310 private final HandshakeCompletedListener 311 getSuppliedHandshakeCompletedListener() 312 { 313 return( mTLSParams == null ? null : mTLSParams.getHandshakeCompletedListener() ); 314 } 315 316 317 private Map <String ,Object > 318 getCredentialsEnv( 319 final String user, 320 final String password ) 321 { 322 final HashMap <String ,Object > env = new HashMap <String ,Object >(); 323 324 final String [] credentials = new String [] { mUser, mPassword }; 325 326 env.put( JMXConnector.CREDENTIALS, credentials ); 327 328 return( env ); 329 } 330 331 private static final String APPSERVER_JNDI_NAME = "/management/rmi-jmx-connector"; 332 333 private void 334 warning( final String msg ) 335 { 336 System.out.println( "\n***\nWARNING: " + msg ); 337 } 338 339 private JMXConnector 340 createNew() 341 throws MalformedURLException , IOException 342 { 343 final Map <String ,Object > env = getCredentialsEnv( mUser, mPassword ); 344 345 env.put("jmx.remote.protocol.provider.class.loader", 347 this.getClass().getClassLoader()); 348 349 final HandshakeCompletedListenerImpl hcListener = 350 new HandshakeCompletedListenerImpl( getSuppliedHandshakeCompletedListener() ); 351 352 JMXServiceURL url = null; 353 if ( mProtocol.equals( PROTOCOL_HTTP ) ) 354 { 355 if ( useTLS() ) 356 { 357 final X509TrustManager[] tms = getTrustManagers(); 359 if (tms != null && tms.length >= 1) { 360 env.put( TRUST_MANAGERS_KEY, tms[0]); 361 } 362 env.put( HANDSHAKE_COMPLETED_LISTENER_KEY, hcListener ); 363 } 364 365 env.put( "com.sun.enterprise.as.http.auth", "BASIC" ); 366 env.put( "USER", mUser ); 367 env.put( "PASSWORD", mPassword ); 368 env.put( JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, HTTP_FACTORY_PACKAGES ); 370 371 final String internalProtocol = useTLS() ? INTERNAL_HTTPS : INTERNAL_HTTP; 372 url = new JMXServiceURL ( internalProtocol, mHost, mPort); 373 } 374 else if ( mProtocol.equals( PROTOCOL_RMI ) ) 375 { 376 if ( useTLS() ) 377 { 378 final AdminRMISSLClientSocketFactoryEnvImpl rmiEnv = 381 AdminRMISSLClientSocketFactoryEnvImpl.getInstance(); 382 rmiEnv.setHandshakeCompletedListener( hcListener ); 383 rmiEnv.setTrustManagers( getTrustManagers() ); 384 } 385 386 final String s = "service:jmx:rmi:///jndi/rmi://" + 387 mHost + ":" + mPort + APPSERVER_JNDI_NAME; 388 389 url = new JMXServiceURL ( s ); 390 } 391 else 392 { 393 assert( false ); 394 } 395 396 final JMXConnector conn = JMXConnectorFactory.connect( url, env ); 397 398 403 if ( ! disableHandShakeCompletedCheck() ) 404 { 405 if ( useTLS() && hcListener.getLastEvent() == null ) 406 { 407 conn.close(); 408 throw new IOException ( "Connection could not be established using TLS; server is not using TLS" ); 409 } 410 } 411 else 412 { 413 416 } 417 418 conn.addConnectionNotificationListener( this, null, conn ); 419 420 return( conn ); 421 } 422 423 427 public void 428 handleNotification( 429 final Notification notifIn, 430 final Object handback) 431 { 432 if ( notifIn instanceof JMXConnectionNotification ) 433 { 434 final JMXConnectionNotification notif = (JMXConnectionNotification )notifIn; 435 436 final String type = notif.getType(); 437 438 if ( type.equals( JMXConnectionNotification.FAILED) || 439 type.equals( JMXConnectionNotification.CLOSED ) ) 440 { 441 mJMXConnector = null; 442 } 443 } 444 } 445 446 453 public JMXConnector 454 getJMXConnector( final boolean forceNew ) 455 throws IOException 456 { 457 if ( forceNew || mJMXConnector == null ) 458 { 459 mJMXConnector = createNew(); 460 getMBeanServerConnection( false ); } 462 463 return( mJMXConnector ); 464 } 465 466 467 public MBeanServerConnection 468 getExistingMBeanServerConnection( ) 469 { 470 try 471 { 472 return( getJMXConnector( false ).getMBeanServerConnection() ); 473 } 474 catch( IOException e ) 475 { 476 } 477 return( null ); 478 } 479 480 481 484 public MBeanServerConnection 485 getMBeanServerConnection( final boolean forceNew ) 486 throws IOException 487 { 488 return( getJMXConnector( forceNew ).getMBeanServerConnection() ); 489 } 490 491 499 public DomainRoot 500 getDomainRoot() 501 throws IOException 502 { 503 final DomainRoot domainRoot = 504 ProxyFactory.getInstance( this ).getDomainRoot( true ); 505 506 return domainRoot; 507 } 508 509 public String 510 toString() 511 { 512 return( 513 "protocol=" + mProtocol + 514 ", host=" + mHost + 515 ", port=" + mPort + 516 ", user=" + mUser + 517 ", useTLS={" + useTLS() + "}" + 518 ", mReserved=" + (mReserved == null ? "null" : MapUtil.toString( mReserved )) ); 519 } 520 521 522 523 } 524 525 | Popular Tags |