1 /*
   2  * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4924664
  27  * @summary Tests the use of the "jmx.remote.x.password.file" and
  28  *          "jmx.remote.x.access.file" environment map properties.
  29  * @author Luis-Miguel Alventosa
  30  * @run clean PasswordAccessFileTest SimpleStandard SimpleStandardMBean
  31  * @run build PasswordAccessFileTest SimpleStandard SimpleStandardMBean
  32  * @run main PasswordAccessFileTest
  33  */
  34 
  35 import java.io.File;
  36 import java.util.HashMap;
  37 import javax.management.Attribute;
  38 import javax.management.MBeanServer;
  39 import javax.management.MBeanServerConnection;
  40 import javax.management.MBeanServerFactory;
  41 import javax.management.MBeanServerInvocationHandler;
  42 import javax.management.Notification;
  43 import javax.management.NotificationListener;
  44 import javax.management.ObjectName;
  45 import javax.management.remote.JMXConnector;
  46 import javax.management.remote.JMXConnectorFactory;
  47 import javax.management.remote.JMXConnectorServer;
  48 import javax.management.remote.JMXConnectorServerFactory;
  49 import javax.management.remote.JMXServiceURL;
  50 
  51 public class PasswordAccessFileTest {
  52 
  53     public static void main(String[] args) {
  54         try {
  55             //------------------------------------------------------------------
  56             // SERVER
  57             //------------------------------------------------------------------
  58 
  59             // Instantiate the MBean server
  60             //
  61             System.out.println("Create the MBean server");
  62             MBeanServer mbs = MBeanServerFactory.createMBeanServer();
  63 
  64             // Create SimpleStandard MBean
  65             //
  66             ObjectName mbeanName = new ObjectName("MBeans:type=SimpleStandard");
  67             System.out.println("Create SimpleStandard MBean...");
  68             mbs.createMBean("SimpleStandard", mbeanName, null, null);
  69 
  70             // Server's environment map
  71             //
  72             System.out.println(">>> Initialize the server's environment map");
  73             HashMap sEnv = new HashMap();
  74 
  75             // Provide the password file used by the connector server to
  76             // perform user authentication. The password file is a properties
  77             // based text file specifying username/password pairs. This
  78             // properties based password authenticator has been implemented
  79             // using the JMXAuthenticator interface and is passed to the
  80             // connector through the "jmx.remote.authenticator" property
  81             // in the map.
  82             //
  83             // This property is implementation-dependent and might not be
  84             // supported by all implementations of the JMX Remote API.
  85             //
  86             sEnv.put("jmx.remote.x.password.file",
  87                      System.getProperty("test.src") +
  88                      File.separator +
  89                      "password.properties");
  90 
  91             // Provide the access level file used by the connector server to
  92             // perform user authorization. The access level file is a properties
  93             // based text file specifying username/access level pairs where
  94             // access level is either "readonly" or "readwrite" access to the
  95             // MBeanServer operations. This properties based access control
  96             // checker has been implemented using the MBeanServerForwarder
  97             // interface which wraps the real MBean server inside an access
  98             // controller MBean server which performs the access control checks
  99             // before forwarding the requests to the real MBean server.
 100             //
 101             // This property is implementation-dependent and might not be
 102             // supported by all implementations of the JMX Remote API.
 103             //
 104             sEnv.put("jmx.remote.x.access.file",
 105                      System.getProperty("test.src") +
 106                      File.separator +
 107                      "access.properties");
 108 
 109             // Create an RMI connector server
 110             //
 111             System.out.println("Create an RMI connector server");
 112             JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
 113             JMXConnectorServer cs =
 114                 JMXConnectorServerFactory.newJMXConnectorServer(url, sEnv, mbs);
 115 
 116             // Start the RMI connector server
 117             //
 118             System.out.println("Start the RMI connector server");
 119             cs.start();
 120             System.out.println("RMI connector server successfully started");
 121             System.out.println("Waiting for incoming connections...");
 122 
 123             //------------------------------------------------------------------
 124             // CLIENT : Invalid authentication credentials
 125             //------------------------------------------------------------------
 126 
 127             final String invalidCreds[][] = {
 128                 {"admin1", "adminPassword"},
 129                 {"admin",  "adminPassword1"},
 130                 {"user1",  "userPassword"},
 131                 {"user",   "userPassword1"}
 132             };
 133 
 134             // Try to connect to the server using the invalid credentials.
 135             // All the connect calls should get SecurityException.
 136             //
 137             for (int i = 0 ; i < invalidCreds.length ; i++) {
 138                 // Client environment map
 139                 //
 140                 System.out.println(">>> Initialize the client environment map" +
 141                                    " for user [" +
 142                                    invalidCreds[i][0] +
 143                                    "] with password [" +
 144                                    invalidCreds[i][1] + "]");
 145                 HashMap cEnv = new HashMap();
 146                 cEnv.put("jmx.remote.credentials", invalidCreds[i]);
 147 
 148                 // Create an RMI connector client and
 149                 // connect it to the RMI connector server
 150                 //
 151                 System.out.println("Create an RMI connector client and " +
 152                                    "connect it to the RMI connector server");
 153                 try {
 154                     JMXConnector jmxc =
 155                         JMXConnectorFactory.connect(cs.getAddress(), cEnv);
 156                 } catch (SecurityException e) {
 157                     System.out.println("Got expected security exception: " + e);
 158                 } catch (Exception e) {
 159                     System.out.println("Got unexpected exception: " + e);
 160                     e.printStackTrace();
 161                     System.exit(1);
 162                 }
 163             }
 164 
 165             //------------------------------------------------------------------
 166             // CLIENT (admin)
 167             //------------------------------------------------------------------
 168 
 169             // Admin client environment map
 170             //
 171             String[] adminCreds = new String[] { "admin" , "adminPassword" };
 172             System.out.println(">>> Initialize the client environment map for" +
 173                                " user [" + adminCreds[0] + "] with " +
 174                                "password [" + adminCreds[1] + "]");
 175             HashMap adminEnv = new HashMap();
 176             adminEnv.put("jmx.remote.credentials", adminCreds);
 177 
 178             // Create an RMI connector client and
 179             // connect it to the RMI connector server
 180             //
 181             System.out.println("Create an RMI connector client and " +
 182                                "connect it to the RMI connector server");
 183             JMXConnector adminConnector =
 184                 JMXConnectorFactory.connect(cs.getAddress(), adminEnv);
 185 
 186             // Get an MBeanServerConnection
 187             //
 188             System.out.println("Get an MBeanServerConnection");
 189             MBeanServerConnection adminConnection =
 190                 adminConnector.getMBeanServerConnection();
 191 
 192             // Get the proxy for the Simple MBean
 193             //
 194             SimpleStandardMBean adminProxy = (SimpleStandardMBean)
 195                 MBeanServerInvocationHandler.newProxyInstance(
 196                                              adminConnection,
 197                                              mbeanName,
 198                                              SimpleStandardMBean.class,
 199                                              false);
 200 
 201             // Get State attribute
 202             //
 203             System.out.println("State = " + adminProxy.getState());
 204 
 205             // Set State attribute
 206             //
 207             adminProxy.setState("changed state");
 208 
 209             // Get State attribute
 210             //
 211             System.out.println("State = " + adminProxy.getState());
 212 
 213             // Invoke "reset" in SimpleStandard MBean
 214             //
 215             System.out.println("Invoke reset() in SimpleStandard MBean...");
 216             adminProxy.reset();
 217 
 218             // Close MBeanServer connection
 219             //
 220             System.out.println("Close the admin connection to the server");
 221             adminConnector.close();
 222 
 223             //------------------------------------------------------------------
 224             // CLIENT (user)
 225             //------------------------------------------------------------------
 226 
 227             // User client environment map
 228             //
 229             String[] userCreds = new String[] { "user" , "userPassword" };
 230             System.out.println(">>> Initialize the client environment map for" +
 231                                " user [" + userCreds[0] + "] with " +
 232                                "password [" + userCreds[1] + "]");
 233             HashMap userEnv = new HashMap();
 234             userEnv.put("jmx.remote.credentials", userCreds);
 235 
 236             // Create an RMI connector client and
 237             // connect it to the RMI connector server
 238             //
 239             System.out.println("Create an RMI connector client and " +
 240                                "connect it to the RMI connector server");
 241             JMXConnector userConnector =
 242                 JMXConnectorFactory.connect(cs.getAddress(), userEnv);
 243 
 244             // Get an MBeanServerConnection
 245             //
 246             System.out.println("Get an MBeanServerConnection");
 247             MBeanServerConnection userConnection =
 248                 userConnector.getMBeanServerConnection();
 249 
 250             // Get the proxy for the Simple MBean
 251             //
 252             SimpleStandardMBean userProxy = (SimpleStandardMBean)
 253                 MBeanServerInvocationHandler.newProxyInstance(
 254                                              userConnection,
 255                                              mbeanName,
 256                                              SimpleStandardMBean.class,
 257                                              false);
 258 
 259             // Get State attribute
 260             //
 261             System.out.println("State = " + userProxy.getState());
 262 
 263             // Set State attribute
 264             //
 265             try {
 266                 userProxy.setState("changed state");
 267             } catch (SecurityException e) {
 268                 System.out.println("Got expected security exception: " + e);
 269             } catch (Exception e) {
 270                 System.out.println("Got unexpected exception: " + e);
 271                 e.printStackTrace();
 272                 System.exit(1);
 273             }
 274 
 275             // Get State attribute
 276             //
 277             System.out.println("State = " + userProxy.getState());
 278 
 279             // Invoke "reset" in SimpleStandard MBean
 280             //
 281             try {
 282                 System.out.println("Invoke reset() in SimpleStandard MBean...");
 283                 userProxy.reset();
 284             } catch (SecurityException e) {
 285                 System.out.println("Got expected security exception: " + e);
 286             } catch (Exception e) {
 287                 System.out.println("Got unexpected exception: " + e);
 288                 e.printStackTrace();
 289                 System.exit(1);
 290             }
 291 
 292             // Close MBeanServer connection
 293             //
 294             System.out.println("Close the user connection to the server");
 295             userConnector.close();
 296 
 297             //------------------------------------------------------------------
 298             // SERVER
 299             //------------------------------------------------------------------
 300 
 301             // Stop the connector server
 302             //
 303             System.out.println(">>> Stop the connector server");
 304             cs.stop();
 305 
 306             System.out.println("Bye! Bye!");
 307         } catch (Exception e) {
 308             System.out.println("Got unexpected exception: " + e);
 309             e.printStackTrace();
 310             System.exit(1);
 311         }
 312     }
 313 }