1 /*
2  * Copyright (c) 2004, 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 5016508
27  * @summary Supplies an alternative JAAS configuration for authenticating RMI clients
28  * @author Luis-Miguel Alventosa
29  * @modules java.management.rmi
30  *          java.management/com.sun.jmx.remote.security
31  * @run clean RMIAltAuthTest
32  * @run build RMIAltAuthTest SimpleStandard SimpleStandardMBean
33  * @run main RMIAltAuthTest
34  */
35 
36 import java.io.File;
37 import java.rmi.RemoteException;
38 import java.rmi.registry.Registry;
39 import java.rmi.registry.LocateRegistry;
40 import java.util.HashMap;
41 import java.util.Properties;
42 
43 import javax.management.Attribute;
44 import javax.management.MBeanServer;
45 import javax.management.MBeanServerConnection;
46 import javax.management.MBeanServerFactory;
47 import javax.management.Notification;
48 import javax.management.NotificationListener;
49 import javax.management.ObjectName;
50 import javax.management.remote.JMXConnector;
51 import javax.management.remote.JMXConnectorFactory;
52 import javax.management.remote.JMXConnectorServer;
53 import javax.management.remote.JMXConnectorServerFactory;
54 import javax.management.remote.JMXServiceURL;
55 import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
56 
57 public class RMIAltAuthTest {
58 
main(String[] args)59     public static void main(String[] args) {
60         try {
61 
62             // Override the default JAAS configuration
63             //
64             final String loginConfig = System.getProperty("test.src") +
65                 File.separator + "jmxremote.login";
66             System.out.println("JAAS configuration file = " + loginConfig);
67             System.setProperty("java.security.auth.login.config",
68                 "file:" + loginConfig);
69 
70             // Create an RMI registry
71             //
72             System.out.println("Start RMI registry...");
73             Registry reg = null;
74             int port = 5800;
75             while (port++ < 6000) {
76                 try {
77                     reg = LocateRegistry.createRegistry(port);
78                     System.out.println("RMI registry running on port " + port);
79                     break;
80                 } catch (RemoteException e) {
81                     // Failed to create RMI registry...
82                     System.out.println("Failed to create RMI registry " +
83                                        "on port " + port);
84                 }
85             }
86             if (reg == null) {
87                 System.exit(1);
88             }
89 
90             // Instantiate the MBean server
91             //
92             System.out.println("Create the MBean server");
93             MBeanServer mbs = MBeanServerFactory.createMBeanServer();
94             // Register the ClassPathClassLoaderMBean
95             //
96             System.out.println("Create ClassPathClassLoader MBean");
97             ObjectName cpcl =
98                 new ObjectName("ClassLoader:name=ClassPathClassLoader");
99             mbs.createMBean("javax.management.loading.MLet", cpcl);
100             // Register the SimpleStandardMBean
101             //
102             System.out.println("Create SimpleStandard MBean");
103             mbs.createMBean("SimpleStandard",
104                             new ObjectName("MBeans:name=SimpleStandard"));
105             // Create Properties containing the username/password entries
106             //
107             Properties props = new Properties();
108             props.setProperty("jmx.remote.x.login.config",
109                 "PasswordFileAuthentication");
110             // Initialize environment map to be passed to the connector server
111             //
112             System.out.println("Initialize environment map");
113             HashMap env = new HashMap();
114             env.put("jmx.remote.authenticator",
115                     new JMXPluggableAuthenticator(props));
116             // Create an RMI connector server
117             //
118             System.out.println("Create an RMI connector server");
119             JMXServiceURL url =
120                 new JMXServiceURL("rmi", null, 0,
121                                   "/jndi/rmi://:" + port + "/server" + port);
122             JMXConnectorServer rcs =
123                 JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
124             rcs.start();
125 
126             // Create an RMI connector client
127             //
128             System.out.println("Create an RMI connector client");
129             HashMap cli_env = new HashMap();
130             // These credentials must match those in the supplied password file
131             //
132             String[] credentials = new String[] { "monitorRole" , "pwd1" };
133             cli_env.put("jmx.remote.credentials", credentials);
134             JMXConnector jmxc = JMXConnectorFactory.connect(url, cli_env);
135             MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
136             // Get domains from MBeanServer
137             //
138             System.out.println("Domains:");
139             String domains[] = mbsc.getDomains();
140             for (int i = 0; i < domains.length; i++) {
141                 System.out.println("\tDomain[" + i + "] = " + domains[i]);
142             }
143             // Get MBean count
144             //
145             System.out.println("MBean count = " + mbsc.getMBeanCount());
146             // Get State attribute
147             //
148             String oldState =
149                 (String) mbsc.getAttribute(
150                               new ObjectName("MBeans:name=SimpleStandard"),
151                               "State");
152             System.out.println("Old State = \"" + oldState + "\"");
153             // Set State attribute
154             //
155             System.out.println("Set State to \"changed state\"");
156             mbsc.setAttribute(new ObjectName("MBeans:name=SimpleStandard"),
157                               new Attribute("State", "changed state"));
158             // Get State attribute
159             //
160             String newState =
161                 (String) mbsc.getAttribute(
162                               new ObjectName("MBeans:name=SimpleStandard"),
163                               "State");
164             System.out.println("New State = \"" + newState + "\"");
165             if (!newState.equals("changed state")) {
166                 System.out.println("Invalid State = \"" + newState + "\"");
167                 System.exit(1);
168             }
169             // Add notification listener on SimpleStandard MBean
170             //
171             System.out.println("Add notification listener...");
172             mbsc.addNotificationListener(
173                  new ObjectName("MBeans:name=SimpleStandard"),
174                  new NotificationListener() {
175                      public void handleNotification(Notification notification,
176                                                     Object handback) {
177                          System.out.println("Received notification: " +
178                                             notification);
179                      }
180                  },
181                  null,
182                  null);
183             // Unregister SimpleStandard MBean
184             //
185             System.out.println("Unregister SimpleStandard MBean...");
186             mbsc.unregisterMBean(new ObjectName("MBeans:name=SimpleStandard"));
187             // Close MBeanServer connection
188             //
189             jmxc.close();
190             System.out.println("Bye! Bye!");
191         } catch (Exception e) {
192             System.out.println("Unexpected exception caught = " + e);
193             e.printStackTrace();
194             System.exit(1);
195         }
196     }
197 }
198