1 /* 2 * Copyright (c) 2017, 2018, 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 /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 142 public static void MultiAllowTest() throws InterruptedException, IOException { 143 String allowOpt = ",allow=127.0.0.1+10.0.0.0/8+172.16.0.0/12+192.168.0.0/24"; 144 positiveTest("MultiAllowTest", allowOpt); 145 } 146 147 public static void DenyTest() throws InterruptedException, IOException { 148 // Bad allow address 149 String allowOpt = ",allow=0.0.0.0"; 150 negativeTest("DenyTest", allowOpt); 151 } 152 153 public static void MultiDenyTest() throws InterruptedException, IOException { 154 // Wrong separator ';' is used for allow option 155 String allowOpt = ",allow=127.0.0.1;192.168.0.0/24"; 156 badAllowOptionTest("MultiDenyTest", allowOpt); 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 }