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