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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [net/] [SocketPermission.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* SocketPermission.java -- Class modeling permissions for socket operations
2
   Copyright (C) 1998, 2000, 2001, 2002, 2004, 2006 Free Software
3
   Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
package java.net;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import java.io.IOException;
44
import java.io.ObjectInputStream;
45
import java.io.ObjectOutputStream;
46
import java.io.Serializable;
47
import java.security.Permission;
48
import java.security.PermissionCollection;
49
import java.util.StringTokenizer;
50
 
51
 
52
/**
53
 * This class models a specific set of permssions for connecting to a
54
 * host.  There are two elements to this, the host/port combination and
55
 * the permission list.
56
 * <p>
57
 * The host/port combination is specified as followed
58
 * <p>
59
 * <pre>
60
 * hostname[:[-]port[-[port]]]
61
 * </pre>
62
 * <p>
63
 * The hostname portion can be either a hostname or IP address.  If it is
64
 * a hostname, a wildcard is allowed in hostnames.  This wildcard is a "*"
65
 * and matches one or more characters.  Only one "*" may appear in the
66
 * host and it must be the leftmost character.  For example,
67
 * "*.urbanophile.com" matches all hosts in the "urbanophile.com" domain.
68
 * <p>
69
 * The port portion can be either a single value, or a range of values
70
 * treated as inclusive.  The first or the last port value in the range
71
 * can be omitted in which case either the minimum or maximum legal
72
 * value for a port (respectively) is used by default.  Here are some
73
 * examples:
74
 * <p><ul>
75
 * <li>8080 - Represents port 8080 only</li>
76
 * <li>2000-3000 - Represents ports 2000 through 3000 inclusive</li>
77
 * <li>-4000 - Represents ports 0 through 4000 inclusive</li>
78
 * <li>1024- - Represents ports 1024 through 65535 inclusive</li>
79
 * </ul><p>
80
 * The permission list is a comma separated list of individual permissions.
81
 * These individual permissions are:
82
 * <p>
83
 * <pre>
84
 * accept
85
 * connect
86
 * listen
87
 * resolve
88
 * </pre>
89
 * <p>
90
 * The "listen" permission is only relevant if the host is localhost.  If
91
 * any permission at all is specified, then resolve permission is implied to
92
 * exist.
93
 * <p>
94
 * Here are a variety of examples of how to create SocketPermission's
95
 * <p><pre>
96
 * SocketPermission("www.urbanophile.com", "connect");
97
 *   Can connect to any port on www.urbanophile.com
98
 * SocketPermission("www.urbanophile.com:80", "connect,accept");
99
 *   Can connect to or accept connections from www.urbanophile.com on port 80
100
 * SocketPermission("localhost:1024-", "listen,accept,connect");
101
 *   Can connect to, accept from, an listen on any local port number 1024
102
 *   and up.
103
 * SocketPermission("*.edu", "connect");
104
 *   Can connect to any host in the edu domain
105
 * SocketPermission("197.197.20.1", "accept");
106
 *   Can accept connections from 197.197.20.1
107
 * </pre><p>
108
 *
109
 * This class also supports IPv6 addresses.  These should be specified
110
 * in either RFC 2732 format or in full uncompressed form.
111
 *
112
 * @since 1.2
113
 *
114
 * @author Written by Aaron M. Renn (arenn@urbanophile.com)
115
 * @author Extensively modified by Gary Benson (gbenson@redhat.com)
116
 */
117
public final class SocketPermission extends Permission implements Serializable
118
{
119
  static final long serialVersionUID = -7204263841984476862L;
120
 
121
  /**
122
   * A hostname (possibly wildcarded).  Will be set if and only if
123
   * this object was initialized with a hostname.
124
   */
125
  private transient String hostname = null;
126
 
127
  /**
128
   * An IP address (IPv4 or IPv6).  Will be set if and only if this
129
   * object was initialized with a single literal IP address.
130
   */
131
  private transient InetAddress address = null;
132
 
133
  /**
134
   * A range of ports.
135
   */
136
  private transient int minport;
137
  private transient int maxport;
138
 
139
  /**
140
   * Values used for minimum and maximum ports when one or both bounds
141
   * are omitted.  This class is essentially independent of the
142
   * networking code it describes, so we do not limit ports to the
143
   * usual network limits of 1 and 65535.
144
   */
145
  private static final int MIN_PORT = 0;
146
  private static final int MAX_PORT = Integer.MAX_VALUE;
147
 
148
  /**
149
   * The actions for which we have permission.  This field is present
150
   * to make the serialized form correct and should not be used by
151
   * anything other than writeObject: everything else should use
152
   * actionmask.
153
   */
154
  private String actions;
155
 
156
  /**
157
   * A bitmask representing the actions for which we have permission.
158
   */
159
  private transient int actionmask;
160
 
161
  /**
162
   * The available actions, in the canonical order required for getActions().
163
   */
164
  private static final String[] ACTIONS = new String[] {
165
    "connect", "listen", "accept", "resolve"};
166
 
167
  /**
168
   * Initializes a new instance of <code>SocketPermission</code> with the
169
   * specified host/port combination and actions string.
170
   *
171
   * @param hostport The hostname/port number combination
172
   * @param actions The actions string
173
   */
174
  public SocketPermission(String hostport, String actions)
175
  {
176
    super(processHostport(hostport));
177
 
178
    setHostPort(getName());
179
    setActions(actions);
180
  }
181
 
182
  /**
183
   * There are two cases in which hostport needs rewriting before
184
   * being passed to the superclass constructor.  If hostport is an
185
   * empty string then it is substituted with "localhost".  And if
186
   * the host part of hostport is a literal IPv6 address in the full
187
   * uncompressed form not enclosed with "[" and "]" then we enclose
188
   * it with them.
189
   */
190
  private static String processHostport(String hostport)
191
  {
192
    if (hostport.length() == 0)
193
      return "localhost";
194
 
195
    if (hostport.charAt(0) == '[')
196
      return hostport;
197
 
198
    int colons = 0;
199
    boolean colon_allowed = true;
200
    for (int i = 0; i < hostport.length(); i++)
201
      {
202
        if (hostport.charAt(i) == ':')
203
          {
204
            if (!colon_allowed)
205
              throw new IllegalArgumentException("Ambiguous hostport part");
206
            colons++;
207
            colon_allowed = false;
208
          }
209
        else
210
          colon_allowed = true;
211
      }
212
 
213
    switch (colons)
214
      {
215
      case 0:
216
      case 1:
217
        // a hostname or IPv4 address
218
        return hostport;
219
 
220
      case 7:
221
        // an IPv6 address with no ports
222
        return "[" + hostport + "]";
223
 
224
      case 8:
225
        // an IPv6 address with ports
226
        int last_colon = hostport.lastIndexOf(':');
227
        return "[" + hostport.substring(0, last_colon) + "]"
228
          + hostport.substring(last_colon);
229
 
230
      default:
231
        throw new IllegalArgumentException("Ambiguous hostport part");
232
      }
233
  }
234
 
235
  /**
236
   * Parse the hostport argument to the constructor.
237
   */
238
  private void setHostPort(String hostport)
239
  {
240
    // Split into host and ports
241
    String host, ports;
242
    if (hostport.charAt(0) == '[')
243
      {
244
        // host is a bracketed IPv6 address
245
        int end = hostport.indexOf("]");
246
        if (end == -1)
247
          throw new IllegalArgumentException("Unmatched '['");
248
        host = hostport.substring(1, end);
249
 
250
        address = InetAddress.getByLiteral(host);
251
        if (address == null)
252
          throw new IllegalArgumentException("Bad IPv6 address");
253
 
254
        if (end == hostport.length() - 1)
255
          ports = "";
256
        else if (hostport.charAt(end + 1) == ':')
257
          ports = hostport.substring(end + 2);
258
        else
259
          throw new IllegalArgumentException("Bad character after ']'");
260
      }
261
    else
262
      {
263
        // host is a hostname or IPv4 address
264
        int sep = hostport.indexOf(":");
265
        if (sep == -1)
266
          {
267
            host = hostport;
268
            ports = "";
269
          }
270
        else
271
          {
272
            host = hostport.substring(0, sep);
273
            ports = hostport.substring(sep + 1);
274
          }
275
 
276
        address = InetAddress.getByLiteral(host);
277
        if (address == null)
278
          {
279
            if (host.lastIndexOf('*') > 0)
280
              throw new IllegalArgumentException("Bad hostname");
281
 
282
            hostname = host;
283
          }
284
      }
285
 
286
    // Parse and validate the ports
287
    if (ports.length() == 0)
288
      {
289
        minport = MIN_PORT;
290
        maxport = MAX_PORT;
291
      }
292
    else
293
      {
294
        int sep = ports.indexOf("-");
295
        if (sep == -1)
296
          {
297
            // a single port
298
            minport = maxport = Integer.parseInt(ports);
299
          }
300
        else
301
          {
302
            if (ports.indexOf("-", sep + 1) != -1)
303
              throw new IllegalArgumentException("Unexpected '-'");
304
 
305
            if (sep == 0)
306
              {
307
                // an upper bound
308
                minport = MIN_PORT;
309
                maxport = Integer.parseInt(ports.substring(1));
310
              }
311
            else if (sep == ports.length() - 1)
312
              {
313
                // a lower bound
314
                minport =
315
                  Integer.parseInt(ports.substring(0, ports.length() - 1));
316
                maxport = MAX_PORT;
317
              }
318
            else
319
              {
320
                // a range with two bounds
321
                minport = Integer.parseInt(ports.substring(0, sep));
322
                maxport = Integer.parseInt(ports.substring(sep + 1));
323
              }
324
          }
325
      }
326
  }
327
 
328
  /**
329
   * Parse the actions argument to the constructor.
330
   */
331
  private void setActions(String actionstring)
332
  {
333
    actionmask = 0;
334
 
335
    boolean resolve_needed = false;
336
    boolean resolve_present = false;
337
 
338
    StringTokenizer t = new StringTokenizer(actionstring, ",");
339
    while (t.hasMoreTokens())
340
      {
341
        String action = t.nextToken();
342
        action = action.trim().toLowerCase();
343
        setAction(action);
344
 
345
        if (action.equals("resolve"))
346
          resolve_present = true;
347
        else
348
          resolve_needed = true;
349
      }
350
 
351
    if (resolve_needed && !resolve_present)
352
      setAction("resolve");
353
  }
354
 
355
  /**
356
   * Parse one element of the actions argument to the constructor.
357
   */
358
  private void setAction(String action)
359
  {
360
    for (int i = 0; i < ACTIONS.length; i++)
361
      {
362
        if (action.equals(ACTIONS[i]))
363
          {
364
            actionmask |= 1 << i;
365
            return;
366
          }
367
      }
368
    throw new IllegalArgumentException("Unknown action " + action);
369
  }
370
 
371
  /**
372
   * Tests this object for equality against another.  This will be true if
373
   * and only if the passed object is an instance of
374
   * <code>SocketPermission</code> and both its hostname/port combination
375
   * and permissions string are identical.
376
   *
377
   * @param obj The object to test against for equality
378
   *
379
   * @return <code>true</code> if object is equal to this object,
380
   *         <code>false</code> otherwise.
381
   */
382
  public boolean equals(Object obj)
383
  {
384
    SocketPermission p;
385
 
386
    if (obj instanceof SocketPermission)
387
      p = (SocketPermission) obj;
388
    else
389
      return false;
390
 
391
    if (p.actionmask != actionmask ||
392
        p.minport != minport ||
393
        p.maxport != maxport)
394
      return false;
395
 
396
    if (address != null)
397
      {
398
        if (p.address == null)
399
          return false;
400
        else
401
          return p.address.equals(address);
402
      }
403
    else
404
      {
405
        if (p.hostname == null)
406
          return false;
407
        else
408
          return p.hostname.equals(hostname);
409
      }
410
  }
411
 
412
  /**
413
   * Returns a hash code value for this object.  Overrides the
414
   * <code>Permission.hashCode()</code>.
415
   *
416
   * @return A hash code
417
   */
418
  public int hashCode()
419
  {
420
    int code = actionmask + minport + maxport;
421
    if (address != null)
422
      code += address.hashCode();
423
    else
424
      code += hostname.hashCode();
425
    return code;
426
  }
427
 
428
  /**
429
   * Returns the list of permission actions in this object in canonical
430
   * order.  The canonical order is "connect,listen,accept,resolve"
431
   *
432
   * @return The permitted action string.
433
   */
434
  public String getActions()
435
  {
436
    CPStringBuilder sb = new CPStringBuilder("");
437
 
438
    for (int i = 0; i < ACTIONS.length; i++)
439
      {
440
        if ((actionmask & (1 << i)) != 0)
441
          {
442
            if (sb.length() != 0)
443
              sb.append(",");
444
            sb.append(ACTIONS[i]);
445
          }
446
      }
447
 
448
    return sb.toString();
449
  }
450
 
451
  /**
452
   * Returns a new <code>PermissionCollection</code> object that can hold
453
   * <code>SocketPermission</code>'s.
454
   *
455
   * @return A new <code>PermissionCollection</code>.
456
   */
457
  public PermissionCollection newPermissionCollection()
458
  {
459
    // FIXME: Implement
460
 
461
    return null;
462
  }
463
 
464
  /**
465
   * Returns an array of all IP addresses represented by this object.
466
   */
467
  private InetAddress[] getAddresses()
468
  {
469
    if (address != null)
470
      return new InetAddress[] {address};
471
 
472
    try
473
      {
474
        return InetAddress.getAllByName(hostname);
475
      }
476
    catch (UnknownHostException e)
477
      {
478
        return new InetAddress[0];
479
      }
480
  }
481
 
482
  /**
483
   * Returns the canonical hostname represented by this object,
484
   * or null if this object represents a wildcarded domain.
485
   */
486
  private String getCanonicalHostName()
487
  {
488
    if (address != null)
489
      return address.internalGetCanonicalHostName();
490
    if (hostname.charAt(0) == '*')
491
      return null;
492
    try
493
      {
494
        return InetAddress.getByName(hostname).internalGetCanonicalHostName();
495
      }
496
    catch (UnknownHostException e)
497
      {
498
        return null;
499
      }
500
  }
501
 
502
  /**
503
   * Returns true if the permission object passed it is implied by the
504
   * this permission.  This will be true if:
505
   *
506
   * <ul>
507
   * <li>The argument is of type <code>SocketPermission</code></li>
508
   * <li>The actions list of the argument are in this object's actions</li>
509
   * <li>The port range of the argument is within this objects port range</li>
510
   * <li>The hostname is equal to or a subset of this objects hostname</li>
511
   * </ul>
512
   *
513
   * <p>The argument's hostname will be a subset of this object's hostname if:</p>
514
   *
515
   * <ul>
516
   * <li>The argument's hostname or IP address is equal to this object's.</li>
517
   * <li>The argument's canonical hostname is equal to this object's.</li>
518
   * <li>The argument's canonical name matches this domains hostname with
519
   * wildcards</li>
520
   * </ul>
521
   *
522
   * @param perm The <code>Permission</code> to check against
523
   *
524
   * @return <code>true</code> if the <code>Permission</code> is implied by
525
   * this object, <code>false</code> otherwise.
526
   */
527
  public boolean implies(Permission perm)
528
  {
529
    SocketPermission p;
530
 
531
    // First make sure we are the right object type
532
    if (perm instanceof SocketPermission)
533
      p = (SocketPermission) perm;
534
    else
535
      return false;
536
 
537
    // If p was initialised with an empty hostname then we do not
538
    // imply it. This is not part of the spec, but it seems necessary.
539
    if (p.hostname != null && p.hostname.length() == 0)
540
      return false;
541
 
542
    // Next check the actions
543
    if ((p.actionmask & actionmask) != p.actionmask)
544
        return false;
545
 
546
    // Then check the ports
547
    if ((p.minport < minport) || (p.maxport > maxport))
548
      return false;
549
 
550
    // Finally check the hosts
551
    String p_canon = null;
552
 
553
    // Return true if this object was initialized with a single
554
    // IP address which one of p's IP addresses is equal to.
555
    if (address != null)
556
      {
557
        InetAddress[] addrs = p.getAddresses();
558
        for (int i = 0; i < addrs.length; i++)
559
          {
560
            if (address.equals(addrs[i]))
561
              return true;
562
          }
563
      }
564
 
565
    // Return true if this object is a wildcarded domain that
566
    // p's canonical name matches.
567
    if (hostname != null && hostname.charAt(0) == '*')
568
      {
569
        p_canon = p.getCanonicalHostName();
570
        if (p_canon != null && p_canon.endsWith(hostname.substring(1)))
571
          return true;
572
 
573
      }
574
 
575
    // Return true if this one of this object's IP addresses
576
    // is equal to one of p's.
577
    if (address == null)
578
      {
579
        InetAddress[] addrs = p.getAddresses();
580
        InetAddress[] p_addrs = p.getAddresses();
581
 
582
        for (int i = 0; i < addrs.length; i++)
583
          {
584
            for (int j = 0; j < p_addrs.length; j++)
585
              {
586
                if (addrs[i].equals(p_addrs[j]))
587
                  return true;
588
              }
589
          }
590
      }
591
 
592
    // Return true if this object's canonical name equals p's.
593
    String canon = getCanonicalHostName();
594
    if (canon != null)
595
      {
596
        if (p_canon == null)
597
          p_canon = p.getCanonicalHostName();
598
        if (p_canon != null && canon.equals(p_canon))
599
          return true;
600
      }
601
 
602
    // Didn't make it
603
    return false;
604
  }
605
 
606
  /**
607
   * Deserializes a <code>SocketPermission</code> object from
608
   * an input stream.
609
   *
610
   * @param input the input stream.
611
   * @throws IOException if an I/O error occurs in the stream.
612
   * @throws ClassNotFoundException if the class of the
613
   *         serialized object could not be found.
614
   */
615
  private void readObject(ObjectInputStream input)
616
    throws IOException, ClassNotFoundException
617
  {
618
    input.defaultReadObject();
619
    setHostPort(getName());
620
    setActions(actions);
621
  }
622
 
623
  /**
624
   * Serializes a <code>SocketPermission</code> object to an
625
   * output stream.
626
   *
627
   * @param output the output stream.
628
   * @throws IOException if an I/O error occurs in the stream.
629
   */
630
  private void writeObject(ObjectOutputStream output)
631
    throws IOException
632
  {
633
    actions = getActions();
634
    output.defaultWriteObject();
635
  }
636
}

powered by: WebSVN 2.1.0

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