Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java
38867 views
1
/*
2
* Copyright (c) 2005, 2014, 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 5106721
27
* @summary Check the NotificationAccessController methods are properly called.
28
* @author Luis-Miguel Alventosa
29
* @run clean NotificationAccessControllerTest
30
* @run build NotificationAccessControllerTest
31
* @run main NotificationAccessControllerTest
32
*/
33
34
import com.sun.jmx.remote.security.NotificationAccessController;
35
import java.util.ArrayList;
36
import java.util.Collections;
37
import java.util.HashMap;
38
import java.util.List;
39
import java.util.Map;
40
import java.util.concurrent.CopyOnWriteArrayList;
41
import java.util.concurrent.Semaphore;
42
import javax.management.MBeanServer;
43
import javax.management.MBeanServerConnection;
44
import javax.management.MBeanServerFactory;
45
import javax.management.Notification;
46
import javax.management.NotificationBroadcasterSupport;
47
import javax.management.NotificationListener;
48
import javax.management.ObjectName;
49
import javax.management.remote.JMXAuthenticator;
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.JMXPrincipal;
55
import javax.management.remote.JMXServiceURL;
56
import javax.security.auth.Subject;
57
58
public class NotificationAccessControllerTest {
59
60
public class NAC implements NotificationAccessController {
61
private final boolean throwException;
62
public NAC(boolean throwException) {
63
this.throwException = throwException;
64
}
65
66
@Override
67
public void addNotificationListener(
68
String connectionId,
69
ObjectName name,
70
Subject subject)
71
throws SecurityException {
72
echo("addNotificationListener:");
73
echo("\tconnectionId: " + connectionId);
74
echo("\tname: " + name);
75
echo("\tsubject: " +
76
(subject == null ? null : subject.getPrincipals()));
77
if (throwException)
78
if (name.getCanonicalName().equals("domain:name=1,type=NB")
79
&&
80
subject != null
81
&&
82
subject.getPrincipals().contains(new JMXPrincipal("role")))
83
throw new SecurityException();
84
}
85
86
@Override
87
public void removeNotificationListener(
88
String connectionId,
89
ObjectName name,
90
Subject subject)
91
throws SecurityException {
92
echo("removeNotificationListener:");
93
echo("\tconnectionId: " + connectionId);
94
echo("\tname: " + name);
95
echo("\tsubject: " +
96
(subject == null ? null : subject.getPrincipals()));
97
if (throwException)
98
if (name.getCanonicalName().equals("domain:name=2,type=NB")
99
&&
100
subject != null
101
&&
102
subject.getPrincipals().contains(new JMXPrincipal("role")))
103
throw new SecurityException();
104
}
105
106
@Override
107
public void fetchNotification(
108
String connectionId,
109
ObjectName name,
110
Notification notification,
111
Subject subject)
112
throws SecurityException {
113
echo("fetchNotification:");
114
echo("\tconnectionId: " + connectionId);
115
echo("\tname: " + name);
116
echo("\tnotification: " + notification);
117
echo("\tsubject: " +
118
(subject == null ? null : subject.getPrincipals()));
119
if (!throwException)
120
if (name.getCanonicalName().equals("domain:name=2,type=NB")
121
&&
122
subject != null
123
&&
124
subject.getPrincipals().contains(new JMXPrincipal("role")))
125
throw new SecurityException();
126
}
127
}
128
129
public class CustomJMXAuthenticator implements JMXAuthenticator {
130
@Override
131
public Subject authenticate(Object credentials) {
132
String role = ((String[]) credentials)[0];
133
echo("\nCreate principal with name = " + role);
134
return new Subject(true,
135
Collections.singleton(new JMXPrincipal(role)),
136
Collections.EMPTY_SET,
137
Collections.EMPTY_SET);
138
}
139
}
140
141
public interface NBMBean {
142
public void emitNotification(int seqnum, ObjectName name);
143
}
144
145
public static class NB
146
extends NotificationBroadcasterSupport
147
implements NBMBean {
148
@Override
149
public void emitNotification(int seqnum, ObjectName name) {
150
if (name == null) {
151
sendNotification(new Notification("nb", this, seqnum));
152
} else {
153
sendNotification(new Notification("nb", name, seqnum));
154
}
155
}
156
}
157
158
public class Listener implements NotificationListener {
159
public final List<Notification> notifs = new CopyOnWriteArrayList<>();
160
161
private final Semaphore s;
162
public Listener(Semaphore s) {
163
this.s = s;
164
}
165
@Override
166
public void handleNotification(Notification n, Object h) {
167
echo("handleNotification:");
168
echo("\tNotification = " + n);
169
echo("\tNotification.SeqNum = " + n.getSequenceNumber());
170
echo("\tHandback = " + h);
171
notifs.add(n);
172
s.release();
173
}
174
}
175
176
/**
177
* Check received notifications
178
*/
179
public int checkNotifs(int size,
180
List<Notification> received,
181
List<ObjectName> expected) {
182
if (received.size() != size) {
183
echo("Error: expecting " + size + " notifications, got " +
184
received.size());
185
return 1;
186
} else {
187
for (Notification n : received) {
188
echo("Received notification: " + n);
189
if (!n.getType().equals("nb")) {
190
echo("Notification type must be \"nb\"");
191
return 1;
192
}
193
ObjectName o = (ObjectName) n.getSource();
194
int index = (int) n.getSequenceNumber();
195
ObjectName nb = expected.get(index);
196
if (!o.equals(nb)) {
197
echo("Notification source must be " + nb);
198
return 1;
199
}
200
}
201
}
202
return 0;
203
}
204
205
/**
206
* Run test
207
*/
208
public int runTest(boolean enableChecks, boolean throwException)
209
throws Exception {
210
211
echo("\n=-=-= " + (enableChecks ? "Enable" : "Disable") +
212
" notification access control checks " +
213
(!enableChecks ? "" : (throwException ? ": add/remove " :
214
": fetch ")) + "=-=-=");
215
216
JMXConnectorServer server = null;
217
JMXConnector client = null;
218
219
/*
220
* (!enableChecks)
221
* - List must contain three notifs from sources nb1, nb2 and nb3
222
* (enableChecks && !throwException)
223
* - List must contain one notif from source nb1
224
* (enableChecks && throwException)
225
* - List must contain two notifs from sources nb2 and nb3
226
*/
227
final int expected_notifs =
228
(!enableChecks ? 3 : (throwException ? 2 : 1));
229
230
// Create a new MBeanServer
231
//
232
final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
233
234
try {
235
// Create server environment map
236
//
237
final Map<String,Object> env = new HashMap<>();
238
env.put("jmx.remote.authenticator", new CustomJMXAuthenticator());
239
if (enableChecks) {
240
env.put("com.sun.jmx.remote.notification.access.controller",
241
new NAC(throwException));
242
}
243
244
// Create the JMXServiceURL
245
//
246
final JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
247
248
// Create a JMXConnectorServer
249
//
250
server = JMXConnectorServerFactory.newJMXConnectorServer(url,
251
env,
252
mbs);
253
254
// Start the JMXConnectorServer
255
//
256
server.start();
257
258
// Create server environment map
259
//
260
final Map<String,Object> cenv = new HashMap<>();
261
String[] credentials = new String[] { "role" , "password" };
262
cenv.put("jmx.remote.credentials", credentials);
263
264
// Create JMXConnector and connect to JMXConnectorServer
265
//
266
client = JMXConnectorFactory.connect(server.getAddress(), cenv);
267
268
// Get non-secure MBeanServerConnection
269
//
270
final MBeanServerConnection mbsc =
271
client.getMBeanServerConnection();
272
273
// Create NB MBean
274
//
275
ObjectName nb1 = ObjectName.getInstance("domain:type=NB,name=1");
276
ObjectName nb2 = ObjectName.getInstance("domain:type=NB,name=2");
277
ObjectName nb3 = ObjectName.getInstance("domain:type=NB,name=3");
278
mbsc.createMBean(NB.class.getName(), nb1);
279
mbsc.createMBean(NB.class.getName(), nb2);
280
mbsc.createMBean(NB.class.getName(), nb3);
281
282
// Add notification listener
283
//
284
Semaphore s = new Semaphore(0);
285
286
Listener li = new Listener(s);
287
try {
288
mbsc.addNotificationListener(nb1, li, null, null);
289
if (enableChecks && throwException) {
290
echo("Didn't get expected exception");
291
return 1;
292
}
293
} catch (SecurityException e) {
294
if (enableChecks && throwException) {
295
echo("Got expected exception: " + e);
296
} else {
297
echo("Got unexpected exception: " + e);
298
return 1;
299
}
300
}
301
mbsc.addNotificationListener(nb2, li, null, null);
302
303
System.out.println("\n+++ Expecting to receive " + expected_notifs +
304
" notification" + (expected_notifs > 1 ? "s" : "") +
305
" +++");
306
// Invoke the "sendNotification" method
307
//
308
mbsc.invoke(nb1, "emitNotification",
309
new Object[] {0, null},
310
new String[] {"int", "javax.management.ObjectName"});
311
mbsc.invoke(nb2, "emitNotification",
312
new Object[] {1, null},
313
new String[] {"int", "javax.management.ObjectName"});
314
mbsc.invoke(nb2, "emitNotification",
315
new Object[] {2, nb3},
316
new String[] {"int", "javax.management.ObjectName"});
317
318
// Wait for notifications to be emitted
319
//
320
s.acquire(expected_notifs);
321
322
// Remove notification listener
323
//
324
if (!throwException)
325
mbsc.removeNotificationListener(nb1, li);
326
try {
327
mbsc.removeNotificationListener(nb2, li);
328
if (enableChecks && throwException) {
329
echo("Didn't get expected exception");
330
return 1;
331
}
332
} catch (SecurityException e) {
333
if (enableChecks && throwException) {
334
echo("Got expected exception: " + e);
335
} else {
336
echo("Got unexpected exception: " + e);
337
return 1;
338
}
339
}
340
341
int result = 0;
342
List<ObjectName> sources = new ArrayList();
343
sources.add(nb1);
344
sources.add(nb2);
345
sources.add(nb3);
346
result = checkNotifs(expected_notifs, li.notifs, sources);
347
if (result > 0) {
348
return result;
349
}
350
} catch (Exception e) {
351
echo("Failed to perform operation: " + e);
352
e.printStackTrace();
353
return 1;
354
} finally {
355
// Close the connection
356
//
357
if (client != null)
358
client.close();
359
360
// Stop the connector server
361
//
362
if (server != null)
363
server.stop();
364
365
// Release the MBeanServer
366
//
367
if (mbs != null)
368
MBeanServerFactory.releaseMBeanServer(mbs);
369
}
370
371
return 0;
372
}
373
374
/*
375
* Print message
376
*/
377
private static void echo(String message) {
378
System.out.println(message);
379
}
380
381
public static void main(String[] args) throws Exception {
382
383
System.out.println("\nTest notification access control.");
384
385
NotificationAccessControllerTest nact =
386
new NotificationAccessControllerTest();
387
388
int error = 0;
389
390
error += nact.runTest(false, false);
391
392
error += nact.runTest(true, false);
393
394
error += nact.runTest(true, true);
395
396
if (error > 0) {
397
final String msg = "\nTest FAILED! Got " + error + " error(s)";
398
System.out.println(msg);
399
throw new IllegalArgumentException(msg);
400
} else {
401
System.out.println("\nTest PASSED!");
402
}
403
}
404
}
405
406