View Javadoc

1   package com.atlassian.security.auth.trustedapps;
2   
3   import java.util.Iterator;
4   import java.util.LinkedList;
5   import java.util.List;
6   import java.util.Set;
7   import java.util.StringTokenizer;
8   
9   /**
10   * simple list based implementation. Matches using exact matches or wildcards like: 192.168.*.* or 192.145.372.*
11   */
12  public class DefaultIPMatcher implements IPMatcher
13  {
14      private static class AddressMask
15      {
16          private final int address;
17          private final int mask;
18  
19          public AddressMask(int address, int mask)
20          {
21              this.address = address;
22              this.mask = mask;
23          }
24  
25          public boolean matches(int otherAddress)
26          {
27              return address == (otherAddress & mask);
28          }
29  
30          static AddressMask create(int[] pattern)
31          {
32              int address = 0;
33              int mask = 0;
34  
35              for (int i = 0; i < pattern.length; i++)
36              {
37                  address = address << 8;
38                  mask = mask << 8;
39  
40                  if (pattern[i] != -1)
41                  {
42                      address = address | pattern[i];
43                      mask = mask | 0xFF;
44                  }
45              }
46  
47              return new AddressMask(address, mask);
48          }
49      }
50  
51      private static final String WILDCARD = "*";
52  
53      private final List /*<AddressMask>*/ addressMasks;
54  
55      /**
56       * Main ctor.
57       * 
58       * @param patterns the Set<String> of allowed pattern Strings
59       * @throws IPAddressFormatException if the pattern does not represent a valid IP address
60       */
61      public DefaultIPMatcher(Set patterns) throws IPAddressFormatException
62      {
63          this.addressMasks = new LinkedList();
64          for (Iterator iterator = patterns.iterator(); iterator.hasNext();)
65          {
66              String patternStr = (String) iterator.next();
67              int[] pattern = parsePatternString(patternStr);
68              addressMasks.add(AddressMask.create(pattern));
69          }
70      }
71  
72      private int[] parsePatternString(String patternStr)
73      {
74          int[] pattern = new int[4];
75          StringTokenizer st = new StringTokenizer(patternStr, ".");
76          if (st.countTokens() != 4)
77          {
78              throw new IPAddressFormatException(patternStr);
79          }
80  
81          for (int i = 0; i < 4; i++)
82          {
83              final String token = st.nextToken().trim();
84              if (WILDCARD.equals(token))
85              {
86                  pattern[i] = -1;
87              }
88              else
89              {
90                  try
91                  {
92                      int value = Integer.valueOf(token).intValue();
93  
94                      if ((value < 0) || value > 255)
95                      {
96                          throw new IPAddressFormatException(patternStr);
97                      }
98  
99                      pattern[i] = value;
100                 }
101                 catch (NumberFormatException e)
102                 {
103                     throw new IPAddressFormatException(patternStr);
104                 }
105             }
106         }
107         return pattern;
108     }
109 
110     public boolean match(String ipAddress)
111     {
112         if (addressMasks.isEmpty())
113         {
114             return true;
115         }
116 
117         int address = toAddress(ipAddress);
118 
119         for (Iterator iterator = addressMasks.iterator(); iterator.hasNext();)
120         {
121             AddressMask addressMask = (AddressMask) iterator.next();
122             if (addressMask.matches(address))
123             {
124                 return true;
125             }
126         }
127         return false;
128     }
129 
130     private int toAddress(String ipAddress)
131     {
132         int address = 0;
133         int[] parsedIPAddr = parsePatternString(ipAddress);
134         for (int i = 0; i < parsedIPAddr.length; i++)
135         {
136             address = address << 8;
137             address = address | parsedIPAddr[i];
138         }
139         return address;
140     }
141 }