OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [security/] [PolicyFile.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* PolicyFile.java -- policy file reader
2
   Copyright (C) 2004, 2005, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.java.security;
39
 
40
import gnu.classpath.debug.Component;
41
import gnu.classpath.debug.SystemLogger;
42
 
43
import gnu.java.lang.CPStringBuilder;
44
import gnu.java.security.action.GetPropertyAction;
45
 
46
import java.io.File;
47
import java.io.IOException;
48
import java.io.InputStreamReader;
49
import java.io.StreamTokenizer;
50
import java.lang.reflect.Constructor;
51
import java.net.MalformedURLException;
52
import java.net.URL;
53
import java.security.AccessController;
54
import java.security.CodeSource;
55
import java.security.KeyStore;
56
import java.security.KeyStoreException;
57
import java.security.Permission;
58
import java.security.PermissionCollection;
59
import java.security.Permissions;
60
import java.security.Policy;
61
import java.security.Principal;
62
import java.security.PrivilegedActionException;
63
import java.security.PrivilegedExceptionAction;
64
import java.security.Security;
65
import java.security.UnresolvedPermission;
66
import java.security.cert.Certificate;
67
import java.security.cert.X509Certificate;
68
import java.util.Enumeration;
69
import java.util.HashMap;
70
import java.util.Iterator;
71
import java.util.LinkedList;
72
import java.util.List;
73
import java.util.Map;
74
import java.util.StringTokenizer;
75
import java.util.logging.Logger;
76
 
77
/**
78
 * An implementation of a {@link java.security.Policy} object whose
79
 * permissions are specified by a <em>policy file</em>.
80
 *
81
 * <p>The approximate syntax of policy files is:</p>
82
 *
83
 * <pre>
84
 * policyFile ::= keystoreOrGrantEntries ;
85
 *
86
 * keystoreOrGrantEntries ::= keystoreOrGrantEntry |
87
 *                            keystoreOrGrantEntries keystoreOrGrantEntry |
88
 *                            EMPTY ;
89
 *
90
 * keystoreOrGrantEntry ::= keystoreEntry | grantEntry ;
91
 *
92
 * keystoreEntry ::= "keystore" keystoreUrl ';' |
93
 *                   "keystore" keystoreUrl ',' keystoreAlgorithm ';' ;
94
 *
95
 * keystoreUrl ::= URL ;
96
 * keystoreAlgorithm ::= STRING ;
97
 *
98
 * grantEntry ::= "grant" domainParameters '{' permissions '}' ';'
99
 *
100
 * domainParameters ::= domainParameter |
101
 *                      domainParameter ',' domainParameters ;
102
 *
103
 * domainParameter ::= "signedBy" signerNames |
104
 *                     "codeBase" codeBaseUrl |
105
 *                     "principal" principalClassName principalName |
106
 *                     "principal" principalName ;
107
 *
108
 * signerNames ::= quotedString ;
109
 * codeBaseUrl ::= URL ;
110
 * principalClassName ::= STRING ;
111
 * principalName ::= quotedString ;
112
 *
113
 * quotedString ::= quoteChar STRING quoteChar ;
114
 * quoteChar ::= '"' | '\'';
115
 *
116
 * permissions ::= permission | permissions permission ;
117
 *
118
 * permission ::= "permission" permissionClassName permissionTarget permissionAction |
119
 *                "permission" permissionClassName permissionTarget |
120
 *                "permission" permissionClassName;
121
 * </pre>
122
 *
123
 * <p>Comments are either form of Java comments. Keystore entries only
124
 * affect subsequent grant entries, so if a grant entry preceeds a
125
 * keystore entry, that grant entry is not affected by that keystore
126
 * entry. Certian instances of <code>${property-name}</code> will be
127
 * replaced with <code>System.getProperty("property-name")</code> in
128
 * quoted strings.</p>
129
 *
130
 * <p>This class will load the following files when created or
131
 * refreshed, in order:</p>
132
 *
133
 * <ol>
134
 * <li>The file <code>${java.home}/lib/security/java.policy</code>.</li>
135
 * <li>All URLs specified by security properties
136
 * <code>"policy.file.<i>n</i>"</code>, for increasing <i>n</i>
137
 * starting from 1. The sequence stops at the first undefined
138
 * property, so you must set <code>"policy.file.1"</code> if you also
139
 * set <code>"policy.file.2"</code>, and so on.</li>
140
 * <li>The URL specified by the property
141
 * <code>"java.security.policy"</code>.</li>
142
 * </ol>
143
 *
144
 * @author Casey Marshall (csm@gnu.org)
145
 * @see java.security.Policy
146
 */
147
public final class PolicyFile extends Policy
148
{
149
 
150
  // Constants and fields.
151
  // -------------------------------------------------------------------------
152
 
153
  protected static final Logger logger = SystemLogger.SYSTEM;
154
  // Added to cut redundant AccessController.doPrivileged calls
155
  private static GetPropertyAction prop = new GetPropertyAction("file.separator");
156
  private static final String fs = (String) AccessController.doPrivileged(prop);
157
 
158
  private static final String DEFAULT_POLICY =
159
    (String) AccessController.doPrivileged(prop.setParameters("java.home"))
160
    + fs + "lib" + fs + "security" + fs + "java.policy";
161
  private static final String DEFAULT_USER_POLICY =
162
    (String) AccessController.doPrivileged(prop.setParameters("user.home")) +
163
    fs + ".java.policy";
164
 
165
  private final Map cs2pc;
166
 
167
  // Constructors.
168
  // -------------------------------------------------------------------------
169
 
170
  public PolicyFile()
171
  {
172
    cs2pc = new HashMap();
173
    refresh();
174
  }
175
 
176
  // Instance methods.
177
  // -------------------------------------------------------------------------
178
 
179
  public PermissionCollection getPermissions(CodeSource codeSource)
180
  {
181
    Permissions perms = new Permissions();
182
    for (Iterator it = cs2pc.entrySet().iterator(); it.hasNext(); )
183
      {
184
        Map.Entry e = (Map.Entry) it.next();
185
        CodeSource cs = (CodeSource) e.getKey();
186
        if (cs.implies(codeSource))
187
          {
188
            logger.log (Component.POLICY, "{0} -> {1}", new Object[]
189
              { cs, codeSource });
190
            PermissionCollection pc = (PermissionCollection) e.getValue();
191
            for (Enumeration ee = pc.elements(); ee.hasMoreElements(); )
192
              {
193
                perms.add((Permission) ee.nextElement());
194
              }
195
          }
196
        else
197
          logger.log (Component.POLICY, "{0} !-> {1}", new Object[]
198
            { cs, codeSource });
199
      }
200
    logger.log (Component.POLICY, "returning permissions {0} for {1}",
201
                new Object[] { perms, codeSource });
202
    return perms;
203
  }
204
 
205
  public void refresh()
206
  {
207
    cs2pc.clear();
208
    final List policyFiles = new LinkedList();
209
    try
210
      {
211
        policyFiles.add (new File (DEFAULT_POLICY).toURL());
212
        policyFiles.add (new File (DEFAULT_USER_POLICY).toURL ());
213
 
214
        AccessController.doPrivileged(
215
          new PrivilegedExceptionAction()
216
          {
217
            public Object run() throws Exception
218
            {
219
              String allow = Security.getProperty ("policy.allowSystemProperty");
220
              if (allow == null || Boolean.getBoolean (allow))
221
                {
222
                  String s = System.getProperty ("java.security.policy");
223
                  logger.log (Component.POLICY, "java.security.policy={0}", s);
224
                  if (s != null)
225
                    {
226
                      boolean only = s.startsWith ("=");
227
                      if (only)
228
                        s = s.substring (1);
229
                      policyFiles.clear ();
230
                      policyFiles.add (new URL (s));
231
                      if (only)
232
                        return null;
233
                    }
234
                }
235
              for (int i = 1; ; i++)
236
                {
237
                  String pname = "policy.url." + i;
238
                  String s = Security.getProperty (pname);
239
                  logger.log (Component.POLICY, "{0}={1}", new Object []
240
                    { pname, s });
241
                  if (s == null)
242
                    break;
243
                  policyFiles.add (new URL (s));
244
                }
245
              return null;
246
            }
247
          });
248
      }
249
    catch (PrivilegedActionException pae)
250
      {
251
        logger.log (Component.POLICY, "reading policy properties", pae);
252
      }
253
    catch (MalformedURLException mue)
254
      {
255
        logger.log (Component.POLICY, "setting default policies", mue);
256
      }
257
 
258
    logger.log (Component.POLICY, "building policy from URLs {0}",
259
                policyFiles);
260
    for (Iterator it = policyFiles.iterator(); it.hasNext(); )
261
      {
262
        try
263
          {
264
            URL url = (URL) it.next();
265
            parse(url);
266
          }
267
        catch (IOException ioe)
268
          {
269
            logger.log (Component.POLICY, "reading policy", ioe);
270
          }
271
      }
272
  }
273
 
274
  public String toString()
275
  {
276
    return super.toString() + " [ " + cs2pc.toString() + " ]";
277
  }
278
 
279
  // Own methods.
280
  // -------------------------------------------------------------------------
281
 
282
  private static final int STATE_BEGIN = 0;
283
  private static final int STATE_GRANT = 1;
284
  private static final int STATE_PERMS = 2;
285
 
286
  /**
287
   * Parse a policy file, incorporating the permission definitions
288
   * described therein.
289
   *
290
   * @param url The URL of the policy file to read.
291
   * @throws IOException if an I/O error occurs, or if the policy file
292
   * cannot be parsed.
293
   */
294
  private void parse(final URL url) throws IOException
295
  {
296
    logger.log (Component.POLICY, "reading policy file from {0}", url);
297
    final StreamTokenizer in = new StreamTokenizer(new InputStreamReader(url.openStream()));
298
    in.resetSyntax();
299
    in.slashSlashComments(true);
300
    in.slashStarComments(true);
301
    in.wordChars('A', 'Z');
302
    in.wordChars('a', 'z');
303
    in.wordChars('0', '9');
304
    in.wordChars('.', '.');
305
    in.wordChars('_', '_');
306
    in.wordChars('$', '$');
307
    in.whitespaceChars(' ', ' ');
308
    in.whitespaceChars('\t', '\t');
309
    in.whitespaceChars('\f', '\f');
310
    in.whitespaceChars('\n', '\n');
311
    in.whitespaceChars('\r', '\r');
312
    in.quoteChar('\'');
313
    in.quoteChar('"');
314
 
315
    int tok;
316
    int state = STATE_BEGIN;
317
    List keystores = new LinkedList();
318
    URL currentBase = null;
319
    List currentCerts = new LinkedList();
320
    Permissions currentPerms = new Permissions();
321
    while ((tok = in.nextToken()) != StreamTokenizer.TT_EOF)
322
      {
323
        switch (tok)
324
          {
325
          case '{':
326
            if (state != STATE_GRANT)
327
              error(url, in, "spurious '{'");
328
            state = STATE_PERMS;
329
            tok = in.nextToken();
330
            break;
331
          case '}':
332
            if (state != STATE_PERMS)
333
              error(url, in, "spurious '}'");
334
            state = STATE_BEGIN;
335
            currentPerms.setReadOnly();
336
            Certificate[] c = null;
337
            if (!currentCerts.isEmpty())
338
              c = (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()]);
339
            cs2pc.put(new CodeSource(currentBase, c), currentPerms);
340
            currentCerts.clear();
341
            currentPerms = new Permissions();
342
            currentBase = null;
343
            tok = in.nextToken();
344
            if (tok != ';')
345
              in.pushBack();
346
            continue;
347
          }
348
        if (tok != StreamTokenizer.TT_WORD)
349
          {
350
            error(url, in, "expecting word token");
351
          }
352
 
353
        // keystore "<keystore-path>" [',' "<keystore-type>"] ';'
354
        if (in.sval.equalsIgnoreCase("keystore"))
355
          {
356
            String alg = KeyStore.getDefaultType();
357
            tok = in.nextToken();
358
            if (tok != '"' && tok != '\'')
359
              error(url, in, "expecting key store URL");
360
            String store = in.sval;
361
            tok = in.nextToken();
362
            if (tok == ',')
363
              {
364
                tok = in.nextToken();
365
                if (tok != '"' && tok != '\'')
366
                  error(url, in, "expecting key store type");
367
                alg = in.sval;
368
                tok = in.nextToken();
369
              }
370
            if (tok != ';')
371
              error(url, in, "expecting semicolon");
372
            try
373
              {
374
                KeyStore keystore = KeyStore.getInstance(alg);
375
                keystore.load(new URL(url, store).openStream(), null);
376
                keystores.add(keystore);
377
              }
378
            catch (Exception x)
379
              {
380
                error(url, in, x.toString());
381
              }
382
          }
383
        else if (in.sval.equalsIgnoreCase("grant"))
384
          {
385
            if (state != STATE_BEGIN)
386
              error(url, in, "extraneous grant keyword");
387
            state = STATE_GRANT;
388
          }
389
        else if (in.sval.equalsIgnoreCase("signedBy"))
390
          {
391
            if (state != STATE_GRANT && state != STATE_PERMS)
392
              error(url, in, "spurious 'signedBy'");
393
            if (keystores.isEmpty())
394
              error(url, in, "'signedBy' with no keystores");
395
            tok = in.nextToken();
396
            if (tok != '"' && tok != '\'')
397
              error(url, in, "expecting signedBy name");
398
            StringTokenizer st = new StringTokenizer(in.sval, ",");
399
            while (st.hasMoreTokens())
400
              {
401
                String alias = st.nextToken();
402
                for (Iterator it = keystores.iterator(); it.hasNext(); )
403
                  {
404
                    KeyStore keystore = (KeyStore) it.next();
405
                    try
406
                      {
407
                        if (keystore.isCertificateEntry(alias))
408
                          currentCerts.add(keystore.getCertificate(alias));
409
                      }
410
                    catch (KeyStoreException kse)
411
                      {
412
                        error(url, in, kse.toString());
413
                      }
414
                  }
415
              }
416
            tok = in.nextToken();
417
            if (tok != ',')
418
              {
419
                if (state != STATE_GRANT)
420
                  error(url, in, "spurious ','");
421
                in.pushBack();
422
              }
423
          }
424
        else if (in.sval.equalsIgnoreCase("codeBase"))
425
          {
426
            if (state != STATE_GRANT)
427
              error(url, in, "spurious 'codeBase'");
428
            tok = in.nextToken();
429
            if (tok != '"' && tok != '\'')
430
              error(url, in, "expecting code base URL");
431
            String base = expand(in.sval);
432
            if (File.separatorChar != '/')
433
              base = base.replace(File.separatorChar, '/');
434
            try
435
              {
436
                currentBase = new URL(base);
437
              }
438
            catch (MalformedURLException mue)
439
              {
440
                error(url, in, mue.toString());
441
              }
442
            tok = in.nextToken();
443
            if (tok != ',')
444
              in.pushBack();
445
          }
446
        else if (in.sval.equalsIgnoreCase("principal"))
447
          {
448
            if (state != STATE_GRANT)
449
              error(url, in, "spurious 'principal'");
450
            tok = in.nextToken();
451
            if (tok == StreamTokenizer.TT_WORD)
452
              {
453
                tok = in.nextToken();
454
                if (tok != '"' && tok != '\'')
455
                  error(url, in, "expecting principal name");
456
                String name = in.sval;
457
                Principal p = null;
458
                try
459
                  {
460
                    Class pclass = Class.forName(in.sval);
461
                    Constructor c =
462
                      pclass.getConstructor(new Class[] { String.class });
463
                    p = (Principal) c.newInstance(new Object[] { name });
464
                  }
465
                catch (Exception x)
466
                  {
467
                    error(url, in, x.toString());
468
                  }
469
                for (Iterator it = keystores.iterator(); it.hasNext(); )
470
                  {
471
                    KeyStore ks = (KeyStore) it.next();
472
                    try
473
                      {
474
                        for (Enumeration e = ks.aliases(); e.hasMoreElements(); )
475
                          {
476
                            String alias = (String) e.nextElement();
477
                            if (ks.isCertificateEntry(alias))
478
                              {
479
                                Certificate cert = ks.getCertificate(alias);
480
                                if (!(cert instanceof X509Certificate))
481
                                  continue;
482
                                if (p.equals(((X509Certificate) cert).getSubjectDN()) ||
483
                                    p.equals(((X509Certificate) cert).getSubjectX500Principal()))
484
                                  currentCerts.add(cert);
485
                              }
486
                          }
487
                      }
488
                    catch (KeyStoreException kse)
489
                      {
490
                        error(url, in, kse.toString());
491
                      }
492
                  }
493
              }
494
            else if (tok == '"' || tok == '\'')
495
              {
496
                String alias = in.sval;
497
                for (Iterator it = keystores.iterator(); it.hasNext(); )
498
                  {
499
                    KeyStore ks = (KeyStore) it.next();
500
                    try
501
                      {
502
                        if (ks.isCertificateEntry(alias))
503
                          currentCerts.add(ks.getCertificate(alias));
504
                      }
505
                    catch (KeyStoreException kse)
506
                      {
507
                        error(url, in, kse.toString());
508
                      }
509
                  }
510
              }
511
            else
512
              error(url, in, "expecting principal");
513
            tok = in.nextToken();
514
            if (tok != ',')
515
              in.pushBack();
516
          }
517
        else if (in.sval.equalsIgnoreCase("permission"))
518
          {
519
            if (state != STATE_PERMS)
520
              error(url, in, "spurious 'permission'");
521
            tok = in.nextToken();
522
            if (tok != StreamTokenizer.TT_WORD)
523
              error(url, in, "expecting permission class name");
524
            String className = in.sval;
525
            Class clazz = null;
526
            try
527
              {
528
                clazz = Class.forName(className);
529
              }
530
            catch (ClassNotFoundException cnfe)
531
              {
532
              }
533
            tok = in.nextToken();
534
            if (tok == ';')
535
              {
536
                if (clazz == null)
537
                  {
538
                    currentPerms.add(new UnresolvedPermission(className,
539
                      null, null, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()])));
540
                    continue;
541
                  }
542
                try
543
                  {
544
                    currentPerms.add((Permission) clazz.newInstance());
545
                  }
546
                catch (Exception x)
547
                  {
548
                    error(url, in, x.toString());
549
                  }
550
                continue;
551
              }
552
            if (tok != '"' && tok != '\'')
553
              error(url, in, "expecting permission target");
554
            String target = expand(in.sval);
555
            tok = in.nextToken();
556
            if (tok == ';')
557
              {
558
                if (clazz == null)
559
                  {
560
                    currentPerms.add(new UnresolvedPermission(className,
561
                      target, null, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()])));
562
                    continue;
563
                  }
564
                try
565
                  {
566
                    Constructor c =
567
                      clazz.getConstructor(new Class[] { String.class });
568
                    currentPerms.add((Permission) c.newInstance(
569
                      new Object[] { target }));
570
                  }
571
                catch (Exception x)
572
                  {
573
                    error(url, in, x.toString());
574
                  }
575
                continue;
576
              }
