1 /*
   2  * Copyright (c) 2019, 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  * @bug 8231358
  27  * @run main/othervm -Djdk.nio.channels.tmpdir=/tmp Security policy1
  28  * @run main/othervm -Djdk.nio.channels.tmpdir=/tmp Security policy2
  29  * @summary Security test for Unix Domain socket and server socket channels
  30  */
  31 
  32 import java.io.File;
  33 import java.io.IOException;
  34 import java.net.SocketAddress;
  35 import java.net.UnixDomainSocketAddress;
  36 import java.nio.channels.*;
  37 import java.nio.file.Files;
  38 import java.nio.file.Path;
  39 import java.util.Comparator;
  40 
  41 import static java.net.StandardProtocolFamily.UNIX;
  42 
  43 /**
  44  * Tests required all with security manager
  45  */
  46 
  47 public class Security {
  48 
  49     static interface Command {
  50         public void run() throws Exception;
  51     }
  52 
  53     static <T extends Exception> void call(Command r, Class<? extends Exception> expectedException) {
  54         boolean threw = false;
  55         try {
  56             r.run();
  57         } catch (Throwable t) {
  58             if (expectedException == null) {
  59                 t.printStackTrace();
  60                 throw new RuntimeException("an exception was thrown but was not expected");
  61             }
  62             threw = true;
  63             if (!(expectedException.isAssignableFrom(t.getClass()))) {
  64                 throw new RuntimeException("wrong exception type thrown " + t.toString());
  65             }
  66         }
  67         if (expectedException != null && !threw) {
  68             // should have thrown
  69             throw new RuntimeException("SecurityException was expected");
  70         }
  71     }
  72 
  73 
  74     public static void main(String[] args) throws Exception {
  75         try {SocketChannel.open(); } catch (java.io.IOException e) {}
  76 
  77         int namelen = Integer.parseInt(System.getProperty("jdk.nio.channels.unixdomain.maxnamelength"));
  78         if (namelen == -1) {
  79             System.out.println("Unix domain not supported");
  80             return;
  81         }
  82         String policy = args[0];
  83         switch (policy) {
  84             case "policy1":
  85                 setSecurityManager(policy);
  86                 testPolicy1();
  87                 break;
  88             case "policy2":
  89                 setSecurityManager(policy);
  90                 testPolicy2();
  91                 break;
  92             default:
  93         }
  94 
  95     }
  96 
  97     static void setSecurityManager(String policy) {
  98         String testSrc = System.getProperty("test.src");
  99         // Three /// required for Windows below
 100         String policyURL = "file:///" + testSrc + File.separator + policy;
 101         System.out.println("POLICY: " + policyURL);
 102         System.setProperty("java.security.policy", policyURL);
 103         System.setSecurityManager(new SecurityManager());
 104     }
 105 
 106     static void close(NetworkChannel... channels) {
 107 
 108         for (NetworkChannel chan : channels) {
 109             try {
 110                 chan.close();
 111             } catch (Exception e) {
 112             }
 113         }
 114     }
 115 
 116     private static final Class<SecurityException> SE = SecurityException.class;
 117     private static final Class<IOException> IOE = IOException.class;
 118 
 119     // No permission
 120 
 121     public static void testPolicy1() throws Exception {
 122         Path servername = Path.of("sock");
 123         Files.deleteIfExists(servername);
 124         // Permission exists to bind a ServerSocketChannel
 125         final UnixDomainSocketAddress saddr = UnixDomainSocketAddress.of(servername);
 126         final ServerSocketChannel server = ServerSocketChannel.open(UNIX);
 127         final SocketChannel client = SocketChannel.open(UNIX);
 128         call(() -> {
 129             server.bind(saddr);
 130         }, SE);
 131         call(() -> {
 132             client.connect(saddr);
 133         }, SE);
 134         close(server, client);
 135     }
 136 
 137     // All permissions
 138 
 139     public static void testPolicy2() throws Exception {
 140         Path servername = Path.of("sock");
 141         Files.deleteIfExists(servername);
 142         final UnixDomainSocketAddress saddr = UnixDomainSocketAddress.of(servername);
 143         final ServerSocketChannel server = ServerSocketChannel.open(UNIX);
 144         final SocketChannel client = SocketChannel.open(UNIX);
 145         call(() -> {
 146             server.bind(saddr);
 147         }, null);
 148         call(() -> {
 149             client.connect(saddr);
 150         }, null);
 151         close(server, client);
 152     }
 153 }