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 * @summary Smoke test for JDWP hardening
27 * @library /test/lib
28 * @run driver BasicJDWPConnectionTest
29 */
30
31 import java.io.IOException;
32 import java.io.BufferedReader;
33 import java.io.InputStreamReader;
34
35 import java.net.Socket;
36 import java.net.SocketException;
37
38 import jdk.test.lib.apps.LingeredApp;
39 import jdk.test.lib.Utils;
40
41 import java.util.ArrayList;
42 import java.util.List;
43
44
45 public class BasicJDWPConnectionTest {
46
47 public static int handshake(int port) throws IOException {
48 // Connect to the debuggee and handshake
49 int res = -1;
50 Socket s = null;
51 try {
52 s = new Socket("localhost", port);
53 s.getOutputStream().write("JDWP-Handshake".getBytes("UTF-8"));
54 byte[] buffer = new byte[24];
55 res = s.getInputStream().read(buffer);
56 }
57 catch (SocketException ex) {
58 // pass
59 } finally {
60 if (s != null) {
61 s.close();
62 }
63 }
64 return res;
65 }
66
67 public static ArrayList<String> prepareCmd(int port, String allowOpt) {
68 String address = "*:" + String.valueOf(port);
69 ArrayList<String> cmd = new ArrayList<>();
70
71 String jdwpArgs = "-agentlib:jdwp=transport=dt_socket,server=y," +
72 "suspend=n,address=" + address + allowOpt;
73 cmd.add(jdwpArgs);
74 return cmd;
75 }
76
77 public static void positiveTest(String testName, String allowOpt)
78 throws InterruptedException, IOException {
79 System.err.println("\nStarting " + testName);
80 int port = Utils.getFreePort();
81 ArrayList<String> cmd = prepareCmd(port, allowOpt);
82
83 LingeredApp a = LingeredApp.startApp(cmd);
84 int res = handshake(port);
85 a.stopApp();
86 if (res < 0) {
87 throw new RuntimeException(testName + " FAILED");
88 }
89 System.err.println(testName + " PASSED");
90 }
91
92 public static void negativeTest(String testName, String allowOpt)
93 throws InterruptedException, IOException {
94 System.err.println("\nStarting " + testName);
95 int port = Utils.getFreePort();
96 ArrayList<String> cmd = prepareCmd(port, allowOpt);
97
98 LingeredApp a = LingeredApp.startApp(cmd);
99 int res = handshake(port);
100 a.stopApp();
101 if (res > 0) {
102 System.err.println(testName + ": res=" + res);
103 throw new RuntimeException(testName + " FAILED");
104 }
105 System.err.println(testName + ": returned a negative code as expected: " + res);
106 System.err.println(testName + " PASSED");
107 }
108
109 public static void badAllowOptionTest(String testName, String allowOpt)
110 throws InterruptedException, IOException {
111 System.err.println("\nStarting " + testName);
112 int port = Utils.getFreePort();
113 ArrayList<String> cmd = prepareCmd(port, allowOpt);
114
115 try {
116 LingeredApp a = LingeredApp.startApp(cmd);
117 } catch (IOException ex) {
118 System.err.println(testName + ": caught expected IOException");
119 System.err.println(testName + " PASSED");
120 return;
121 }
122 throw new RuntimeException(testName + " FAILED");
123 }
124
125 public static void DefaultTest() throws InterruptedException, IOException {
126 // No allow option is the same as the allow option ',allow=*' is passed
127 String allowOpt = "";
128 positiveTest("DefaultTest", allowOpt);
129 }
130
131 static void ExplicitDefaultTest() throws InterruptedException, IOException {
132 // Explicit permission for connections from everywhere
133 String allowOpt = ",allow=*";
134 positiveTest("ExplicitDefaultTest" ,allowOpt);
135 }
136
137 public static void AllowTest() throws InterruptedException, IOException {
138 String allowOpt = ",allow=127.0.0.1";
139 positiveTest("AllowTest", allowOpt);
140 }
141
157 }
158
159 public static void EmptyAllowOptionTest() throws InterruptedException, IOException {
160 // Empty allow option
161 String allowOpt = ",allow=";
162 badAllowOptionTest("EmptyAllowOptionTest", allowOpt);
163 }
164
165 public static void ExplicitMultiDefault1Test() throws InterruptedException, IOException {
166 // Bad mix of allow option '*' with address value
167 String allowOpt = ",allow=*+allow=127.0.0.1";
168 badAllowOptionTest("ExplicitMultiDefault1Test", allowOpt);
169 }
170
171 public static void ExplicitMultiDefault2Test() throws InterruptedException, IOException {
172 // Bad mix of allow address value with '*'
173 String allowOpt = ",allow=allow=127.0.0.1+*";
174 badAllowOptionTest("ExplicitMultiDefault2Test", allowOpt);
175 }
176
177 public static void main(String[] args) {
178 try {
179 DefaultTest();
180 ExplicitDefaultTest();
181 AllowTest();
182 MultiAllowTest();
183 DenyTest();
184 MultiDenyTest();
185 EmptyAllowOptionTest();
186 ExplicitMultiDefault1Test();
187 ExplicitMultiDefault2Test();
188 System.err.println("\nTest PASSED");
189 } catch (InterruptedException ex) {
190 System.err.println("\nTest ERROR, getFreePort");
191 ex.printStackTrace();
192 System.exit(3);
193 } catch (IOException ex) {
194 System.err.println("\nTest ERROR");
195 ex.printStackTrace();
196 System.exit(3);
197 }
198 }
199 }
|
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 * @summary Smoke test for JDWP hardening
27 * @library /test/lib
28 * @run driver BasicJDWPConnectionTest
29 */
30
31 import java.io.IOException;
32
33 import java.net.Socket;
34 import java.net.SocketException;
35
36 import jdk.test.lib.apps.LingeredApp;
37
38 import java.util.ArrayList;
39 import java.util.regex.Matcher;
40 import java.util.regex.Pattern;
41
42
43 public class BasicJDWPConnectionTest {
44
45 public static int handshake(int port) throws IOException {
46 // Connect to the debuggee and handshake
47 int res = -1;
48 Socket s = null;
49 try {
50 s = new Socket("localhost", port);
51 s.getOutputStream().write("JDWP-Handshake".getBytes("UTF-8"));
52 byte[] buffer = new byte[24];
53 res = s.getInputStream().read(buffer);
54 }
55 catch (SocketException ex) {
56 // pass
57 } finally {
58 if (s != null) {
59 s.close();
60 }
61 }
62 return res;
63 }
64
65 public static ArrayList<String> prepareCmd(String allowOpt) {
66 ArrayList<String> cmd = new ArrayList<>();
67
68 String jdwpArgs = "-agentlib:jdwp=transport=dt_socket,server=y," +
69 "suspend=n,address=*:0" + allowOpt;
70 cmd.add(jdwpArgs);
71 return cmd;
72 }
73
74 private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(\\d+)\\b");
75 private static int detectPort(String s) {
76 Matcher m = listenRegexp.matcher(s);
77 if (!m.find()) {
78 throw new RuntimeException("Could not detect port from '" + s + "'");
79 }
80 // m.group(1) is transport, m.group(2) is port
81 return Integer.parseInt(m.group(2));
82 }
83
84 public static void positiveTest(String testName, String allowOpt)
85 throws InterruptedException, IOException {
86 System.err.println("\nStarting " + testName);
87 ArrayList<String> cmd = prepareCmd(allowOpt);
88
89 LingeredApp a = LingeredApp.startApp(cmd);
90 int res;
91 try {
92 res = handshake(detectPort(a.getProcessStdout()));
93 } finally {
94 a.stopApp();
95 }
96 if (res < 0) {
97 throw new RuntimeException(testName + " FAILED");
98 }
99 System.err.println(testName + " PASSED");
100 }
101
102 public static void negativeTest(String testName, String allowOpt)
103 throws InterruptedException, IOException {
104 System.err.println("\nStarting " + testName);
105 ArrayList<String> cmd = prepareCmd(allowOpt);
106
107 LingeredApp a = LingeredApp.startApp(cmd);
108 int res;
109 try {
110 res = handshake(detectPort(a.getProcessStdout()));
111 } finally {
112 a.stopApp();
113 }
114 if (res > 0) {
115 System.err.println(testName + ": res=" + res);
116 throw new RuntimeException(testName + " FAILED");
117 }
118 System.err.println(testName + ": returned a negative code as expected: " + res);
119 System.err.println(testName + " PASSED");
120 }
121
122 public static void badAllowOptionTest(String testName, String allowOpt)
123 throws InterruptedException, IOException {
124 System.err.println("\nStarting " + testName);
125 ArrayList<String> cmd = prepareCmd(allowOpt);
126
127 LingeredApp a;
128 try {
129 a = LingeredApp.startApp(cmd);
130 } catch (IOException ex) {
131 System.err.println(testName + ": caught expected IOException");
132 System.err.println(testName + " PASSED");
133 return;
134 }
135 // LingeredApp.startApp is expected to fail, but if not, terminate the app
136 a.stopApp();
137 throw new RuntimeException(testName + " FAILED");
138 }
139
140 public static void DefaultTest() throws InterruptedException, IOException {
141 // No allow option is the same as the allow option ',allow=*' is passed
142 String allowOpt = "";
143 positiveTest("DefaultTest", allowOpt);
144 }
145
146 static void ExplicitDefaultTest() throws InterruptedException, IOException {
147 // Explicit permission for connections from everywhere
148 String allowOpt = ",allow=*";
149 positiveTest("ExplicitDefaultTest" ,allowOpt);
150 }
151
152 public static void AllowTest() throws InterruptedException, IOException {
153 String allowOpt = ",allow=127.0.0.1";
154 positiveTest("AllowTest", allowOpt);
155 }
156
172 }
173
174 public static void EmptyAllowOptionTest() throws InterruptedException, IOException {
175 // Empty allow option
176 String allowOpt = ",allow=";
177 badAllowOptionTest("EmptyAllowOptionTest", allowOpt);
178 }
179
180 public static void ExplicitMultiDefault1Test() throws InterruptedException, IOException {
181 // Bad mix of allow option '*' with address value
182 String allowOpt = ",allow=*+allow=127.0.0.1";
183 badAllowOptionTest("ExplicitMultiDefault1Test", allowOpt);
184 }
185
186 public static void ExplicitMultiDefault2Test() throws InterruptedException, IOException {
187 // Bad mix of allow address value with '*'
188 String allowOpt = ",allow=allow=127.0.0.1+*";
189 badAllowOptionTest("ExplicitMultiDefault2Test", allowOpt);
190 }
191
192 public static void main(String[] args) throws Exception {
193 DefaultTest();
194 ExplicitDefaultTest();
195 AllowTest();
196 MultiAllowTest();
197 DenyTest();
198 MultiDenyTest();
199 EmptyAllowOptionTest();
200 ExplicitMultiDefault1Test();
201 ExplicitMultiDefault2Test();
202 System.err.println("\nTest PASSED");
203 }
204 }
|