577
            if (tok != ',')
578
              error(url, in, "expecting ','");
579
            tok = in.nextToken();
580
            if (tok == StreamTokenizer.TT_WORD)
581
              {
582
                if (!in.sval.equalsIgnoreCase("signedBy"))
583
                  error(url, in, "expecting 'signedBy'");
584
                try
585
                  {
586
                    Constructor c =
587
                      clazz.getConstructor(new Class[] { String.class });
588
                    currentPerms.add((Permission) c.newInstance(
589
                      new Object[] { target }));
590
                  }
591
                catch (Exception x)
592
                  {
593
                    error(url, in, x.toString());
594
                  }
595
                in.pushBack();
596
                continue;
597
              }
598
            if (tok != '"' && tok != '\'')
599
              error(url, in, "expecting permission action");
600
            String action = in.sval;
601
            if (clazz == null)
602
              {
603
                currentPerms.add(new UnresolvedPermission(className,
604
                  target, action, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()])));
605
                continue;
606
              }
607
            else
608
              {
609
                try
610
                  {
611
                    Constructor c = clazz.getConstructor(
612
                      new Class[] { String.class, String.class });
613
                    currentPerms.add((Permission) c.newInstance(
614
                      new Object[] { target, action }));
615
                  }
616
                catch (Exception x)
617
                  {
618
                    error(url, in, x.toString());
619
                  }
620
              }
