1 /* 2 * Copyright (c) 2013, 2016, 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 A simple smoke test of the HttpURLPermission mechanism, which checks 27 * for either IOException (due to unknown host) or SecurityException 28 * due to lack of permission to connect 29 * @run main/othervm LookupTest 30 */ 31 32 import java.io.BufferedWriter; 33 import java.io.FilePermission; 34 import java.io.FileWriter; 35 import java.io.IOException; 36 import java.io.InputStream; 37 import java.io.OutputStream; 38 import java.io.PrintWriter; 39 import java.net.NetPermission; 40 import java.net.ProxySelector; 41 import java.net.ServerSocket; 42 import java.net.Socket; 43 import java.net.SocketPermission; 44 import java.net.URL; 45 import java.net.URLConnection; 46 import java.net.URLPermission; 47 import java.security.CodeSource; 48 import java.security.Permission; 49 import java.security.PermissionCollection; 50 import java.security.Permissions; 51 import java.security.Policy; 52 import java.security.ProtectionDomain; 53 import static java.nio.charset.StandardCharsets.US_ASCII; 54 55 public class LookupTest { 56 57 static int port; 58 static volatile ServerSocket serverSocket; 59 60 static void test(String url, 61 boolean throwsSecException, 62 boolean throwsIOException) { 63 ProxySelector.setDefault(null); 64 URL u; 65 InputStream is = null; 66 try { 67 u = new URL(url); 68 System.err.println("Connecting to " + u); 69 URLConnection urlc = u.openConnection(); 70 is = urlc.getInputStream(); 71 } catch (SecurityException e) { 72 if (!throwsSecException) { 73 throw new RuntimeException("Unexpected SecurityException:", e); 74 } 75 return; 76 } catch (IOException e) { 77 if (!throwsIOException) { 78 System.err.println("Unexpected IOException:" + e.getMessage()); 79 throw new RuntimeException(e); 80 } 81 return; 82 } finally { 83 if (is != null) { 84 try { 85 is.close(); 86 } catch (IOException e) { 87 System.err.println("Unexpected IOException:" + e.getMessage()); 88 throw new RuntimeException(e); 89 } 90 } 91 } 92 93 if (throwsSecException || throwsIOException) { 94 System.err.printf("was expecting a %s\n", throwsSecException 95 ? "security exception" : "IOException"); 96 throw new RuntimeException("was expecting an exception"); 97 } 98 } 99 100 static final String CWD = System.getProperty("user.dir", "."); 101 102 public static void main(String args[]) throws Exception { 103 String hostsFileName = CWD + "/LookupTestHosts"; 104 System.setProperty("jdk.net.hosts.file", hostsFileName); 105 addMappingToHostsFile("allowedAndFound.com", 106 "127.0.0.1", 107 hostsFileName, 108 false); 109 addMappingToHostsFile("notAllowedButFound.com", 110 "99.99.99.99", 111 hostsFileName, 112 true); 113 // name "notAllowedAndNotFound.com" is not in map 114 // name "allowedButNotfound.com" is not in map 115 Server server = new Server(); 116 try { 117 Policy.setPolicy(new LookupTestPolicy()); 118 System.setSecurityManager(new SecurityManager()); 119 server.start(); 120 test("http://allowedAndFound.com:" + port + "/foo", false, false); 121 test("http://notAllowedButFound.com:" + port + "/foo", true, false); 122 test("http://allowedButNotfound.com:" + port + "/foo", false, true); 123 test("http://notAllowedAndNotFound.com:" + port + "/foo", true, false); 124 } finally { 125 server.terminate(); 126 } 127 } 128 129 static class Server extends Thread { 130 private volatile boolean done; 131 132 public Server() throws IOException { 133 serverSocket = new ServerSocket(0); 134 port = serverSocket.getLocalPort(); 135 } 136 137 public void run() { 138 try { 139 while (!done) { 140 try (Socket s = serverSocket.accept()) { 141 readOneRequest(s.getInputStream()); 142 OutputStream o = s.getOutputStream(); 143 String rsp = "HTTP/1.1 200 Ok\r\n" + 144 "Connection: close\r\n" + 145 "Content-length: 0\r\n\r\n"; 146 o.write(rsp.getBytes(US_ASCII)); 147 } 148 } 149 } catch (IOException e) { 150 if (!done) 151 e.printStackTrace(); 152 } 153 } 154 155 void terminate() { 156 done = true; 157 try { serverSocket.close(); } 158 catch (IOException unexpected) { unexpected.printStackTrace(); } 159 } 160 161 static final byte[] requestEnd = new byte[] {'\r', '\n', '\r', '\n' }; 162 163 // Read until the end of a HTTP request 164 void readOneRequest(InputStream is) throws IOException { 165 int requestEndCount = 0, r; 166 while ((r = is.read()) != -1) { 167 if (r == requestEnd[requestEndCount]) { 168 requestEndCount++; 169 if (requestEndCount == 4) { 170 break; 171 } 172 } else { 173 requestEndCount = 0; 174 } 175 } 176 } 177 } 178 179 private static void addMappingToHostsFile(String host, 180 String addr, 181 String hostsFileName, 182 boolean append) 183 throws IOException 184 { 185 String mapping = addr + " " + host; 186 try (FileWriter fr = new FileWriter(hostsFileName, append); 187 PrintWriter hfPWriter = new PrintWriter(new BufferedWriter(fr))) { 188 hfPWriter.println(mapping); 189 } 190 } 191 192 static class LookupTestPolicy extends Policy { 193 final PermissionCollection perms = new Permissions(); 194 195 LookupTestPolicy() throws Exception { 196 perms.add(new NetPermission("setProxySelector")); 197 perms.add(new SocketPermission("localhost:1024-", "resolve,accept")); 198 perms.add(new URLPermission("http://allowedAndFound.com:" + port + "/-", "*:*")); 199 perms.add(new URLPermission("http://allowedButNotfound.com:" + port + "/-", "*:*")); 200 perms.add(new FilePermission("<<ALL FILES>>", "read,write,delete")); 201 //perms.add(new PropertyPermission("java.io.tmpdir", "read")); 202 } 203 204 public PermissionCollection getPermissions(ProtectionDomain domain) { 205 return perms; 206 } 207 208 public PermissionCollection getPermissions(CodeSource codesource) { 209 return perms; 210 } 211 212 public boolean implies(ProtectionDomain domain, Permission perm) { 213 return perms.implies(perm); 214 } 215 } 216 }