1 /*
   2  * Copyright (c) 2003, 2015, 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  * @modules java.management.rmi
  31  * @run clean PasswordAccessFileTest SimpleStandard SimpleStandardMBean
  32  * @run build PasswordAccessFileTest SimpleStandard SimpleStandardMBean
  33  * @run main PasswordAccessFileTest
  34  */
  35 
  36 import java.io.File;
  37 import java.util.HashMap;
  38 import javax.management.Attribute;
  39 import javax.management.MBeanServer;
  40 import javax.management.MBeanServerConnection;
  41 import javax.management.MBeanServerFactory;
  42 import javax.management.MBeanServerInvocationHandler;
  43 import javax.management.Notification;
  44 import javax.management.NotificationListener;
  45 import javax.management.ObjectName;
  46 import javax.management.remote.JMXConnector;
  47 import javax.management.remote.JMXConnectorFactory;
  48 import javax.management.remote.JMXConnectorServer;
  49 import javax.management.remote.JMXConnectorServerFactory;
  50 import javax.management.remote.JMXServiceURL;
  51 
  52 public class PasswordAccessFileTest {
  53 
  54     public static void main(String[] args) {
  55         try {
  56             //------------------------------------------------------------------
  57             // SERVER
  58             //------------------------------------------------------------------
  59 
  60             // Instantiate the MBean server
  61             //
  62             System.out.println("Create the MBean server");
  63             MBeanServer mbs = MBeanServerFactory.createMBeanServer();
  64 
  65             // Create SimpleStandard MBean
  66             //
  67             ObjectName mbeanName = new ObjectName("MBeans:type=SimpleStandard");
  68             System.out.println("Create SimpleStandard MBean...");
  69             mbs.createMBean("SimpleStandard", mbeanName, null, null);
  70 
  71             // Server's environment map
  72             //
  73             System.out.println(">>> Initialize the server's environment map");
  74             HashMap sEnv = new HashMap();
  75 
  76             // Provide the password file used by the connector server to
  77             // perform user authentication. The password file is a properties
  78             // based text file specifying username/password pairs. This
  79             // properties based password authenticator has been implemented
  80             // using the JMXAuthenticator interface and is passed to the
  81             // connector through the "jmx.remote.authenticator" property
  82             // in the map.
  83             //
  84             // This property is implementation-dependent and might not be
  85             // supported by all implementations of the JMX Remote API.
  86             //
  87             sEnv.put("jmx.remote.x.password.file",
  88                      System.getProperty("test.src") +
  89                      File.separator +
  90                      "password.properties");
  91 
  92             // Provide the access level file used by the connector server to
  93             // perform user authorization. The access level file is a properties
  94             // based text file specifying username/access level pairs where
  95             // access level is either "readonly" or "readwrite" access to the
  96             // MBeanServer operations. This properties based access control
  97             // checker has been implemented using the MBeanServerForwarder
  98             // interface which wraps the real MBean server inside an access
  99             // controller MBean server which performs the access control checks
 100             // before forwarding the requests to the real MBean server.
 101             //
 102             // This property is implementation-dependent and might not be
 103             // supported by all implementations of the JMX Remote API.
 104             //
 105             sEnv.put("jmx.remote.x.access.file",
 106                      System.getProperty("test.src") +
 107                      File.separator +
 108                      "access.properties");
 109 
 110             // Create an RMI connector server
 111             //
 112             System.out.println("Create an RMI connector server");
 113             JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
 114             JMXConnectorServer cs =
 115                 JMXConnectorServerFactory.newJMXConnectorServer(url, sEnv, mbs);
 116 
 117             // Start the RMI connector server
 118             //
 119             System.out.println("Start the RMI connector server");
 120             cs.start();
 121             System.out.println("RMI connector server successfully started");
 122             System.out.println("Waiting for incoming connections...");
 123 
 124             //------------------------------------------------------------------
 125             // CLIENT : Invalid authentication credentials
 126             //------------------------------------------------------------------
 127 
 128             final String invalidCreds[][] = {
 129                 {"admin1", "adminPassword"},
 130                 {"admin",  "adminPassword1"},
 131                 {"user1",  "userPassword"},
 132                 {"user",   "userPassword1"}
 133             };
 134 
 135             // Try to connect to the server using the invalid credentials.
 136             // All the connect calls should get SecurityException.
 137             //
 138             for (int i = 0 ; i < invalidCreds.length ; i++) {
 139                 // Client environment map
 140                 //
 141                 System.out.println(">>> Initialize the client environment map" +
 142                                    " for user [" +
 143                                    invalidCreds[i][0] +
 144                                    "] with password [" +
 145                                    invalidCreds[i][1] + "]");
 146                 HashMap cEnv = new HashMap();
 147                 cEnv.put("jmx.remote.credentials", invalidCreds[i]);
 148 
 149                 // Create an RMI connector client and
 150                 // connect it to the RMI connector server
 151                 //
 152                 System.out.println("Create an RMI connector client and " +
 153                                    "connect it to the RMI connector server");
 154                 try {
 155                     JMXConnector jmxc =
 156                         JMXConnectorFactory.connect(cs.getAddress(), cEnv);
 157                 } catch (SecurityException e) {
 158                     System.out.println("Got expected security exception: " + e);
 159                 } catch (Exception e) {
 160                     System.out.println("Got unexpected exception: " + e);
 161                     e.printStackTrace();
 162                     System.exit(1);
 163                 }
 164             }
 165 
 166             //------------------------------------------------------------------
 167             // CLIENT (admin)
 168             //------------------------------------------------------------------
 169 
 170             // Admin client environment map
 171             //
 172             String[] adminCreds = new String[] { "admin" , "adminPassword" };
 173             System.out.println(">>> Initialize the client environment map for" +
 174                                " user [" + adminCreds[0] + "] with " +
 175                                "password [" + adminCreds[1] + "]");
 176             HashMap adminEnv = new HashMap();
 177             adminEnv.put("jmx.remote.credentials", adminCreds);
 178 
 179             // Create an RMI connector client and
 180             // connect it to the RMI connector server
 181             //
 182             System.out.println("Create an RMI connector client and " +
 183                                "connect it to the RMI connector server");
 184             JMXConnector adminConnector =
 185                 JMXConnectorFactory.connect(cs.getAddress(), adminEnv);
 186 
 187             // Get an MBeanServerConnection
 188             //
 189             System.out.println("Get an MBeanServerConnection");
 190             MBeanServerConnection adminConnection =
 191                 adminConnector.getMBeanServerConnection();
 192 
 193             // Get the proxy for the Simple MBean
 194             //
 195             SimpleStandardMBean adminProxy = (SimpleStandardMBean)
 196                 MBeanServerInvocationHandler.newProxyInstance(
 197                                              adminConnection,
 198                                              mbeanName,
 199                                              SimpleStandardMBean.class,
 200                                              false);
 201 
 202             // Get State attribute
 203             //
 204             System.out.println("State = " + adminProxy.getState());
 205 
 206             // Set State attribute
 207             //
 208             adminProxy.setState("changed state");
 209 
 210             // Get State attribute
 211             //
 212             System.out.println("State = " + adminProxy.getState());
 213 
 214             // Invoke "reset" in SimpleStandard MBean
 215             //
 216             System.out.println("Invoke reset() in SimpleStandard MBean...");
 217             adminProxy.reset();
 218 
 219             // Close MBeanServer connection
 220             //
 221             System.out.println("Close the admin connection to the server");
 222             adminConnector.close();
 223 
 224             //------------------------------------------------------------------
 225             // CLIENT (user)
 226             //------------------------------------------------------------------
 227 
 228             // User client environment map
 229             //
 230             String[] userCreds = new String[] { "user" , "userPassword" };
 231             System.out.println(">>> Initialize the client environment map for" +
 232                                " user [" + userCreds[0] + "] with " +
 233                                "password [" + userCreds[1] + "]");
 234             HashMap userEnv = new HashMap();
 235             userEnv.put("jmx.remote.credentials", userCreds);
 236 
 237             // Create an RMI connector client and
 238             // connect it to the RMI connector server
 239             //
 240             System.out.println("Create an RMI connector client and " +
 241                                "connect it to the RMI connector server");
 242             JMXConnector userConnector =
 243                 JMXConnectorFactory.connect(cs.getAddress(), userEnv);
 244 
 245             // Get an MBeanServerConnection
 246             //
 247             System.out.println("Get an MBeanServerConnection");
 248             MBeanServerConnection userConnection =
 249                 userConnector.getMBeanServerConnection();
 250 
 251             // Get the proxy for the Simple MBean
 252             //
 253             SimpleStandardMBean userProxy = (SimpleStandardMBean)
 254                 MBeanServerInvocationHandler.newProxyInstance(
 255                                              userConnection,
 256                                              mbeanName,
 257                                              SimpleStandardMBean.class,
 258                                              false);
 259 
 260             // Get State attribute
 261             //
 262             System.out.println("State = " + userProxy.getState());
 263 
 264             // Set State attribute
 265             //
 266             try {
 267                 userProxy.setState("changed state");
 268             } catch (SecurityException e) {
 269                 System.out.println("Got expected security exception: " + e);
 270             } catch (Exception e) {
 271                 System.out.println("Got unexpected exception: " + e);
 272                 e.printStackTrace();
 273                 System.exit(1);
 274             }
 275 
 276             // Get State attribute
 277             //
 278             System.out.println("State = " + userProxy.getState());
 279 
 280             // Invoke "reset" in SimpleStandard MBean
 281             //
 282             try {
 283                 System.out.println("Invoke reset() in SimpleStandard MBean...");
 284                 userProxy.reset();
 285             } catch (SecurityException e) {
 286                 System.out.println("Got expected security exception: " + e);
 287             } catch (Exception e) {
 288                 System.out.println("Got unexpected exception: " + e);
 289                 e.printStackTrace();
 290                 System.exit(1);
 291             }
 292 
 293             // Close MBeanServer connection
 294             //
 295             System.out.println("Close the user connection to the server");
 296             userConnector.close();
 297 
 298             //------------------------------------------------------------------
 299             // SERVER
 300             //------------------------------------------------------------------
 301 
 302             // Stop the connector server
 303             //
 304             System.out.println(">>> Stop the connector server");
 305             cs.stop();
 306 
 307             System.out.println("Bye! Bye!");
 308         } catch (Exception e) {
 309             System.out.println("Got unexpected exception: " + e);
 310             e.printStackTrace();
 311             System.exit(1);
 312         }
 313     }
 314 }