|
4 | 4 | import struct
|
5 | 5 | import base64
|
6 | 6 | import time
|
| 7 | +from ipaddress import AddressValueError |
| 8 | +from ipaddress import IPv4Address |
| 9 | +from ipaddress import IPv6Address |
7 | 10 |
|
8 | 11 | from saml2 import time_util
|
9 | 12 |
|
@@ -112,55 +115,30 @@ def validate_before(not_before, slack):
|
112 | 115 |
|
113 | 116 |
|
114 | 117 | def valid_address(address):
|
| 118 | + """Validate IPv4/IPv6 addresses.""" |
115 | 119 | if not (valid_ipv4(address) or valid_ipv6(address)):
|
116 | 120 | raise NotValid("address")
|
117 | 121 | return True
|
118 | 122 |
|
119 | 123 |
|
120 | 124 | def valid_ipv4(address):
|
121 |
| - parts = address.split(".") |
122 |
| - if len(parts) != 4: |
| 125 | + """Validate IPv4 addresses.""" |
| 126 | + try: |
| 127 | + IPv4Address(address) |
| 128 | + except AddressValueError: |
123 | 129 | return False
|
124 |
| - for item in parts: |
125 |
| - try: |
126 |
| - if not 0 <= int(item) <= 255: |
127 |
| - raise NotValid("ipv4") |
128 |
| - except ValueError: |
129 |
| - return False |
130 | 130 | return True
|
131 | 131 |
|
132 |
| -# |
133 |
| -IPV6_PATTERN = re.compile(r""" |
134 |
| - ^ |
135 |
| - \s* # Leading whitespace |
136 |
| - (?!.*::.*::) # Only a single wildcard allowed |
137 |
| - (?:(?!:)|:(?=:)) # Colon iff it would be part of a wildcard |
138 |
| - (?: # Repeat 6 times: |
139 |
| - [0-9a-f]{0,4} # A group of at most four hexadecimal digits |
140 |
| - (?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard |
141 |
| - ){6} # |
142 |
| - (?: # Either |
143 |
| - [0-9a-f]{0,4} # Another group |
144 |
| - (?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard |
145 |
| - [0-9a-f]{0,4} # Last group |
146 |
| - (?: (?<=::) # Colon iff preceeded by exacly one colon |
147 |
| - | (?<!:) # |
148 |
| - | (?<=:) (?<!::) : # |
149 |
| - ) # OR |
150 |
| - | # A v4 address with NO leading zeros |
151 |
| - (?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d) |
152 |
| - (?: \. |
153 |
| - (?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d) |
154 |
| - ){3} |
155 |
| - ) |
156 |
| - \s* # Trailing whitespace |
157 |
| - $ |
158 |
| -""", re.VERBOSE | re.IGNORECASE | re.DOTALL) |
159 |
| - |
160 | 132 |
|
161 | 133 | def valid_ipv6(address):
|
162 |
| - """Validates IPv6 addresses. """ |
163 |
| - return IPV6_PATTERN.match(address) is not None |
| 134 | + """Validate IPv6 addresses.""" |
| 135 | + is_enclosed_in_brackets = address.startswith("[") and address.endswith("]") |
| 136 | + address_raw = address[1:-1] if is_enclosed_in_brackets else address |
| 137 | + try: |
| 138 | + IPv6Address(address_raw) |
| 139 | + except AddressValueError: |
| 140 | + return False |
| 141 | + return True |
164 | 142 |
|
165 | 143 |
|
166 | 144 | def valid_boolean(val):
|
|
0 commit comments