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