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