1 /* 2 * Copyright (c) 2013, 2014, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package build.tools.makejavasecurity; 27 28 import java.io.*; 29 import java.nio.file.Files; 30 import java.nio.file.Paths; 31 import java.util.*; 32 33 /** 34 * Builds the java.security file, including 35 * 36 * 1. Adds additional packages to the package.access and 37 * package.definition security properties. 38 * 2. Filter out platform-unrelated parts 39 * 40 * In order to easily maintain platform-related entries, every item 41 * (including the last line) in package.access and package.definition 42 * MUST end with ',\'. A blank line MUST exist after the last line. 43 */ 44 public class MakeJavaSecurity { 45 46 private static final String PKG_ACC = "package.access"; 47 private static final String PKG_DEF = "package.definition"; 48 private static final int PKG_ACC_INDENT = 15; 49 private static final int PKG_DEF_INDENT = 19; 50 51 public static void main(String[] args) throws Exception { 52 53 if (args.length < 4) { 54 System.err.println("Usage: java MakeJavaSecurity " + 55 "[input java.security file name] " + 56 "[output java.security file name] " + 57 "[openjdk target os] " + 58 "[more restricted packages file name]"); 59 System.exit(1); 60 } 61 62 // more restricted packages 63 List<String> extraLines = null; 64 try { 65 extraLines = Files.readAllLines(Paths.get(args[3])); 66 } catch (IOException e) { 67 // This could happen in openjdk-only build 68 extraLines = Collections.emptyList(); 69 } 70 71 List<String> lines = new ArrayList<>(); 72 73 // read raw java.security and add more restricted packages 74 try (FileReader fr = new FileReader(args[0]); 75 BufferedReader br = new BufferedReader(fr)) { 76 // looking for pkg access properties 77 String line = br.readLine(); 78 while (line != null) { 79 if (line.startsWith(PKG_ACC)) { 80 addPackages(br, lines, line, PKG_ACC_INDENT, extraLines); 81 } else if (line.startsWith(PKG_DEF)) { 82 addPackages(br, lines, line, PKG_DEF_INDENT, extraLines); 83 } else { 84 lines.add(line); 85 } 86 line = br.readLine(); 87 } 88 } 89 90 // Filter out platform-unrelated ones. We only support 91 // #ifdef, #ifndef, and #endif. 92 int mode = 0; // 0: out of block, 1: in match, 2: in non-match 93 Iterator<String> iter = lines.iterator(); 94 while (iter.hasNext()) { 95 String line = iter.next(); 96 if (line.startsWith("#endif")) { 97 mode = 0; 98 iter.remove(); 99 } else if (line.startsWith("#ifdef ")) { 100 mode = line.endsWith(args[2])?1:2; 101 iter.remove(); 102 } else if (line.startsWith("#ifndef ")) { 103 mode = line.endsWith(args[2])?2:1; 104 iter.remove(); 105 } else { 106 if (mode == 2) iter.remove(); 107 } 108 } 109 110 // Update .tbd to .1, .2, etc. 111 Map<String,Integer> count = new HashMap<>(); 112 for (int i=0; i<lines.size(); i++) { 113 String line = lines.get(i); 114 int index = line.indexOf(".tbd"); 115 if (index >= 0) { 116 String prefix = line.substring(0, index); 117 int n = count.getOrDefault(prefix, 1); 118 count.put(prefix, n+1); 119 lines.set(i, prefix + "." + n + line.substring(index+4)); 120 } 121 } 122 123 // Clean up the last line of PKG_ACC and PKG_DEF blocks. 124 // Not really necessary since a blank line follows. 125 boolean inBlock = false; 126 for (int i=0; i<lines.size(); i++) { 127 String line = lines.get(i); 128 if (line.startsWith(PKG_ACC) || line.startsWith(PKG_DEF)) { 129 inBlock = true; 130 } 131 if (inBlock) { 132 if (line.isEmpty()) { 133 String lastLine = lines.get(i-1); 134 lines.set(i-1, lastLine.substring(0, lastLine.length()-2)); 135 inBlock = false; 136 } 137 } 138 } 139 140 Files.write(Paths.get(args[1]), lines); 141 } 142 143 private static void addPackages(BufferedReader br, List<String> lines, 144 String line, int numSpaces, 145 List<String> args) throws IOException { 146 // parse property until EOL, not including line breaks 147 boolean first = true; 148 while (!line.isEmpty()) { 149 if (!line.startsWith("#")) { 150 if (!line.endsWith(",\\") || 151 (!first && line.contains("="))) { 152 throw new IOException("Invalid line: " + line); 153 } 154 } 155 lines.add(line); 156 line = br.readLine(); 157 first = false; 158 } 159 // add new packages, one per line 160 for (String arg: args) { 161 if (arg.startsWith("#")) { 162 lines.add(arg); 163 } else { 164 lines.add(String.format("%"+numSpaces+"s", "") + arg + ",\\"); 165 } 166 } 167 lines.add(line); 168 } 169 }