3789983e89
Reviewed-by: darcy, ihse
201 lines
7.0 KiB
Java
201 lines
7.0 KiB
Java
/*
|
|
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @summary Smoke test for JDWP hardening
|
|
* @library /lib/testlibrary
|
|
* @library /test/lib
|
|
* @run driver BasicJDWPConnectionTest
|
|
*/
|
|
|
|
import java.io.IOException;
|
|
import java.io.BufferedReader;
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.net.Socket;
|
|
import java.net.SocketException;
|
|
|
|
import jdk.test.lib.apps.LingeredApp;
|
|
import jdk.testlibrary.Utils;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
|
|
public class BasicJDWPConnectionTest {
|
|
|
|
public static int handshake(int port) throws IOException {
|
|
// Connect to the debuggee and handshake
|
|
int res = -1;
|
|
Socket s = null;
|
|
try {
|
|
s = new Socket("localhost", port);
|
|
s.getOutputStream().write("JDWP-Handshake".getBytes("UTF-8"));
|
|
byte[] buffer = new byte[24];
|
|
res = s.getInputStream().read(buffer);
|
|
}
|
|
catch (SocketException ex) {
|
|
// pass
|
|
} finally {
|
|
if (s != null) {
|
|
s.close();
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
public static ArrayList<String> prepareCmd(int port, String allowOpt) {
|
|
String address = "*:" + String.valueOf(port);
|
|
ArrayList<String> cmd = new ArrayList<>();
|
|
|
|
String jdwpArgs = "-agentlib:jdwp=transport=dt_socket,server=y," +
|
|
"suspend=n,address=" + address + allowOpt;
|
|
cmd.add(jdwpArgs);
|
|
return cmd;
|
|
}
|
|
|
|
public static void positiveTest(String testName, String allowOpt)
|
|
throws InterruptedException, IOException {
|
|
System.err.println("\nStarting " + testName);
|
|
int port = Utils.getFreePort();
|
|
ArrayList<String> cmd = prepareCmd(port, allowOpt);
|
|
|
|
LingeredApp a = LingeredApp.startApp(cmd);
|
|
int res = handshake(port);
|
|
a.stopApp();
|
|
if (res < 0) {
|
|
throw new RuntimeException(testName + " FAILED");
|
|
}
|
|
System.err.println(testName + " PASSED");
|
|
}
|
|
|
|
public static void negativeTest(String testName, String allowOpt)
|
|
throws InterruptedException, IOException {
|
|
System.err.println("\nStarting " + testName);
|
|
int port = Utils.getFreePort();
|
|
ArrayList<String> cmd = prepareCmd(port, allowOpt);
|
|
|
|
LingeredApp a = LingeredApp.startApp(cmd);
|
|
int res = handshake(port);
|
|
a.stopApp();
|
|
if (res > 0) {
|
|
System.err.println(testName + ": res=" + res);
|
|
throw new RuntimeException(testName + " FAILED");
|
|
}
|
|
System.err.println(testName + ": returned a negative code as expected: " + res);
|
|
System.err.println(testName + " PASSED");
|
|
}
|
|
|
|
public static void badAllowOptionTest(String testName, String allowOpt)
|
|
throws InterruptedException, IOException {
|
|
System.err.println("\nStarting " + testName);
|
|
int port = Utils.getFreePort();
|
|
ArrayList<String> cmd = prepareCmd(port, allowOpt);
|
|
|
|
try {
|
|
LingeredApp a = LingeredApp.startApp(cmd);
|
|
} catch (IOException ex) {
|
|
System.err.println(testName + ": caught expected IOException");
|
|
System.err.println(testName + " PASSED");
|
|
return;
|
|
}
|
|
throw new RuntimeException(testName + " FAILED");
|
|
}
|
|
|
|
public static void DefaultTest() throws InterruptedException, IOException {
|
|
// No allow option is the same as the allow option ',allow=*' is passed
|
|
String allowOpt = "";
|
|
positiveTest("DefaultTest", allowOpt);
|
|
}
|
|
|
|
static void ExplicitDefaultTest() throws InterruptedException, IOException {
|
|
// Explicit permission for connections from everywhere
|
|
String allowOpt = ",allow=*";
|
|
positiveTest("ExplicitDefaultTest" ,allowOpt);
|
|
}
|
|
|
|
public static void AllowTest() throws InterruptedException, IOException {
|
|
String allowOpt = ",allow=127.0.0.1";
|
|
positiveTest("AllowTest", allowOpt);
|
|
}
|
|
|
|
public static void MultiAllowTest() throws InterruptedException, IOException {
|
|
String allowOpt = ",allow=127.0.0.1+10.0.0.0/8+172.16.0.0/12+192.168.0.0/24";
|
|
positiveTest("MultiAllowTest", allowOpt);
|
|
}
|
|
|
|
public static void DenyTest() throws InterruptedException, IOException {
|
|
// Bad allow address
|
|
String allowOpt = ",allow=0.0.0.0";
|
|
negativeTest("DenyTest", allowOpt);
|
|
}
|
|
|
|
public static void MultiDenyTest() throws InterruptedException, IOException {
|
|
// Wrong separator ';' is used for allow option
|
|
String allowOpt = ",allow=127.0.0.1;192.168.0.0/24";
|
|
badAllowOptionTest("MultiDenyTest", allowOpt);
|
|
}
|
|
|
|
public static void EmptyAllowOptionTest() throws InterruptedException, IOException {
|
|
// Empty allow option
|
|
String allowOpt = ",allow=";
|
|
badAllowOptionTest("EmptyAllowOptionTest", allowOpt);
|
|
}
|
|
|
|
public static void ExplicitMultiDefault1Test() throws InterruptedException, IOException {
|
|
// Bad mix of allow option '*' with address value
|
|
String allowOpt = ",allow=*+allow=127.0.0.1";
|
|
badAllowOptionTest("ExplicitMultiDefault1Test", allowOpt);
|
|
}
|
|
|
|
public static void ExplicitMultiDefault2Test() throws InterruptedException, IOException {
|
|
// Bad mix of allow address value with '*'
|
|
String allowOpt = ",allow=allow=127.0.0.1+*";
|
|
badAllowOptionTest("ExplicitMultiDefault2Test", allowOpt);
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
try {
|
|
DefaultTest();
|
|
ExplicitDefaultTest();
|
|
AllowTest();
|
|
MultiAllowTest();
|
|
DenyTest();
|
|
MultiDenyTest();
|
|
EmptyAllowOptionTest();
|
|
ExplicitMultiDefault1Test();
|
|
ExplicitMultiDefault2Test();
|
|
System.err.println("\nTest PASSED");
|
|
} catch (InterruptedException ex) {
|
|
System.err.println("\nTest ERROR, getFreePort");
|
|
ex.printStackTrace();
|
|
System.exit(3);
|
|
} catch (IOException ex) {
|
|
System.err.println("\nTest ERROR");
|
|
ex.printStackTrace();
|
|
System.exit(3);
|
|
}
|
|
}
|
|
}
|