Showing the changes to java/pkg/com/sun/security/auth/login/ConfigFile.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,675 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000, 2011, 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 com.sun.security.auth.login; | ||
| 27 | |||
| 28 | import javax.security.auth.AuthPermission; | ||
| 29 | import javax.security.auth.login.AppConfigurationEntry; | ||
| 30 | import java.io.*; | ||
| 31 | import java.util.*; | ||
| 32 | import java.net.URI; | ||
| 33 | import java.net.URL; | ||
| 34 | import java.net.MalformedURLException; | ||
| 35 | import java.text.MessageFormat; | ||
| 36 | import sun.security.util.Debug; | ||
| 37 | import sun.security.util.ResourcesMgr; | ||
| 38 | import sun.security.util.PropertyExpander; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * This class represents a default implementation for | ||
| 42 | * <code>javax.security.auth.login.Configuration</code>. | ||
| 43 | * | ||
| 44 | * <p> This object stores the runtime login configuration representation, | ||
| 45 | * and is the amalgamation of multiple static login | ||
| 46 | * configurations that resides in files. | ||
| 47 | * The algorithm for locating the login configuration file(s) and reading their | ||
| 48 | * information into this <code>Configuration</code> object is: | ||
| 49 | * | ||
| 50 | * <ol> | ||
| 51 | * <li> | ||
| 52 | * Loop through the <code>java.security.Security</code> properties, | ||
| 53 | * <i>login.config.url.1</i>, <i>login.config.url.2</i>, ..., | ||
| 54 | * <i>login.config.url.X</i>. These properties are set | ||
| 55 | * in the Java security properties file, which is located in the file named | ||
| 56 | * <JAVA_HOME>/lib/security/java.security. | ||
| 57 | * <JAVA_HOME> refers to the value of the java.home system property, | ||
| 58 | * and specifies the directory where the JRE is installed. | ||
| 59 | * Each property value specifies a <code>URL</code> pointing to a | ||
| 60 | * login configuration file to be loaded. Read in and load | ||
| 61 | * each configuration. | ||
| 62 | * | ||
| 63 | * <li> | ||
| 64 | * The <code>java.lang.System</code> property | ||
| 65 | * <i>java.security.auth.login.config</i> | ||
| 66 | * may also be set to a <code>URL</code> pointing to another | ||
| 67 | * login configuration file | ||
| 68 | * (which is the case when a user uses the -D switch at runtime). | ||
| 69 | * If this property is defined, and its use is allowed by the | ||
| 70 | * security property file (the Security property, | ||
| 71 | * <i>policy.allowSystemProperty</i> is set to <i>true</i>), | ||
| 72 | * also load that login configuration. | ||
| 73 | * | ||
| 74 | * <li> | ||
| 75 | * If the <i>java.security.auth.login.config</i> property is defined using | ||
| 76 | * "==" (rather than "="), then ignore all other specified | ||
| 77 | * login configurations and only load this configuration. | ||
| 78 | * | ||
| 79 | * <li> | ||
| 80 | * If no system or security properties were set, try to read from the file, | ||
| 81 | * ${user.home}/.java.login.config, where ${user.home} is the value | ||
| 82 | * represented by the "user.home" System property. | ||
| 83 | * </ol> | ||
| 84 | * | ||
| 85 | * <p> The configuration syntax supported by this implementation | ||
| 86 | * is exactly that syntax specified in the | ||
| 87 | * <code>javax.security.auth.login.Configuration</code> class. | ||
| 88 | * | ||
| 89 | * @see javax.security.auth.login.LoginContext | ||
| 90 | */ | ||
| 91 | public class ConfigFile extends javax.security.auth.login.Configuration { | ||
| 92 | |||
| 93 | private StreamTokenizer st; | ||
| 94 | private int lookahead; | ||
| 95 | private int linenum; | ||
| 96 | private HashMap<String, LinkedList<AppConfigurationEntry>> configuration; | ||
| 97 | private boolean expandProp = true; | ||
| 98 | private URL url; | ||
| 99 | |||
| 100 | private static Debug debugConfig = Debug.getInstance("configfile"); | ||
| 101 | private static Debug debugParser = Debug.getInstance("configparser"); | ||
| 102 | |||
| 103 | /** | ||
| 104 | * Create a new <code>Configuration</code> object. | ||
| 105 | */ | ||
| 106 | public ConfigFile() { | ||
| 107 | try { | ||
| 108 | init(url); | ||
| 109 | } catch (IOException ioe) { | ||
| 110 | throw (SecurityException) | ||
| 111 | new SecurityException(ioe.getMessage()).initCause(ioe); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * Create a new <code>Configuration</code> object from the specified URI. | ||
| 117 | * | ||
| 118 | * @param uri Create a new Configuration object from this URI. | ||
| 119 | */ | ||
| 120 | public ConfigFile(URI uri) { | ||
| 121 | // only load config from the specified URI | ||
| 122 | try { | ||
| 123 | url = uri.toURL(); | ||
| 124 | init(url); | ||
| 125 | } catch (MalformedURLException mue) { | ||
| 126 | throw (SecurityException) | ||
| 127 | new SecurityException(mue.getMessage()).initCause(mue); | ||
| 128 | } catch (IOException ioe) { | ||
| 129 | throw (SecurityException) | ||
| 130 | new SecurityException(ioe.getMessage()).initCause(ioe); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 135 | * Read and initialize the entire login Configuration. | ||
| 136 | * | ||
| 137 | * <p> | ||
| 138 | * | ||
| 139 | * @exception IOException if the Configuration can not be initialized. <p> | ||
| 140 | * @exception SecurityException if the caller does not have permission | ||
| 141 | * to initialize the Configuration. | ||
| 142 | */ | ||
| 143 | private void init(URL url) throws IOException { | ||
| 144 | |||
| 145 | boolean initialized = false; | ||
| 146 | FileReader fr = null; | ||
| 147 | String sep = File.separator; | ||
| 148 | |||
| 149 | if ("false".equals(System.getProperty("policy.expandProperties"))) { | ||
| 150 | expandProp = false; | ||
| 151 | } | ||
| 152 | |||
| 153 | // new configuration | ||
| 154 | HashMap<String, LinkedList<AppConfigurationEntry>> newConfig = | ||
| 155 | new HashMap<>(); | ||
| 156 | |||
| 157 | if (url != null) { | ||
| 158 | |||
| 159 | /** | ||
| 160 | * If the caller specified a URI via Configuration.getInstance, | ||
| 161 | * we only read from that URI | ||
| 162 | */ | ||
| 163 | if (debugConfig != null) { | ||
| 164 | debugConfig.println("reading " + url); | ||
| 165 | } | ||
| 166 | init(url, newConfig); | ||
| 167 | configuration = newConfig; | ||
| 168 | return; | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * Caller did not specify URI via Configuration.getInstance. | ||
| 173 | * Read from URLs listed in the java.security properties file. | ||
| 174 | */ | ||
| 175 | |||
| 176 | String allowSys = java.security.Security.getProperty | ||
| 177 | ("policy.allowSystemProperty"); | ||
| 178 | |||
| 179 | if ("true".equalsIgnoreCase(allowSys)) { | ||
| 180 | String extra_config = System.getProperty | ||
| 181 | ("java.security.auth.login.config"); | ||
| 182 | if (extra_config != null) { | ||
| 183 | boolean overrideAll = false; | ||
| 184 | if (extra_config.startsWith("=")) { | ||
| 185 | overrideAll = true; | ||
| 186 | extra_config = extra_config.substring(1); | ||
| 187 | } | ||
| 188 | try { | ||
| 189 | extra_config = PropertyExpander.expand(extra_config); | ||
| 190 | } catch (PropertyExpander.ExpandException peee) { | ||
| 191 | MessageFormat form = new MessageFormat | ||
| 192 | (ResourcesMgr.getString | ||
| 193 | ("Unable.to.properly.expand.config", | ||
| 194 | "sun.security.util.AuthResources")); | ||
| 195 | Object[] source = {extra_config}; | ||
| 196 | throw new IOException(form.format(source)); | ||
| 197 | } | ||
| 198 | |||
| 199 | URL configURL = null; | ||
| 200 | try { | ||
| 201 | configURL = new URL(extra_config); | ||
| 202 | } catch (java.net.MalformedURLException mue) { | ||
| 203 | File configFile = new File(extra_config); | ||
| 204 | if (configFile.exists()) { | ||
| 205 | configURL = configFile.toURI().toURL(); | ||
| 206 | } else { | ||
| 207 | MessageFormat form = new MessageFormat | ||
| 208 | (ResourcesMgr.getString | ||
| 209 | ("extra.config.No.such.file.or.directory.", | ||
| 210 | "sun.security.util.AuthResources")); | ||
| 211 | Object[] source = {extra_config}; | ||
| 212 | throw new IOException(form.format(source)); | ||
| 213 | } | ||
| 214 | } | ||
| 215 | |||
| 216 | if (debugConfig != null) { | ||
| 217 | debugConfig.println("reading "+configURL); | ||
| 218 | } | ||
| 219 | init(configURL, newConfig); | ||
| 220 | initialized = true; | ||
| 221 | if (overrideAll) { | ||
| 222 | if (debugConfig != null) { | ||
| 223 | debugConfig.println("overriding other policies!"); | ||
| 224 | } | ||
| 225 | configuration = newConfig; | ||
| 226 | return; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | int n = 1; | ||
| 232 | String config_url; | ||
| 233 | while ((config_url = java.security.Security.getProperty | ||
| 234 | ("login.config.url."+n)) != null) { | ||
| 235 | try { | ||
| 236 | config_url = PropertyExpander.expand | ||
| 237 | (config_url).replace(File.separatorChar, '/'); | ||
| 238 | if (debugConfig != null) { | ||
| 239 | debugConfig.println("\tReading config: " + config_url); | ||
| 240 | } | ||
| 241 | init(new URL(config_url), newConfig); | ||
| 242 | initialized = true; | ||
| 243 | } catch (PropertyExpander.ExpandException peee) { | ||
| 244 | MessageFormat form = new MessageFormat | ||
| 245 | (ResourcesMgr.getString | ||
| 246 | ("Unable.to.properly.expand.config", | ||
| 247 | "sun.security.util.AuthResources")); | ||
| 248 | Object[] source = {config_url}; | ||
| 249 | throw new IOException(form.format(source)); | ||
| 250 | } | ||
| 251 | n++; | ||
| 252 | } | ||
| 253 | |||
| 254 | if (initialized == false && n == 1 && config_url == null) { | ||
| 255 | |||
| 256 | // get the config from the user's home directory | ||
| 257 | if (debugConfig != null) { | ||
| 258 | debugConfig.println("\tReading Policy " + | ||
| 259 | "from ~/.java.login.config"); | ||
| 260 | } | ||
| 261 | config_url = System.getProperty("user.home"); | ||
| 262 | String userConfigFile = config_url + | ||
| 263 | File.separatorChar + ".java.login.config"; | ||
| 264 | |||
| 265 | // No longer throws an exception when there's no config file | ||
| 266 | // at all. Returns an empty Configuration instead. | ||
| 267 | if (new File(userConfigFile).exists()) { | ||
| 268 | init(new File(userConfigFile).toURI().toURL(), | ||
| 269 | newConfig); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | configuration = newConfig; | ||
| 274 | } | ||
| 275 | |||
| 276 | private void init(URL config, | ||
| 277 | HashMap<String, LinkedList<AppConfigurationEntry>> newConfig) | ||
| 278 | throws IOException { | ||
| 279 | |||
| 280 | InputStreamReader isr = null; | ||
| 281 | try { | ||
| 282 | isr = new InputStreamReader(getInputStream(config), "UTF-8"); | ||
| 283 | readConfig(isr, newConfig); | ||
| 284 | } catch (FileNotFoundException fnfe) { | ||
| 285 | if (debugConfig != null) { | ||
| 286 | debugConfig.println(fnfe.toString()); | ||
| 287 | } | ||
| 288 | throw new IOException(ResourcesMgr.getString | ||
| 289 | ("Configuration.Error.No.such.file.or.directory", | ||
| 290 | "sun.security.util.AuthResources")); | ||
| 291 | } finally { | ||
| 292 | if (isr != null) { | ||
| 293 | isr.close(); | ||
| 294 | } | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | /** | ||
| 299 | * Retrieve an entry from the Configuration using an application name | ||
| 300 | * as an index. | ||
| 301 | * | ||
| 302 | * <p> | ||
| 303 | * | ||
| 304 | * @param applicationName the name used to index the Configuration. | ||
| 305 | * @return an array of AppConfigurationEntries which correspond to | ||
| 306 | * the stacked configuration of LoginModules for this | ||
| 307 | * application, or null if this application has no configured | ||
| 308 | * LoginModules. | ||
| 309 | */ | ||
| 310 | public AppConfigurationEntry[] getAppConfigurationEntry | ||
| 311 | (String applicationName) { | ||
| 312 | |||
| 313 | LinkedList<AppConfigurationEntry> list = null; | ||
| 314 | synchronized (configuration) { | ||
| 315 | list = configuration.get(applicationName); | ||
| 316 | } | ||
| 317 | |||
| 318 | if (list == null || list.size() == 0) | ||
| 319 | return null; | ||
| 320 | |||
| 321 | AppConfigurationEntry[] entries = | ||
| 322 | new AppConfigurationEntry[list.size()]; | ||
| 323 | Iterator<AppConfigurationEntry> iterator = list.iterator(); | ||
| 324 | for (int i = 0; iterator.hasNext(); i++) { | ||
| 325 | AppConfigurationEntry e = iterator.next(); | ||
| 326 | entries[i] = new AppConfigurationEntry(e.getLoginModuleName(), | ||
| 327 | e.getControlFlag(), | ||
| 328 | e.getOptions()); | ||
| 329 | } | ||
| 330 | return entries; | ||
| 331 | } | ||
| 332 | |||
| 333 | /** | ||
| 334 | * Refresh and reload the Configuration by re-reading all of the | ||
| 335 | * login configurations. | ||
| 336 | * | ||
| 337 | * <p> | ||
| 338 | * | ||
| 339 | * @exception SecurityException if the caller does not have permission | ||
| 340 | * to refresh the Configuration. | ||
| 341 | */ | ||
| 342 | public synchronized void refresh() { | ||
| 343 | |||
| 344 | java.lang.SecurityManager sm = System.getSecurityManager(); | ||
| 345 | if (sm != null) | ||
| 346 | sm.checkPermission(new AuthPermission("refreshLoginConfiguration")); | ||
| 347 | |||
| 348 | java.security.AccessController.doPrivileged | ||
| 349 | (new java.security.PrivilegedAction<Void>() { | ||
| 350 | public Void run() { | ||
| 351 | try { | ||
| 352 | init(url); | ||
| 353 | } catch (java.io.IOException ioe) { | ||
| 354 | throw (SecurityException) new SecurityException | ||
| 355 | (ioe.getLocalizedMessage()).initCause(ioe); | ||
| 356 | } | ||
| 357 | return null; | ||
| 358 | } | ||
| 359 | }); | ||
| 360 | } | ||
| 361 | |||
| 362 | private void readConfig(Reader reader, | ||
| 363 | HashMap<String, LinkedList<AppConfigurationEntry>> newConfig) | ||
| 364 | throws IOException { | ||
| 365 | |||
| 366 | int linenum = 1; | ||
| 367 | |||
| 368 | if (!(reader instanceof BufferedReader)) | ||
| 369 | reader = new BufferedReader(reader); | ||
| 370 | |||
| 371 | st = new StreamTokenizer(reader); | ||
| 372 | st.quoteChar('"'); | ||
| 373 | st.wordChars('$', '$'); | ||
| 374 | st.wordChars('_', '_'); | ||
| 375 | st.wordChars('-', '-'); | ||
| 376 | st.lowerCaseMode(false); | ||
| 377 | st.slashSlashComments(true); | ||
| 378 | st.slashStarComments(true); | ||
| 379 | st.eolIsSignificant(true); | ||
| 380 | |||
| 381 | lookahead = nextToken(); | ||
| 382 | while (lookahead != StreamTokenizer.TT_EOF) { | ||
| 383 | parseLoginEntry(newConfig); | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 387 | private void parseLoginEntry( | ||
| 388 | HashMap<String, LinkedList<AppConfigurationEntry>> newConfig) | ||
| 389 | throws IOException { | ||
| 390 | |||
| 391 | String appName; | ||
| 392 | String moduleClass; | ||
| 393 | String sflag; | ||
| 394 | AppConfigurationEntry.LoginModuleControlFlag controlFlag; | ||
| 395 | LinkedList<AppConfigurationEntry> configEntries = new LinkedList<>(); | ||
| 396 | |||
| 397 | // application name | ||
| 398 | appName = st.sval; | ||
| 399 | lookahead = nextToken(); | ||
| 400 | |||
| 401 | if (debugParser != null) { | ||
| 402 | debugParser.println("\tReading next config entry: " + appName); | ||
| 403 | } | ||
| 404 | |||
| 405 | match("{"); | ||
| 406 | |||
| 407 | // get the modules | ||
| 408 | while (peek("}") == false) { | ||
| 409 | // get the module class name | ||
| 410 | moduleClass = match("module class name"); | ||
| 411 | |||
| 412 | // controlFlag (required, optional, etc) | ||
| 413 | sflag = match("controlFlag"); | ||
| 414 | if (sflag.equalsIgnoreCase("REQUIRED")) | ||
| 415 | controlFlag = | ||
| 416 | AppConfigurationEntry.LoginModuleControlFlag.REQUIRED; | ||
| 417 | else if (sflag.equalsIgnoreCase("REQUISITE")) | ||
| 418 | controlFlag = | ||
| 419 | AppConfigurationEntry.LoginModuleControlFlag.REQUISITE; | ||
| 420 | else if (sflag.equalsIgnoreCase("SUFFICIENT")) | ||
| 421 | controlFlag = | ||
| 422 | AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT; | ||
| 423 | else if (sflag.equalsIgnoreCase("OPTIONAL")) | ||
| 424 | controlFlag = | ||
| 425 | AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL; | ||
| 426 | else { | ||
| 427 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 428 | ("Configuration.Error.Invalid.control.flag.flag", | ||
| 429 | "sun.security.util.AuthResources")); | ||
| 430 | Object[] source = {sflag}; | ||
| 431 | throw new IOException(form.format(source)); | ||
| 432 | } | ||
| 433 | |||
| 434 | // get the args | ||
| 435 | HashMap<String, String> options = new HashMap<>(); | ||
| 436 | String key; | ||
| 437 | String value; | ||
| 438 | while (peek(";") == false) { | ||
| 439 | key = match("option key"); | ||
| 440 | match("="); | ||
| 441 | try { | ||
| 442 | value = expand(match("option value")); | ||
| 443 | } catch (PropertyExpander.ExpandException peee) { | ||
| 444 | throw new IOException(peee.getLocalizedMessage()); | ||
| 445 | } | ||
| 446 | options.put(key, value); | ||
| 447 | } | ||
| 448 | |||
| 449 | lookahead = nextToken(); | ||
| 450 | |||
| 451 | // create the new element | ||
| 452 | if (debugParser != null) { | ||
| 453 | debugParser.println("\t\t" + moduleClass + ", " + sflag); | ||
| 454 | java.util.Iterator<String> i = options.keySet().iterator(); | ||
| 455 | while (i.hasNext()) { | ||
| 456 | key = i.next(); | ||
| 457 | debugParser.println("\t\t\t" + | ||
| 458 | key + | ||
| 459 | "=" + | ||
| 460 | options.get(key)); | ||
| 461 | } | ||
| 462 | } | ||
| 463 | AppConfigurationEntry entry = new AppConfigurationEntry | ||
| 464 | (moduleClass, | ||
| 465 | controlFlag, | ||
| 466 | options); | ||
| 467 | configEntries.add(entry); | ||
| 468 | } | ||
| 469 | |||
| 470 | match("}"); | ||
| 471 | match(";"); | ||
| 472 | |||
| 473 | // add this configuration entry | ||
| 474 | if (newConfig.containsKey(appName)) { | ||
| 475 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 476 | ("Configuration.Error.Can.not.specify.multiple.entries.for.appName", | ||
| 477 | "sun.security.util.AuthResources")); | ||
| 478 | Object[] source = {appName}; | ||
| 479 | throw new IOException(form.format(source)); | ||
| 480 | } | ||
| 481 | newConfig.put(appName, configEntries); | ||
| 482 | } | ||
| 483 | |||
| 484 | private String match(String expect) throws IOException { | ||
| 485 | |||
| 486 | String value = null; | ||
| 487 | |||
| 488 | switch(lookahead) { | ||
| 489 | case StreamTokenizer.TT_EOF: | ||
| 490 | |||
| 491 | MessageFormat form1 = new MessageFormat(ResourcesMgr.getString | ||
| 492 | ("Configuration.Error.expected.expect.read.end.of.file.", | ||
| 493 | "sun.security.util.AuthResources")); | ||
| 494 | Object[] source1 = {expect}; | ||
| 495 | throw new IOException(form1.format(source1)); | ||
| 496 | |||
| 497 | case '"': | ||
| 498 | case StreamTokenizer.TT_WORD: | ||
| 499 | |||
| 500 | if (expect.equalsIgnoreCase("module class name") || | ||
| 501 | expect.equalsIgnoreCase("controlFlag") || | ||
| 502 | expect.equalsIgnoreCase("option key") || | ||
| 503 | expect.equalsIgnoreCase("option value")) { | ||
| 504 | value = st.sval; | ||
| 505 | lookahead = nextToken(); | ||
| 506 | } else { | ||
| 507 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 508 | ("Configuration.Error.Line.line.expected.expect.found.value.", | ||
| 509 | "sun.security.util.AuthResources")); | ||
| 510 | Object[] source = {new Integer(linenum), expect, st.sval}; | ||
| 511 | throw new IOException(form.format(source)); | ||
| 512 | } | ||
| 513 | break; | ||
| 514 | |||
| 515 | case '{': | ||
| 516 | |||
| 517 | if (expect.equalsIgnoreCase("{")) { | ||
| 518 | lookahead = nextToken(); | ||
| 519 | } else { | ||
| 520 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 521 | ("Configuration.Error.Line.line.expected.expect.", | ||
| 522 | "sun.security.util.AuthResources")); | ||
| 523 | Object[] source = {new Integer(linenum), expect, st.sval}; | ||
| 524 | throw new IOException(form.format(source)); | ||
| 525 | } | ||
| 526 | break; | ||
| 527 | |||
| 528 | case ';': | ||
| 529 | |||
| 530 | if (expect.equalsIgnoreCase(";")) { | ||
| 531 | lookahead = nextToken(); | ||
| 532 | } else { | ||
| 533 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 534 | ("Configuration.Error.Line.line.expected.expect.", | ||
| 535 | "sun.security.util.AuthResources")); | ||
| 536 | Object[] source = {new Integer(linenum), expect, st.sval}; | ||
| 537 | throw new IOException(form.format(source)); | ||
| 538 | } | ||
| 539 | break; | ||
| 540 | |||
| 541 | case '}': | ||
| 542 | |||
| 543 | if (expect.equalsIgnoreCase("}")) { | ||
| 544 | lookahead = nextToken(); | ||
| 545 | } else { | ||
| 546 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 547 | ("Configuration.Error.Line.line.expected.expect.", | ||
| 548 | "sun.security.util.AuthResources")); | ||
| 549 | Object[] source = {new Integer(linenum), expect, st.sval}; | ||
| 550 | throw new IOException(form.format(source)); | ||
| 551 | } | ||
| 552 | break; | ||
| 553 | |||
| 554 | case '=': | ||
| 555 | |||
| 556 | if (expect.equalsIgnoreCase("=")) { | ||
| 557 | lookahead = nextToken(); | ||
| 558 | } else { | ||
| 559 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 560 | ("Configuration.Error.Line.line.expected.expect.", | ||
| 561 | "sun.security.util.AuthResources")); | ||
| 562 | Object[] source = {new Integer(linenum), expect, st.sval}; | ||
| 563 | throw new IOException(form.format(source)); | ||
| 564 | } | ||
| 565 | break; | ||
| 566 | |||
| 567 | default: | ||
| 568 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 569 | ("Configuration.Error.Line.line.expected.expect.found.value.", | ||
| 570 | "sun.security.util.AuthResources")); | ||
| 571 | Object[] source = {new Integer(linenum), expect, st.sval}; | ||
| 572 | throw new IOException(form.format(source)); | ||
| 573 | } | ||
| 574 | return value; | ||
| 575 | } | ||
| 576 | |||
| 577 | private boolean peek(String expect) { | ||
| 578 | boolean found = false; | ||
| 579 | |||
| 580 | switch (lookahead) { | ||
| 581 | case ',': | ||
| 582 | if (expect.equalsIgnoreCase(",")) | ||
| 583 | found = true; | ||
| 584 | break; | ||
| 585 | case ';': | ||
| 586 | if (expect.equalsIgnoreCase(";")) | ||
| 587 | found = true; | ||
| 588 | break; | ||
| 589 | case '{': | ||
| 590 | if (expect.equalsIgnoreCase("{")) | ||
| 591 | found = true; | ||
| 592 | break; | ||
| 593 | case '}': | ||
| 594 | if (expect.equalsIgnoreCase("}")) | ||
| 595 | found = true; | ||
| 596 | break; | ||
| 597 | default: | ||
| 598 | } | ||
| 599 | return found; | ||
| 600 | } | ||
| 601 | |||
| 602 | private int nextToken() throws IOException { | ||
| 603 | int tok; | ||
| 604 | while ((tok = st.nextToken()) == StreamTokenizer.TT_EOL) { | ||
| 605 | linenum++; | ||
| 606 | } | ||
| 607 | return tok; | ||
| 608 | } | ||
| 609 | |||
| 610 | /* | ||
| 611 | * Fast path reading from file urls in order to avoid calling | ||
| 612 | * FileURLConnection.connect() which can be quite slow the first time | ||
| 613 | * it is called. We really should clean up FileURLConnection so that | ||
| 614 | * this is not a problem but in the meantime this fix helps reduce | ||
| 615 | * start up time noticeably for the new launcher. -- DAC | ||
| 616 | */ | ||
| 617 | private InputStream getInputStream(URL url) throws IOException { | ||
| 618 | if ("file".equalsIgnoreCase(url.getProtocol())) { | ||
| 619 | // Compatibility notes: | ||
| 620 | // | ||
| 621 | // Code changed from | ||
| 622 | // String path = url.getFile().replace('/', File.separatorChar); | ||
| 623 | // return new FileInputStream(path); | ||
| 624 | // | ||
| 625 | // The original implementation would search for "/tmp/a%20b" | ||
| 626 | // when url is "file:///tmp/a%20b". This is incorrect. The | ||
| 627 | // current codes fix this bug and searches for "/tmp/a b". | ||
| 628 | // For compatibility reasons, when the file "/tmp/a b" does | ||
| 629 | // not exist, the file named "/tmp/a%20b" will be tried. | ||
| 630 | // | ||
| 631 | // This also means that if both file exists, the behavior of | ||
| 632 | // this method is changed, and the current codes choose the | ||
| 633 | // correct one. | ||
| 634 | try { | ||
| 635 | return url.openStream(); | ||
| 636 | } catch (Exception e) { | ||
| 637 | String file = url.getPath(); | ||
| 638 | if (url.getHost().length() > 0) { // For Windows UNC | ||
| 639 | file = "//" + url.getHost() + file; | ||
| 640 | } | ||
| 641 | if (debugConfig != null) { | ||
| 642 | debugConfig.println("cannot read " + url + | ||
| 643 | ", try " + file); | ||
| 644 | } | ||
| 645 | return new FileInputStream(file); | ||
| 646 | } | ||
| 647 | } else { | ||
| 648 | return url.openStream(); | ||
| 649 | } | ||
| 650 | } | ||
| 651 | |||
| 652 | private String expand(String value) | ||
| 653 | throws PropertyExpander.ExpandException, IOException { | ||
| 654 | |||
| 655 | if ("".equals(value)) { | ||
| 656 | return value; | ||
| 657 | } | ||
| 658 | |||
| 659 | if (expandProp) { | ||
| 660 | |||
| 661 | String s = PropertyExpander.expand(value); | ||
| 662 | |||
| 663 | if (s == null || s.length() == 0) { | ||
| 664 | MessageFormat form = new MessageFormat(ResourcesMgr.getString | ||
| 665 | ("Configuration.Error.Line.line.system.property.value.expanded.to.empty.value", | ||
| 666 | "sun.security.util.AuthResources")); | ||
| 667 | Object[] source = {new Integer(linenum), value}; | ||
| 668 | throw new IOException(form.format(source)); | ||
| 669 | } | ||
| 670 | return s; | ||
| 671 | } else { | ||
| 672 | return value; | ||
| 673 | } | ||
| 674 | } | ||
| 675 | } | ||