PageRenderTime 171ms CodeModel.GetById 53ms RepoModel.GetById 13ms app.codeStats 1ms

/src/share/classes/sun/security/tools/policytool/PolicyTool.java

https://bitbucket.org/screenconnect/openjdk8-jdk
Java | 4518 lines | 3696 code | 331 blank | 491 comment | 202 complexity | ed5fa049fa423d5fe189c1f699d37584 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) 1997, 2013, 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. package sun.security.tools.policytool;
  26. import java.io.*;
  27. import java.util.LinkedList;
  28. import java.util.ListIterator;
  29. import java.util.Vector;
  30. import java.util.Enumeration;
  31. import java.net.URL;
  32. import java.net.MalformedURLException;
  33. import java.lang.reflect.*;
  34. import java.text.Collator;
  35. import java.text.MessageFormat;
  36. import sun.security.util.PropertyExpander;
  37. import sun.security.util.PropertyExpander.ExpandException;
  38. import java.awt.Component;
  39. import java.awt.Container;
  40. import java.awt.Dimension;
  41. import java.awt.FileDialog;
  42. import java.awt.GridBagConstraints;
  43. import java.awt.GridBagLayout;
  44. import java.awt.Insets;
  45. import java.awt.Point;
  46. import java.awt.Toolkit;
  47. import java.awt.Window;
  48. import java.awt.event.*;
  49. import java.security.cert.Certificate;
  50. import java.security.cert.CertificateException;
  51. import java.security.*;
  52. import sun.security.provider.*;
  53. import sun.security.util.PolicyUtil;
  54. import javax.security.auth.x500.X500Principal;
  55. import javax.swing.*;
  56. import javax.swing.border.EmptyBorder;
  57. /**
  58. * PolicyTool may be used by users and administrators to configure the
  59. * overall java security policy (currently stored in the policy file).
  60. * Using PolicyTool administrators may add and remove policies from
  61. * the policy file. <p>
  62. *
  63. * @see java.security.Policy
  64. * @since 1.2
  65. */
  66. public class PolicyTool {
  67. // for i18n
  68. static final java.util.ResourceBundle rb =
  69. java.util.ResourceBundle.getBundle(
  70. "sun.security.tools.policytool.Resources");
  71. static final Collator collator = Collator.getInstance();
  72. static {
  73. // this is for case insensitive string comparisons
  74. collator.setStrength(Collator.PRIMARY);
  75. // Support for Apple menu bar
  76. if (System.getProperty("apple.laf.useScreenMenuBar") == null) {
  77. System.setProperty("apple.laf.useScreenMenuBar", "true");
  78. }
  79. System.setProperty("apple.awt.application.name", getMessage("Policy.Tool"));
  80. // Apply the system L&F if not specified with a system property.
  81. if (System.getProperty("swing.defaultlaf") == null) {
  82. try {
  83. UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  84. } catch (Exception e) {
  85. // ignore
  86. }
  87. }
  88. }
  89. // anyone can add warnings
  90. Vector<String> warnings;
  91. boolean newWarning = false;
  92. // set to true if policy modified.
  93. // this way upon exit we know if to ask the user to save changes
  94. boolean modified = false;
  95. private static final boolean testing = false;
  96. private static final Class<?>[] TWOPARAMS = { String.class, String.class };
  97. private static final Class<?>[] ONEPARAMS = { String.class };
  98. private static final Class<?>[] NOPARAMS = {};
  99. /*
  100. * All of the policy entries are read in from the
  101. * policy file and stored here. Updates to the policy entries
  102. * using addEntry() and removeEntry() are made here. To ultimately save
  103. * the policy entries back to the policy file, the SavePolicy button
  104. * must be clicked.
  105. **/
  106. private static String policyFileName = null;
  107. private Vector<PolicyEntry> policyEntries = null;
  108. private PolicyParser parser = null;
  109. /* The public key alias information is stored here. */
  110. private KeyStore keyStore = null;
  111. private String keyStoreName = " ";
  112. private String keyStoreType = " ";
  113. private String keyStoreProvider = " ";
  114. private String keyStorePwdURL = " ";
  115. /* standard PKCS11 KeyStore type */
  116. private static final String P11KEYSTORE = "PKCS11";
  117. /* reserved word for PKCS11 KeyStores */
  118. private static final String NONE = "NONE";
  119. /**
  120. * default constructor
  121. */
  122. private PolicyTool() {
  123. policyEntries = new Vector<PolicyEntry>();
  124. parser = new PolicyParser();
  125. warnings = new Vector<String>();
  126. }
  127. /**
  128. * get the PolicyFileName
  129. */
  130. String getPolicyFileName() {
  131. return policyFileName;
  132. }
  133. /**
  134. * set the PolicyFileName
  135. */
  136. void setPolicyFileName(String policyFileName) {
  137. PolicyTool.policyFileName = policyFileName;
  138. }
  139. /**
  140. * clear keyStore info
  141. */
  142. void clearKeyStoreInfo() {
  143. this.keyStoreName = null;
  144. this.keyStoreType = null;
  145. this.keyStoreProvider = null;
  146. this.keyStorePwdURL = null;
  147. this.keyStore = null;
  148. }
  149. /**
  150. * get the keyStore URL name
  151. */
  152. String getKeyStoreName() {
  153. return keyStoreName;
  154. }
  155. /**
  156. * get the keyStore Type
  157. */
  158. String getKeyStoreType() {
  159. return keyStoreType;
  160. }
  161. /**
  162. * get the keyStore Provider
  163. */
  164. String getKeyStoreProvider() {
  165. return keyStoreProvider;
  166. }
  167. /**
  168. * get the keyStore password URL
  169. */
  170. String getKeyStorePwdURL() {
  171. return keyStorePwdURL;
  172. }
  173. /**
  174. * Open and read a policy file
  175. */
  176. void openPolicy(String filename) throws FileNotFoundException,
  177. PolicyParser.ParsingException,
  178. KeyStoreException,
  179. CertificateException,
  180. InstantiationException,
  181. MalformedURLException,
  182. IOException,
  183. NoSuchAlgorithmException,
  184. IllegalAccessException,
  185. NoSuchMethodException,
  186. UnrecoverableKeyException,
  187. NoSuchProviderException,
  188. ClassNotFoundException,
  189. PropertyExpander.ExpandException,
  190. InvocationTargetException {
  191. newWarning = false;
  192. // start fresh - blow away the current state
  193. policyEntries = new Vector<PolicyEntry>();
  194. parser = new PolicyParser();
  195. warnings = new Vector<String>();
  196. setPolicyFileName(null);
  197. clearKeyStoreInfo();
  198. // see if user is opening a NEW policy file
  199. if (filename == null) {
  200. modified = false;
  201. return;
  202. }
  203. // Read in the policy entries from the file and
  204. // populate the parser vector table. The parser vector
  205. // table only holds the entries as strings, so it only
  206. // guarantees that the policies are syntactically
  207. // correct.
  208. setPolicyFileName(filename);
  209. parser.read(new FileReader(filename));
  210. // open the keystore
  211. openKeyStore(parser.getKeyStoreUrl(), parser.getKeyStoreType(),
  212. parser.getKeyStoreProvider(), parser.getStorePassURL());
  213. // Update the local vector with the same policy entries.
  214. // This guarantees that the policy entries are not only
  215. // syntactically correct, but semantically valid as well.
  216. Enumeration<PolicyParser.GrantEntry> enum_ = parser.grantElements();
  217. while (enum_.hasMoreElements()) {
  218. PolicyParser.GrantEntry ge = enum_.nextElement();
  219. // see if all the signers have public keys
  220. if (ge.signedBy != null) {
  221. String signers[] = parseSigners(ge.signedBy);
  222. for (int i = 0; i < signers.length; i++) {
  223. PublicKey pubKey = getPublicKeyAlias(signers[i]);
  224. if (pubKey == null) {
  225. newWarning = true;
  226. MessageFormat form = new MessageFormat(getMessage
  227. ("Warning.A.public.key.for.alias.signers.i.does.not.exist.Make.sure.a.KeyStore.is.properly.configured."));
  228. Object[] source = {signers[i]};
  229. warnings.addElement(form.format(source));
  230. }
  231. }
  232. }
  233. // check to see if the Principals are valid
  234. ListIterator<PolicyParser.PrincipalEntry> prinList =
  235. ge.principals.listIterator(0);
  236. while (prinList.hasNext()) {
  237. PolicyParser.PrincipalEntry pe = prinList.next();
  238. try {
  239. verifyPrincipal(pe.getPrincipalClass(),
  240. pe.getPrincipalName());
  241. } catch (ClassNotFoundException fnfe) {
  242. newWarning = true;
  243. MessageFormat form = new MessageFormat(getMessage
  244. ("Warning.Class.not.found.class"));
  245. Object[] source = {pe.getPrincipalClass()};
  246. warnings.addElement(form.format(source));
  247. }
  248. }
  249. // check to see if the Permissions are valid
  250. Enumeration<PolicyParser.PermissionEntry> perms =
  251. ge.permissionElements();
  252. while (perms.hasMoreElements()) {
  253. PolicyParser.PermissionEntry pe = perms.nextElement();
  254. try {
  255. verifyPermission(pe.permission, pe.name, pe.action);
  256. } catch (ClassNotFoundException fnfe) {
  257. newWarning = true;
  258. MessageFormat form = new MessageFormat(getMessage
  259. ("Warning.Class.not.found.class"));
  260. Object[] source = {pe.permission};
  261. warnings.addElement(form.format(source));
  262. } catch (InvocationTargetException ite) {
  263. newWarning = true;
  264. MessageFormat form = new MessageFormat(getMessage
  265. ("Warning.Invalid.argument.s.for.constructor.arg"));
  266. Object[] source = {pe.permission};
  267. warnings.addElement(form.format(source));
  268. }
  269. // see if all the permission signers have public keys
  270. if (pe.signedBy != null) {
  271. String signers[] = parseSigners(pe.signedBy);
  272. for (int i = 0; i < signers.length; i++) {
  273. PublicKey pubKey = getPublicKeyAlias(signers[i]);
  274. if (pubKey == null) {
  275. newWarning = true;
  276. MessageFormat form = new MessageFormat(getMessage
  277. ("Warning.A.public.key.for.alias.signers.i.does.not.exist.Make.sure.a.KeyStore.is.properly.configured."));
  278. Object[] source = {signers[i]};
  279. warnings.addElement(form.format(source));
  280. }
  281. }
  282. }
  283. }
  284. PolicyEntry pEntry = new PolicyEntry(this, ge);
  285. policyEntries.addElement(pEntry);
  286. }
  287. // just read in the policy -- nothing has been modified yet
  288. modified = false;
  289. }
  290. /**
  291. * Save a policy to a file
  292. */
  293. void savePolicy(String filename)
  294. throws FileNotFoundException, IOException {
  295. // save the policy entries to a file
  296. parser.setKeyStoreUrl(keyStoreName);
  297. parser.setKeyStoreType(keyStoreType);
  298. parser.setKeyStoreProvider(keyStoreProvider);
  299. parser.setStorePassURL(keyStorePwdURL);
  300. parser.write(new FileWriter(filename));
  301. modified = false;
  302. }
  303. /**
  304. * Open the KeyStore
  305. */
  306. void openKeyStore(String name,
  307. String type,
  308. String provider,
  309. String pwdURL) throws KeyStoreException,
  310. NoSuchAlgorithmException,
  311. UnrecoverableKeyException,
  312. IOException,
  313. CertificateException,
  314. NoSuchProviderException,
  315. ExpandException {
  316. if (name == null && type == null &&
  317. provider == null && pwdURL == null) {
  318. // policy did not specify a keystore during open
  319. // or use wants to reset keystore values
  320. this.keyStoreName = null;
  321. this.keyStoreType = null;
  322. this.keyStoreProvider = null;
  323. this.keyStorePwdURL = null;
  324. // caller will set (tool.modified = true) if appropriate
  325. return;
  326. }
  327. URL policyURL = null;
  328. if (policyFileName != null) {
  329. File pfile = new File(policyFileName);
  330. policyURL = new URL("file:" + pfile.getCanonicalPath());
  331. }
  332. // although PolicyUtil.getKeyStore may properly handle
  333. // defaults and property expansion, we do it here so that
  334. // if the call is successful, we can set the proper values
  335. // (PolicyUtil.getKeyStore does not return expanded values)
  336. if (name != null && name.length() > 0) {
  337. name = PropertyExpander.expand(name).replace
  338. (File.separatorChar, '/');
  339. }
  340. if (type == null || type.length() == 0) {
  341. type = KeyStore.getDefaultType();
  342. }
  343. if (pwdURL != null && pwdURL.length() > 0) {
  344. pwdURL = PropertyExpander.expand(pwdURL).replace
  345. (File.separatorChar, '/');
  346. }
  347. try {
  348. this.keyStore = PolicyUtil.getKeyStore(policyURL,
  349. name,
  350. type,
  351. provider,
  352. pwdURL,
  353. null);
  354. } catch (IOException ioe) {
  355. // copied from sun.security.pkcs11.SunPKCS11
  356. String MSG = "no password provided, and no callback handler " +
  357. "available for retrieving password";
  358. Throwable cause = ioe.getCause();
  359. if (cause != null &&
  360. cause instanceof javax.security.auth.login.LoginException &&
  361. MSG.equals(cause.getMessage())) {
  362. // throw a more friendly exception message
  363. throw new IOException(MSG);
  364. } else {
  365. throw ioe;
  366. }
  367. }
  368. this.keyStoreName = name;
  369. this.keyStoreType = type;
  370. this.keyStoreProvider = provider;
  371. this.keyStorePwdURL = pwdURL;
  372. // caller will set (tool.modified = true)
  373. }
  374. /**
  375. * Add a Grant entry to the overall policy at the specified index.
  376. * A policy entry consists of a CodeSource.
  377. */
  378. boolean addEntry(PolicyEntry pe, int index) {
  379. if (index < 0) {
  380. // new entry -- just add it to the end
  381. policyEntries.addElement(pe);
  382. parser.add(pe.getGrantEntry());
  383. } else {
  384. // existing entry -- replace old one
  385. PolicyEntry origPe = policyEntries.elementAt(index);
  386. parser.replace(origPe.getGrantEntry(), pe.getGrantEntry());
  387. policyEntries.setElementAt(pe, index);
  388. }
  389. return true;
  390. }
  391. /**
  392. * Add a Principal entry to an existing PolicyEntry at the specified index.
  393. * A Principal entry consists of a class, and name.
  394. *
  395. * If the principal already exists, it is not added again.
  396. */
  397. boolean addPrinEntry(PolicyEntry pe,
  398. PolicyParser.PrincipalEntry newPrin,
  399. int index) {
  400. // first add the principal to the Policy Parser entry
  401. PolicyParser.GrantEntry grantEntry = pe.getGrantEntry();
  402. if (grantEntry.contains(newPrin) == true)
  403. return false;
  404. LinkedList<PolicyParser.PrincipalEntry> prinList =
  405. grantEntry.principals;
  406. if (index != -1)
  407. prinList.set(index, newPrin);
  408. else
  409. prinList.add(newPrin);
  410. modified = true;
  411. return true;
  412. }
  413. /**
  414. * Add a Permission entry to an existing PolicyEntry at the specified index.
  415. * A Permission entry consists of a permission, name, and actions.
  416. *
  417. * If the permission already exists, it is not added again.
  418. */
  419. boolean addPermEntry(PolicyEntry pe,
  420. PolicyParser.PermissionEntry newPerm,
  421. int index) {
  422. // first add the permission to the Policy Parser Vector
  423. PolicyParser.GrantEntry grantEntry = pe.getGrantEntry();
  424. if (grantEntry.contains(newPerm) == true)
  425. return false;
  426. Vector<PolicyParser.PermissionEntry> permList =
  427. grantEntry.permissionEntries;
  428. if (index != -1)
  429. permList.setElementAt(newPerm, index);
  430. else
  431. permList.addElement(newPerm);
  432. modified = true;
  433. return true;
  434. }
  435. /**
  436. * Remove a Permission entry from an existing PolicyEntry.
  437. */
  438. boolean removePermEntry(PolicyEntry pe,
  439. PolicyParser.PermissionEntry perm) {
  440. // remove the Permission from the GrantEntry
  441. PolicyParser.GrantEntry ppge = pe.getGrantEntry();
  442. modified = ppge.remove(perm);
  443. return modified;
  444. }
  445. /**
  446. * remove an entry from the overall policy
  447. */
  448. boolean removeEntry(PolicyEntry pe) {
  449. parser.remove(pe.getGrantEntry());
  450. modified = true;
  451. return (policyEntries.removeElement(pe));
  452. }
  453. /**
  454. * retrieve all Policy Entries
  455. */
  456. PolicyEntry[] getEntry() {
  457. if (policyEntries.size() > 0) {
  458. PolicyEntry entries[] = new PolicyEntry[policyEntries.size()];
  459. for (int i = 0; i < policyEntries.size(); i++)
  460. entries[i] = policyEntries.elementAt(i);
  461. return entries;
  462. }
  463. return null;
  464. }
  465. /**
  466. * Retrieve the public key mapped to a particular name.
  467. * If the key has expired, a KeyException is thrown.
  468. */
  469. PublicKey getPublicKeyAlias(String name) throws KeyStoreException {
  470. if (keyStore == null) {
  471. return null;
  472. }
  473. Certificate cert = keyStore.getCertificate(name);
  474. if (cert == null) {
  475. return null;
  476. }
  477. PublicKey pubKey = cert.getPublicKey();
  478. return pubKey;
  479. }
  480. /**
  481. * Retrieve all the alias names stored in the certificate database
  482. */
  483. String[] getPublicKeyAlias() throws KeyStoreException {
  484. int numAliases = 0;
  485. String aliases[] = null;
  486. if (keyStore == null) {
  487. return null;
  488. }
  489. Enumeration<String> enum_ = keyStore.aliases();
  490. // first count the number of elements
  491. while (enum_.hasMoreElements()) {
  492. enum_.nextElement();
  493. numAliases++;
  494. }
  495. if (numAliases > 0) {
  496. // now copy them into an array
  497. aliases = new String[numAliases];
  498. numAliases = 0;
  499. enum_ = keyStore.aliases();
  500. while (enum_.hasMoreElements()) {
  501. aliases[numAliases] = new String(enum_.nextElement());
  502. numAliases++;
  503. }
  504. }
  505. return aliases;
  506. }
  507. /**
  508. * This method parses a single string of signers separated by commas
  509. * ("jordan, duke, pippen") into an array of individual strings.
  510. */
  511. String[] parseSigners(String signedBy) {
  512. String signers[] = null;
  513. int numSigners = 1;
  514. int signedByIndex = 0;
  515. int commaIndex = 0;
  516. int signerNum = 0;
  517. // first pass thru "signedBy" counts the number of signers
  518. while (commaIndex >= 0) {
  519. commaIndex = signedBy.indexOf(',', signedByIndex);
  520. if (commaIndex >= 0) {
  521. numSigners++;
  522. signedByIndex = commaIndex + 1;
  523. }
  524. }
  525. signers = new String[numSigners];
  526. // second pass thru "signedBy" transfers signers to array
  527. commaIndex = 0;
  528. signedByIndex = 0;
  529. while (commaIndex >= 0) {
  530. if ((commaIndex = signedBy.indexOf(',', signedByIndex)) >= 0) {
  531. // transfer signer and ignore trailing part of the string
  532. signers[signerNum] =
  533. signedBy.substring(signedByIndex, commaIndex).trim();
  534. signerNum++;
  535. signedByIndex = commaIndex + 1;
  536. } else {
  537. // we are at the end of the string -- transfer signer
  538. signers[signerNum] = signedBy.substring(signedByIndex).trim();
  539. }
  540. }
  541. return signers;
  542. }
  543. /**
  544. * Check to see if the Principal contents are OK
  545. */
  546. void verifyPrincipal(String type, String name)
  547. throws ClassNotFoundException,
  548. InstantiationException
  549. {
  550. if (type.equals(PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
  551. type.equals(PolicyParser.PrincipalEntry.REPLACE_NAME)) {
  552. return;
  553. }
  554. Class<?> PRIN = Class.forName("java.security.Principal");
  555. Class<?> pc = Class.forName(type, true,
  556. Thread.currentThread().getContextClassLoader());
  557. if (!PRIN.isAssignableFrom(pc)) {
  558. MessageFormat form = new MessageFormat(getMessage
  559. ("Illegal.Principal.Type.type"));
  560. Object[] source = {type};
  561. throw new InstantiationException(form.format(source));
  562. }
  563. if (ToolDialog.X500_PRIN_CLASS.equals(pc.getName())) {
  564. // PolicyParser checks validity of X500Principal name
  565. // - PolicyTool needs to as well so that it doesn't store
  566. // an invalid name that can't be read in later
  567. //
  568. // this can throw an IllegalArgumentException
  569. X500Principal newP = new X500Principal(name);
  570. }
  571. }
  572. /**
  573. * Check to see if the Permission contents are OK
  574. */
  575. @SuppressWarnings("fallthrough")
  576. void verifyPermission(String type,
  577. String name,
  578. String actions)
  579. throws ClassNotFoundException,
  580. InstantiationException,
  581. IllegalAccessException,
  582. NoSuchMethodException,
  583. InvocationTargetException
  584. {
  585. //XXX we might want to keep a hash of created factories...
  586. Class<?> pc = Class.forName(type, true,
  587. Thread.currentThread().getContextClassLoader());
  588. Constructor<?> c = null;
  589. Vector<String> objects = new Vector<>(2);
  590. if (name != null) objects.add(name);
  591. if (actions != null) objects.add(actions);
  592. switch (objects.size()) {
  593. case 0:
  594. try {
  595. c = pc.getConstructor(NOPARAMS);
  596. break;
  597. } catch (NoSuchMethodException ex) {
  598. // proceed to the one-param constructor
  599. objects.add(null);
  600. }
  601. /* fall through */
  602. case 1:
  603. try {
  604. c = pc.getConstructor(ONEPARAMS);
  605. break;
  606. } catch (NoSuchMethodException ex) {
  607. // proceed to the two-param constructor
  608. objects.add(null);
  609. }
  610. /* fall through */
  611. case 2:
  612. c = pc.getConstructor(TWOPARAMS);
  613. break;
  614. }
  615. Object parameters[] = objects.toArray();
  616. Permission p = (Permission)c.newInstance(parameters);
  617. }
  618. /*
  619. * Parse command line arguments.
  620. */
  621. static void parseArgs(String args[]) {
  622. /* parse flags */
  623. int n = 0;
  624. for (n=0; (n < args.length) && args[n].startsWith("-"); n++) {
  625. String flags = args[n];
  626. if (collator.compare(flags, "-file") == 0) {
  627. if (++n == args.length) usage();
  628. policyFileName = args[n];
  629. } else {
  630. MessageFormat form = new MessageFormat(getMessage
  631. ("Illegal.option.option"));
  632. Object[] source = { flags };
  633. System.err.println(form.format(source));
  634. usage();
  635. }
  636. }
  637. }
  638. static void usage() {
  639. System.out.println(getMessage("Usage.policytool.options."));
  640. System.out.println();
  641. System.out.println(getMessage
  642. (".file.file.policy.file.location"));
  643. System.out.println();
  644. System.exit(1);
  645. }
  646. /**
  647. * run the PolicyTool
  648. */
  649. public static void main(String args[]) {
  650. parseArgs(args);
  651. SwingUtilities.invokeLater(new Runnable() {
  652. public void run() {
  653. ToolWindow tw = new ToolWindow(new PolicyTool());
  654. tw.displayToolWindow(args);
  655. }
  656. });
  657. }
  658. // split instr to words according to capitalization,
  659. // like, AWTControl -> A W T Control
  660. // this method is for easy pronounciation
  661. static String splitToWords(String instr) {
  662. return instr.replaceAll("([A-Z])", " $1");
  663. }
  664. /**
  665. * Returns the message corresponding to the key in the bundle.
  666. * This is preferred over {@link #getString} because it removes
  667. * any mnemonic '&' character in the string.
  668. *
  669. * @param key the key
  670. *
  671. * @return the message
  672. */
  673. static String getMessage(String key) {
  674. return removeMnemonicAmpersand(rb.getString(key));
  675. }
  676. /**
  677. * Returns the mnemonic for a message.
  678. *
  679. * @param key the key
  680. *
  681. * @return the mnemonic <code>int</code>
  682. */
  683. static int getMnemonicInt(String key) {
  684. String message = rb.getString(key);
  685. return (findMnemonicInt(message));
  686. }
  687. /**
  688. * Returns the mnemonic display index for a message.
  689. *
  690. * @param key the key
  691. *
  692. * @return the mnemonic display index
  693. */
  694. static int getDisplayedMnemonicIndex(String key) {
  695. String message = rb.getString(key);
  696. return (findMnemonicIndex(message));
  697. }
  698. /**
  699. * Finds the mnemonic character in a message.
  700. *
  701. * The mnemonic character is the first character followed by the first
  702. * <code>&</code> that is not followed by another <code>&</code>.
  703. *
  704. * @return the mnemonic as an <code>int</code>, or <code>0</code> if it
  705. * can't be found.
  706. */
  707. private static int findMnemonicInt(String s) {
  708. for (int i = 0; i < s.length() - 1; i++) {
  709. if (s.charAt(i) == '&') {
  710. if (s.charAt(i + 1) != '&') {
  711. return KeyEvent.getExtendedKeyCodeForChar(s.charAt(i + 1));
  712. } else {
  713. i++;
  714. }
  715. }
  716. }
  717. return 0;
  718. }
  719. /**
  720. * Finds the index of the mnemonic character in a message.
  721. *
  722. * The mnemonic character is the first character followed by the first
  723. * <code>&</code> that is not followed by another <code>&</code>.
  724. *
  725. * @return the mnemonic character index as an <code>int</code>, or <code>-1</code> if it
  726. * can't be found.
  727. */
  728. private static int findMnemonicIndex(String s) {
  729. for (int i = 0; i < s.length() - 1; i++) {
  730. if (s.charAt(i) == '&') {
  731. if (s.charAt(i + 1) != '&') {
  732. // Return the index of the '&' since it will be removed
  733. return i;
  734. } else {
  735. i++;
  736. }
  737. }
  738. }
  739. return -1;
  740. }
  741. /**
  742. * Removes the mnemonic identifier (<code>&</code>) from a string unless
  743. * it's escaped by <code>&&</code> or placed at the end.
  744. *
  745. * @param message the message
  746. *
  747. * @return a message with the mnemonic identifier removed
  748. */
  749. private static String removeMnemonicAmpersand(String message) {
  750. StringBuilder s = new StringBuilder();
  751. for (int i = 0; i < message.length(); i++) {
  752. char current = message.charAt(i);
  753. if (current != '&' || i == message.length() - 1
  754. || message.charAt(i + 1) == '&') {
  755. s.append(current);
  756. }
  757. }
  758. return s.toString();
  759. }
  760. }
  761. /**
  762. * Each entry in the policy configuration file is represented by a
  763. * PolicyEntry object.
  764. *
  765. * A PolicyEntry is a (CodeSource,Permission) pair. The
  766. * CodeSource contains the (URL, PublicKey) that together identify
  767. * where the Java bytecodes come from and who (if anyone) signed
  768. * them. The URL could refer to localhost. The URL could also be
  769. * null, meaning that this policy entry is given to all comers, as
  770. * long as they match the signer field. The signer could be null,
  771. * meaning the code is not signed.
  772. *
  773. * The Permission contains the (Type, Name, Action) triplet.
  774. *
  775. */
  776. class PolicyEntry {
  777. private CodeSource codesource;
  778. private PolicyTool tool;
  779. private PolicyParser.GrantEntry grantEntry;
  780. private boolean testing = false;
  781. /**
  782. * Create a PolicyEntry object from the information read in
  783. * from a policy file.
  784. */
  785. PolicyEntry(PolicyTool tool, PolicyParser.GrantEntry ge)
  786. throws MalformedURLException, NoSuchMethodException,
  787. ClassNotFoundException, InstantiationException, IllegalAccessException,
  788. InvocationTargetException, CertificateException,
  789. IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
  790. this.tool = tool;
  791. URL location = null;
  792. // construct the CodeSource
  793. if (ge.codeBase != null)
  794. location = new URL(ge.codeBase);
  795. this.codesource = new CodeSource(location,
  796. (java.security.cert.Certificate[]) null);
  797. if (testing) {
  798. System.out.println("Adding Policy Entry:");
  799. System.out.println(" CodeBase = " + location);
  800. System.out.println(" Signers = " + ge.signedBy);
  801. System.out.println(" with " + ge.principals.size() +
  802. " Principals");
  803. }
  804. this.grantEntry = ge;
  805. }
  806. /**
  807. * get the codesource associated with this PolicyEntry
  808. */
  809. CodeSource getCodeSource() {
  810. return codesource;
  811. }
  812. /**
  813. * get the GrantEntry associated with this PolicyEntry
  814. */
  815. PolicyParser.GrantEntry getGrantEntry() {
  816. return grantEntry;
  817. }
  818. /**
  819. * convert the header portion, i.e. codebase, signer, principals, of
  820. * this policy entry into a string
  821. */
  822. String headerToString() {
  823. String pString = principalsToString();
  824. if (pString.length() == 0) {
  825. return codebaseToString();
  826. } else {
  827. return codebaseToString() + ", " + pString;
  828. }
  829. }
  830. /**
  831. * convert the Codebase/signer portion of this policy entry into a string
  832. */
  833. String codebaseToString() {
  834. String stringEntry = new String();
  835. if (grantEntry.codeBase != null &&
  836. grantEntry.codeBase.equals("") == false)
  837. stringEntry = stringEntry.concat
  838. ("CodeBase \"" +
  839. grantEntry.codeBase +
  840. "\"");
  841. if (grantEntry.signedBy != null &&
  842. grantEntry.signedBy.equals("") == false)
  843. stringEntry = ((stringEntry.length() > 0) ?
  844. stringEntry.concat(", SignedBy \"" +
  845. grantEntry.signedBy +
  846. "\"") :
  847. stringEntry.concat("SignedBy \"" +
  848. grantEntry.signedBy +
  849. "\""));
  850. if (stringEntry.length() == 0)
  851. return new String("CodeBase <ALL>");
  852. return stringEntry;
  853. }
  854. /**
  855. * convert the Principals portion of this policy entry into a string
  856. */
  857. String principalsToString() {
  858. String result = "";
  859. if ((grantEntry.principals != null) &&
  860. (!grantEntry.principals.isEmpty())) {
  861. StringBuffer buffer = new StringBuffer(200);
  862. ListIterator<PolicyParser.PrincipalEntry> list =
  863. grantEntry.principals.listIterator();
  864. while (list.hasNext()) {
  865. PolicyParser.PrincipalEntry pppe = list.next();
  866. buffer.append(" Principal " + pppe.getDisplayClass() + " " +
  867. pppe.getDisplayName(true));
  868. if (list.hasNext()) buffer.append(", ");
  869. }
  870. result = buffer.toString();
  871. }
  872. return result;
  873. }
  874. /**
  875. * convert this policy entry into a PolicyParser.PermissionEntry
  876. */
  877. PolicyParser.PermissionEntry toPermissionEntry(Permission perm) {
  878. String actions = null;
  879. // get the actions
  880. if (perm.getActions() != null &&
  881. perm.getActions().trim() != "")
  882. actions = perm.getActions();
  883. PolicyParser.PermissionEntry pe = new PolicyParser.PermissionEntry
  884. (perm.getClass().getName(),
  885. perm.getName(),
  886. actions);
  887. return pe;
  888. }
  889. }
  890. /**
  891. * The main window for the PolicyTool
  892. */
  893. class ToolWindow extends JFrame {
  894. // use serialVersionUID from JDK 1.2.2 for interoperability
  895. private static final long serialVersionUID = 5682568601210376777L;
  896. /* ESCAPE key */
  897. static final KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
  898. /* external paddings */
  899. public static final Insets TOP_PADDING = new Insets(25,0,0,0);
  900. public static final Insets BOTTOM_PADDING = new Insets(0,0,25,0);
  901. public static final Insets LITE_BOTTOM_PADDING = new Insets(0,0,10,0);
  902. public static final Insets LR_PADDING = new Insets(0,10,0,10);
  903. public static final Insets TOP_BOTTOM_PADDING = new Insets(15, 0, 15, 0);
  904. public static final Insets L_TOP_BOTTOM_PADDING = new Insets(5,10,15,0);
  905. public static final Insets LR_TOP_BOTTOM_PADDING = new Insets(15, 4, 15, 4);
  906. public static final Insets LR_BOTTOM_PADDING = new Insets(0,10,5,10);
  907. public static final Insets L_BOTTOM_PADDING = new Insets(0,10,5,0);
  908. public static final Insets R_BOTTOM_PADDING = new Insets(0, 0, 25, 5);
  909. public static final Insets R_PADDING = new Insets(0, 0, 0, 5);
  910. /* buttons and menus */
  911. public static final String NEW_POLICY_FILE = "New";
  912. public static final String OPEN_POLICY_FILE = "Open";
  913. public static final String SAVE_POLICY_FILE = "Save";
  914. public static final String SAVE_AS_POLICY_FILE = "Save.As";
  915. public static final String VIEW_WARNINGS = "View.Warning.Log";
  916. public static final String QUIT = "Exit";
  917. public static final String ADD_POLICY_ENTRY = "Add.Policy.Entry";
  918. public static final String EDIT_POLICY_ENTRY = "Edit.Policy.Entry";
  919. public static final String REMOVE_POLICY_ENTRY = "Remove.Policy.Entry";
  920. public static final String EDIT_KEYSTORE = "Edit";
  921. public static final String ADD_PUBKEY_ALIAS = "Add.Public.Key.Alias";
  922. public static final String REMOVE_PUBKEY_ALIAS = "Remove.Public.Key.Alias";
  923. /* gridbag index for components in the main window (MW) */
  924. public static final int MW_FILENAME_LABEL = 0;
  925. public static final int MW_FILENAME_TEXTFIELD = 1;
  926. public static final int MW_PANEL = 2;
  927. public static final int MW_ADD_BUTTON = 0;
  928. public static final int MW_EDIT_BUTTON = 1;
  929. public static final int MW_REMOVE_BUTTON = 2;
  930. public static final int MW_POLICY_LIST = 3; // follows MW_PANEL
  931. /* The preferred height of JTextField should match JComboBox. */
  932. static final int TEXTFIELD_HEIGHT = new JComboBox().getPreferredSize().height;
  933. private PolicyTool tool;
  934. /**
  935. * Constructor
  936. */
  937. ToolWindow(PolicyTool tool) {
  938. this.tool = tool;
  939. }
  940. /**
  941. * Don't call getComponent directly on the window
  942. */
  943. public Component getComponent(int n) {
  944. Component c = getContentPane().getComponent(n);
  945. if (c instanceof JScrollPane) {
  946. c = ((JScrollPane)c).getViewport().getView();
  947. }
  948. return c;
  949. }
  950. /**
  951. * Initialize the PolicyTool window with the necessary components
  952. */
  953. private void initWindow() {
  954. // The ToolWindowListener will handle closing the window.
  955. setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
  956. // create the top menu bar
  957. JMenuBar menuBar = new JMenuBar();
  958. // create a File menu
  959. JMenu menu = new JMenu();
  960. configureButton(menu, "File");
  961. ActionListener actionListener = new FileMenuListener(tool, this);
  962. addMenuItem(menu, NEW_POLICY_FILE, actionListener, "N");
  963. addMenuItem(menu, OPEN_POLICY_FILE, actionListener, "O");
  964. addMenuItem(menu, SAVE_POLICY_FILE, actionListener, "S");
  965. addMenuItem(menu, SAVE_AS_POLICY_FILE, actionListener, null);
  966. addMenuItem(menu, VIEW_WARNINGS, actionListener, null);
  967. addMenuItem(menu, QUIT, actionListener, null);
  968. menuBar.add(menu);
  969. // create a KeyStore menu
  970. menu = new JMenu();
  971. configureButton(menu, "KeyStore");
  972. actionListener = new MainWindowListener(tool, this);
  973. addMenuItem(menu, EDIT_KEYSTORE, actionListener, null);
  974. menuBar.add(menu);
  975. setJMenuBar(menuBar);
  976. // Create some space around components
  977. ((JPanel)getContentPane()).setBorder(new EmptyBorder(6, 6, 6, 6));
  978. // policy entry listing
  979. JLabel label = new JLabel(PolicyTool.getMessage("Policy.File."));
  980. addNewComponent(this, label, MW_FILENAME_LABEL,
  981. 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH,
  982. LR_TOP_BOTTOM_PADDING);
  983. JTextField tf = new JTextField(50);
  984. tf.setPreferredSize(new Dimension(tf.getPreferredSize().width, TEXTFIELD_HEIGHT));
  985. tf.getAccessibleContext().setAccessibleName(
  986. PolicyTool.getMessage("Policy.File."));
  987. tf.setEditable(false);
  988. addNewComponent(this, tf, MW_FILENAME_TEXTFIELD,
  989. 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH,
  990. LR_TOP_BOTTOM_PADDING);
  991. // add ADD/REMOVE/EDIT buttons in a new panel
  992. JPanel panel = new JPanel();
  993. panel.setLayout(new GridBagLayout());
  994. JButton button = new JButton();
  995. configureButton(button, ADD_POLICY_ENTRY);
  996. button.addActionListener(new MainWindowListener(tool, this));
  997. addNewComponent(panel, button, MW_ADD_BUTTON,
  998. 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH,
  999. LR_PADDING);
  1000. button = new JButton();
  1001. configureButton(button, EDIT_POLICY_ENTRY);
  1002. button.addActionListener(new MainWindowListener(tool, this));
  1003. addNewComponent(panel, button, MW_EDIT_BUTTON,
  1004. 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH,
  1005. LR_PADDING);
  1006. button = new JButton();
  1007. configureButton(button, REMOVE_POLICY_ENTRY);
  1008. button.addActionListener(new MainWindowListener(tool, this));
  1009. addNewComponent(panel, button, MW_REMOVE_BUTTON,
  1010. 2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH,
  1011. LR_PADDING);
  1012. addNewComponent(this, panel, MW_PANEL,
  1013. 0, 2, 2, 1, 0.0, 0.0, GridBagConstraints.BOTH,
  1014. BOTTOM_PADDING);
  1015. String policyFile = tool.getPolicyFileName();
  1016. if (policyFile == null) {
  1017. String userHome;
  1018. userHome = java.security.AccessController.doPrivileged(
  1019. new sun.security.action.GetPropertyAction("user.home"));
  1020. policyFile = userHome + File.separatorChar + ".java.policy";
  1021. }
  1022. try {
  1023. // open the policy file
  1024. tool.openPolicy(policyFile);
  1025. // display the policy entries via the policy list textarea
  1026. DefaultListModel listModel = new DefaultListModel();
  1027. JList list = new JList(listModel);
  1028. list.setVisibleRowCount(15);
  1029. list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  1030. list.addMouseListener(new PolicyListListener(tool, this));
  1031. PolicyEntry entries[] = tool.getEntry();
  1032. if (entries != null) {
  1033. for (int i = 0; i < entries.length; i++) {
  1034. listModel.addElement(entries[i].headerToString());
  1035. }
  1036. }
  1037. JTextField newFilename = (JTextField)
  1038. getComponent(MW_FILENAME_TEXTFIELD);
  1039. newFilename.setText(policyFile);
  1040. initPolicyList(list);
  1041. } catch (FileNotFoundException fnfe) {
  1042. // add blank policy listing
  1043. JList list = new JList(new DefaultListModel());
  1044. list.setVisibleRowCount(15);
  1045. list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  1046. list.addMouseListener(new PolicyListListener(tool, this));
  1047. initPolicyList(list);
  1048. tool.setPolicyFileName(null);
  1049. tool.modified = false;
  1050. // just add warning
  1051. tool.warnings.addElement(fnfe.toString());
  1052. } catch (Exception e) {
  1053. // add blank policy listing
  1054. JList list = new JList(new DefaultListModel());
  1055. list.setVisibleRowCount(15);
  1056. list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  1057. list.addMouseListener(new PolicyListListener(tool, this));
  1058. initPolicyList(list);
  1059. tool.setPolicyFileName(null);
  1060. tool.modified = false;
  1061. // display the error
  1062. MessageFormat form = new MessageFormat(PolicyTool.getMessage
  1063. ("Could.not.open.policy.file.policyFile.e.toString."));
  1064. Object[] source = {policyFile, e.toString()};
  1065. displayErrorDialog(null, form.format(source));
  1066. }
  1067. }
  1068. // Platform specific modifier (control / command).
  1069. private int shortCutModifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
  1070. private void addMenuItem(JMenu menu, String key, ActionListener actionListener, String accelerator) {
  1071. JMenuItem menuItem = new JMenuItem();
  1072. configureButton(menuItem, key);
  1073. if (PolicyTool.rb.containsKey(key + ".accelerator")) {
  1074. // Accelerator from resources takes precedence
  1075. accelerator = PolicyTool.getMessage(key + ".accelerator");
  1076. }
  1077. if (accelerator != null && !accelerator.isEmpty()) {
  1078. KeyStroke keyStroke;
  1079. if (accelerator.length() == 1) {
  1080. keyStroke = KeyStroke.getKeyStroke(KeyEvent.getExtendedKeyCodeForChar(accelerator.charAt(0)),
  1081. shortCutModifier);
  1082. } else {
  1083. keyStroke = KeyStroke.getKeyStroke(accelerator);
  1084. }
  1085. menuItem.setAccelerator(keyStroke);
  1086. }
  1087. menuItem.addActionListener(actionListener);
  1088. menu.add(menuItem);
  1089. }
  1090. static void configureButton(AbstractButton button, String key) {
  1091. button.setText(PolicyTool.getMessage(key));
  1092. button.setActionCommand(key);
  1093. int mnemonicInt = PolicyTool.getMnemonicInt(key);
  1094. if (mnemonicInt > 0) {
  1095. button.setMnemonic(mnemonicInt);
  1096. button.setDisplayedMnemonicIndex(PolicyTool.getDisplayedMnemonicIndex(key));
  1097. }
  1098. }
  1099. static void configureLabelFor(JLabel label, JComponent component, String key) {
  1100. label.setText(PolicyTool.getMessage(key));
  1101. label.setLabelFor(component);
  1102. int mnemonicInt = PolicyTool.getMnemonicInt(key);
  1103. if (mnemonicInt > 0) {
  1104. label.setDisplayedMnemonic(mnemonicInt);
  1105. label.setDisplayedMnemonicIndex(PolicyTool.getDisplayedMnemonicIndex(key));
  1106. }
  1107. }
  1108. /**
  1109. * Add a component to the PolicyTool window
  1110. */
  1111. void addNewComponent(Container container, JComponent component,
  1112. int index, int gridx, int gridy, int gridwidth, int gridheight,
  1113. double weightx, double weighty, int fill, Insets is) {
  1114. if (container instanceof JFrame) {
  1115. container = ((JFrame)container).getContentPane();
  1116. } else if (container instanceof JDialog) {
  1117. container = ((JDialog)container).getContentPane();
  1118. }
  1119. // add the component at the specified gridbag index
  1120. container.add(component, index);
  1121. // set the constraints
  1122. GridBagLayout gbl = (GridBagLayout)container.getLayout();
  1123. GridBagConstraints gbc = new GridBagConstraints();
  1124. gbc.gridx = gridx;
  1125. gbc.gridy = gridy;
  1126. gbc.gridwidth = gridwidth;
  1127. gbc.gridheight = gridheight;
  1128. gbc.weightx = weightx;
  1129. gbc.weighty = weighty;
  1130. gbc.fill = fill;
  1131. if (is != null) gbc.insets = is;
  1132. gbl.setConstraints(component, gbc);
  1133. }
  1134. /**
  1135. * Add a component to the PolicyTool window without external padding
  1136. */
  1137. void addNewComponent(Container container, JComponent component,
  1138. int index, int gridx, int gridy, int gridwidth, int gridheight,
  1139. double weightx, double weighty, int fill) {
  1140. // delegate with "null" external padding
  1141. addNewComponent(container, component, index, gridx, gridy,
  1142. gridwidth, gridheight, weightx, weighty,
  1143. fill, null);
  1144. }
  1145. /**
  1146. * Init the policy_entry_list TEXTAREA component in the
  1147. * PolicyTool window
  1148. */
  1149. void initPolicyList(JList policyList) {
  1150. // add the policy list to the window
  1151. //policyList.setPreferredSize(new Dimension(500, 350));
  1152. JScrollPane scrollPane = new JScrollPane(policyList);
  1153. addNewComponent(this, scrollPane, MW_POLICY_LIST,
  1154. 0, 3, 2, 1, 1.0, 1.0, GridBagConstraints.BOTH);
  1155. }
  1156. /**
  1157. * Replace the policy_entry_list TEXTAREA component in the
  1158. * PolicyTool window with an updated one.
  1159. */
  1160. void replacePolicyList(JList policyList) {
  1161. // remove the original list of Policy Entries
  1162. // and add the new list of entries
  1163. JList list = (JList)getComponent(MW_POLICY_LIST);
  1164. list.setModel(policyList.getModel());
  1165. }
  1166. /**
  1167. * display the main PolicyTool window
  1168. */
  1169. void displayToolWindow(String args[]) {
  1170. setTitle(PolicyTool.getMessage("Policy.Tool"));
  1171. setResizable(true);
  1172. addWindowListener(new ToolWindowListener(tool, this));
  1173. //setBounds(135, 80, 500, 500);
  1174. getContentPane().setLayout(new GridBagLayout());
  1175. initWindow();
  1176. pack();
  1177. setLocationRelativeTo(null);
  1178. // display it
  1179. setVisible(true);
  1180. if (tool.newWarning == true) {
  1181. displayStatusDialog(this, PolicyTool.getMessage
  1182. ("Errors.have.occurred.while.opening.the.policy.configuration.View.the.Warning.Log.for.more.information."));
  1183. }
  1184. }
  1185. /**
  1186. * displays a dialog box describing an error which occurred.
  1187. */
  1188. void displayErrorDialog(Window w, String error) {
  1189. ToolDialog ed = new ToolDialog
  1190. (PolicyTool.getMessage("Error"), tool, this, true);
  1191. // find where the PolicyTool gui is
  1192. Point location = ((w == null) ?
  1193. getLocationOnScreen() : w.getLocationOnScreen());
  1194. //ed.setBounds(location.x + 50, location.y + 50, 600, 100);
  1195. ed.setLayout(new GridBagLayout());
  1196. JLabel label = new JLabel(error);
  1197. addNewComponent(ed, label, 0,
  1198. 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH);
  1199. JButton okButton = new JButton(PolicyTool.getMessage("OK"));
  1200. ActionListener okListener = new ErrorOKButtonListener(ed);
  1201. okButton.addActionListener(okListener);
  1202. addNewComponent(ed, okButton, 1,
  1203. 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.VERTICAL);
  1204. ed.getRootPane().setDefaultButton(okButton);
  1205. ed.getRootPane().registerKeyboardAction(okListener, escKey, JComponent.WHEN_IN_FOCUSED_WINDOW);
  1206. ed.pack();
  1207. ed.setLocationRelativeTo(w);
  1208. ed.setVisible(true);
  1209. }
  1210. /**
  1211. * displays a dialog box describing an error which occurred.
  1212. */
  1213. void displayErrorDialog(Window w, Throwable t) {
  1214. if (t instanceof NoDisplayException) {
  1215. return;
  1216. }
  1217. displayErrorDialog(w, t.toString());
  1218. }

Large files files are truncated, but you can click here to view the full file