Add IPv6 support for isLocal checks (#1592)
* Add IPv6 support for isLocal checks
* Replace magic values like 127.0.0.1 and use our utility
* Support for IPv6 local adresses in IPv6 only or dual stack environments
* Loopback [::1]
* Site-Local fc00::/7
* Link-local fe80::/10
* Introduce extra method for loopback addresses
* Use public IP for passMaxLogin check
* Use non-local IP addresses in test after change in verification
This commit is contained in:
@@ -1,16 +1,13 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* Utility class about the InternetProtocol
|
||||
*/
|
||||
public final class InternetProtocolUtils {
|
||||
|
||||
private static final Pattern LOCAL_ADDRESS_PATTERN =
|
||||
Pattern.compile("(^127\\.)|(^(0)?10\\.)|(^172\\.(0)?1[6-9]\\.)|(^172\\.(0)?2[0-9]\\.)"
|
||||
+ "|(^172\\.(0)?3[0-1]\\.)|(^169\\.254\\.)|(^192\\.168\\.)");
|
||||
|
||||
// Utility class
|
||||
private InternetProtocolUtils() {
|
||||
}
|
||||
@@ -19,10 +16,57 @@ public final class InternetProtocolUtils {
|
||||
* Checks if the specified address is a private or loopback address
|
||||
*
|
||||
* @param address address to check
|
||||
*
|
||||
* @return true if the address is a local or loopback address, false otherwise
|
||||
* @return true if the address is a local (site and link) or loopback address, false otherwise
|
||||
*/
|
||||
public static boolean isLocalAddress(String address) {
|
||||
return LOCAL_ADDRESS_PATTERN.matcher(address).find();
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getByName(address);
|
||||
|
||||
// Examples: 127.0.0.1, localhost or [::1]
|
||||
return isLoopbackAddress(address)
|
||||
// Example: 10.0.0.0, 172.16.0.0, 192.168.0.0, fec0::/10 (deprecated)
|
||||
// Ref: https://en.wikipedia.org/wiki/IP_address#Private_addresses
|
||||
|| inetAddress.isSiteLocalAddress()
|
||||
// Example: 169.254.0.0/16, fe80::/10
|
||||
// Ref: https://en.wikipedia.org/wiki/IP_address#Address_autoconfiguration
|
||||
|| inetAddress.isLinkLocalAddress()
|
||||
// non deprecated unique site-local that java doesn't check yet -> fc00::/7
|
||||
|| isIPv6UniqueSiteLocal(inetAddress);
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified address is a loopback address. This can be one of the following:
|
||||
* <ul>
|
||||
* <li>127.0.0.1</li>
|
||||
* <li>localhost</li>
|
||||
* <li>[::1]</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param address address to check
|
||||
* @return true if the address is a loopback one
|
||||
*/
|
||||
public static boolean isLoopbackAddress(String address) {
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getByName(address);
|
||||
return inetAddress.isLoopbackAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLoopbackAddress(InetAddress address) {
|
||||
return address.isLoopbackAddress();
|
||||
}
|
||||
|
||||
private static boolean isIPv6UniqueSiteLocal(InetAddress address) {
|
||||
// ref: https://en.wikipedia.org/wiki/Unique_local_address
|
||||
|
||||
// currently undefined but could be used in the near future fc00::/8
|
||||
return (address.getAddress()[0] & 0xFF) == 0xFC
|
||||
// in use for unique site-local fd00::/8
|
||||
|| (address.getAddress()[0] & 0xFF) == 0xFD;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user