621
            tok = in.nextToken();
622
            if (tok != ';' && tok != ',')
623
              error(url, in, "expecting ';' or ','");
624
          }
625
      }
626
  }
627
 
628
  /**
629
   * Expand all instances of <code>"${property-name}"</code> into
630
   * <code>System.getProperty("property-name")</code>.
631
   */
632
  private static String expand(final String s)
633
  {
634
    final CPStringBuilder result = new CPStringBuilder();
635
    final CPStringBuilder prop = new CPStringBuilder();
636
    int state = 0;
637
    for (int i = 0; i < s.length(); i++)
638
      {
639
        switch (state)
640
          {
641
          case 0:
642
            if (s.charAt(i) == '$')
643
              state = 1;
644
            else
645
              result.append(s.charAt(i));
646
            break;
647
          case 1:
648
            if (s.charAt(i) == '{')
649
              state = 2;
650
            else
651
              {
652
                state = 0;
653
                result.append('$').append(s.charAt(i));
654
              }
655
            break;
656
          case 2:
657
            if (s.charAt(i) == '}')
658
              {
659
                String p = prop.toString();
660
                if (p.equals("/"))
661
                  p = "file.separator";
662
                p = System.getProperty(p);
663
                if (p == null)
664
                  p = "";
665
                result.append(p);
666
                prop.setLength(0);
667
                state = 0;
668
              }
669
            else
670
              prop.append(s.charAt(i));
671
            break;
672
          }
673
      }
674
    if (state != 0)
675
      result.append('$').append('{').append(prop);
676
    return result.toString();
677
  }
678
 
679
  /**
680
   * I miss macros.
681
   */
682
  private static void error(URL base, StreamTokenizer in, String msg)
683
    throws IOException
684
  {
685
    throw new IOException(base+":"+in.lineno()+": "+msg);
686
  }
687
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.