This commit is contained in:
laoyuyu
2018-11-08 19:50:16 +08:00
parent 66b36b355a
commit e22e2dc840
83 changed files with 248 additions and 241 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.util;
import java.nio.charset.Charset;
/**
* Helps dealing with Charsets.
*
* @since 3.3
*/
public class Charsets {
/**
* Returns a charset object for the given charset name.
*
* @param charsetName The name of the requested charset; may be a canonical name, an alias, or
* null. If null, return the
* default charset.
* @return A charset object for the named charset
*/
public static Charset toCharset(String charsetName) {
return charsetName == null ? Charset.defaultCharset() : Charset.forName(charsetName);
}
/**
* Returns a charset object for the given charset name.
*
* @param charsetName The name of the requested charset; may be a canonical name, an alias, or
* null.
* If null, return the default charset.
* @param defaultCharsetName the charset name to use if the requested charset is null
* @return A charset object for the named charset
*/
public static Charset toCharset(String charsetName, String defaultCharsetName) {
return charsetName == null ? Charset.forName(defaultCharsetName) : Charset.forName(charsetName);
}
}

View File

@@ -0,0 +1,236 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package aria.apache.commons.net.util;
import aria.apache.commons.net.io.Util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import javax.net.ssl.KeyManager;
import javax.net.ssl.X509ExtendedKeyManager;
/**
* General KeyManager utilities
* <p>
* How to use with a client certificate:
* <pre>
* KeyManager km = KeyManagerUtils.createClientKeyManager("JKS",
* "/path/to/privatekeystore.jks","storepassword",
* "privatekeyalias", "keypassword");
* FTPSClient cl = new FTPSClient();
* cl.setKeyManager(km);
* cl.connect(...);
* </pre>
* If using the default store type and the key password is the same as the
* store password, these parameters can be omitted. <br>
* If the desired key is the first or only key in the keystore, the keyAlias parameter
* can be omitted, in which case the code becomes:
* <pre>
* KeyManager km = KeyManagerUtils.createClientKeyManager(
* "/path/to/privatekeystore.jks","storepassword");
* FTPSClient cl = new FTPSClient();
* cl.setKeyManager(km);
* cl.connect(...);
* </pre>
*
* @since 3.0
*/
public final class KeyManagerUtils {
private static final String DEFAULT_STORE_TYPE = KeyStore.getDefaultType();
private KeyManagerUtils() {
// Not instantiable
}
/**
* Create a client key manager which returns a particular key.
* Does not handle server keys.
*
* @param ks the keystore to use
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key
* entry alias is used
* @param keyPass the password of the key to use
* @return the customised KeyManager
* @throws GeneralSecurityException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(KeyStore ks, String keyAlias, String keyPass)
throws GeneralSecurityException {
ClientKeyStore cks =
new ClientKeyStore(ks, keyAlias != null ? keyAlias : findAlias(ks), keyPass);
return new X509KeyManager(cks);
}
/**
* Create a client key manager which returns a particular key.
* Does not handle server keys.
*
* @param storeType the type of the keyStore, e.g. "JKS"
* @param storePath the path to the keyStore
* @param storePass the keyStore password
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key
* entry alias is used
* @param keyPass the password of the key to use
* @return the customised KeyManager
* @throws GeneralSecurityException if there is a problem creating the keystore
* @throws IOException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(String storeType, File storePath,
String storePass, String keyAlias, String keyPass)
throws IOException, GeneralSecurityException {
KeyStore ks = loadStore(storeType, storePath, storePass);
return createClientKeyManager(ks, keyAlias, keyPass);
}
/**
* Create a client key manager which returns a particular key.
* Does not handle server keys.
* Uses the default store type and assumes the key password is the same as the store password
*
* @param storePath the path to the keyStore
* @param storePass the keyStore password
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key
* entry alias is used
* @return the customised KeyManager
* @throws IOException if there is a problem creating the keystore
* @throws GeneralSecurityException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(File storePath, String storePass, String keyAlias)
throws IOException, GeneralSecurityException {
return createClientKeyManager(DEFAULT_STORE_TYPE, storePath, storePass, keyAlias, storePass);
}
/**
* Create a client key manager which returns a particular key.
* Does not handle server keys.
* Uses the default store type and assumes the key password is the same as the store password.
* The key alias is found by searching the keystore for the first private key entry
*
* @param storePath the path to the keyStore
* @param storePass the keyStore password
* @return the customised KeyManager
* @throws IOException if there is a problem creating the keystore
* @throws GeneralSecurityException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(File storePath, String storePass)
throws IOException, GeneralSecurityException {
return createClientKeyManager(DEFAULT_STORE_TYPE, storePath, storePass, null, storePass);
}
private static KeyStore loadStore(String storeType, File storePath, String storePass)
throws KeyStoreException, IOException, GeneralSecurityException {
KeyStore ks = KeyStore.getInstance(storeType);
FileInputStream stream = null;
try {
stream = new FileInputStream(storePath);
ks.load(stream, storePass.toCharArray());
} finally {
Util.closeQuietly(stream);
}
return ks;
}
private static String findAlias(KeyStore ks) throws KeyStoreException {
Enumeration<String> e = ks.aliases();
while (e.hasMoreElements()) {
String entry = e.nextElement();
if (ks.isKeyEntry(entry)) {
return entry;
}
}
throw new KeyStoreException("Cannot find a private key entry");
}
private static class ClientKeyStore {
private final X509Certificate[] certChain;
private final PrivateKey key;
private final String keyAlias;
ClientKeyStore(KeyStore ks, String keyAlias, String keyPass) throws GeneralSecurityException {
this.keyAlias = keyAlias;
this.key = (PrivateKey) ks.getKey(this.keyAlias, keyPass.toCharArray());
Certificate[] certs = ks.getCertificateChain(this.keyAlias);
X509Certificate[] X509certs = new X509Certificate[certs.length];
for (int i = 0; i < certs.length; i++) {
X509certs[i] = (X509Certificate) certs[i];
}
this.certChain = X509certs;
}
final X509Certificate[] getCertificateChain() {
return this.certChain;
}
final PrivateKey getPrivateKey() {
return this.key;
}
final String getAlias() {
return this.keyAlias;
}
}
private static class X509KeyManager extends X509ExtendedKeyManager {
private final ClientKeyStore keyStore;
X509KeyManager(final ClientKeyStore keyStore) {
this.keyStore = keyStore;
}
// Call sequence: 1
@Override public String chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket) {
return keyStore.getAlias();
}
// Call sequence: 2
@Override public X509Certificate[] getCertificateChain(String alias) {
return keyStore.getCertificateChain();
}
@Override public String[] getClientAliases(String keyType, Principal[] issuers) {
return new String[] { keyStore.getAlias() };
}
// Call sequence: 3
@Override public PrivateKey getPrivateKey(String alias) {
return keyStore.getPrivateKey();
}
@Override public String[] getServerAliases(String keyType, Principal[] issuers) {
return null;
}
@Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
return null;
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.util;
import java.io.Serializable;
import java.util.EventListener;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
/**
*/
public class ListenerList implements Serializable, Iterable<EventListener> {
private static final long serialVersionUID = -1934227607974228213L;
private final CopyOnWriteArrayList<EventListener> __listeners;
public ListenerList() {
__listeners = new CopyOnWriteArrayList<EventListener>();
}
public void addListener(EventListener listener) {
__listeners.add(listener);
}
public void removeListener(EventListener listener) {
__listeners.remove(listener);
}
public int getListenerCount() {
return __listeners.size();
}
/**
* Return an {@link Iterator} for the {@link EventListener} instances.
*
* @return an {@link Iterator} for the {@link EventListener} instances
* @since 2.0
* TODO Check that this is a good defensive strategy
*/
@Override public Iterator<EventListener> iterator() {
return __listeners.iterator();
}
}

View File

@@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package aria.apache.commons.net.util;
import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
/**
* General utilities for SSLContext.
*
* @since 3.0
*/
public class SSLContextUtils {
private SSLContextUtils() {
// Not instantiable
}
/**
* Create and initialise an SSLContext.
*
* @param protocol the protocol used to instatiate the context
* @param keyManager the key manager, may be {@code null}
* @param trustManager the trust manager, may be {@code null}
* @return the initialised context.
* @throws IOException this is used to wrap any {@link GeneralSecurityException} that occurs
*/
public static SSLContext createSSLContext(String protocol, KeyManager keyManager,
TrustManager trustManager) throws IOException {
return createSSLContext(protocol, keyManager == null ? null : new KeyManager[] { keyManager },
trustManager == null ? null : new TrustManager[] { trustManager });
}
/**
* Create and initialise an SSLContext.
*
* @param protocol the protocol used to instatiate the context
* @param keyManagers the array of key managers, may be {@code null} but array entries must not be
* {@code null}
* @param trustManagers the array of trust managers, may be {@code null} but array entries must
* not be {@code null}
* @return the initialised context.
* @throws IOException this is used to wrap any {@link GeneralSecurityException} that occurs
*/
public static SSLContext createSSLContext(String protocol, KeyManager[] keyManagers,
TrustManager[] trustManagers) throws IOException {
SSLContext ctx;
try {
ctx = SSLContext.getInstance(protocol);
ctx.init(keyManagers, trustManagers, /*SecureRandom*/ null);
} catch (GeneralSecurityException e) {
IOException ioe = new IOException("Could not initialize SSL context");
ioe.initCause(e);
throw ioe;
}
return ctx;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package aria.apache.commons.net.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.net.ssl.SSLSocket;
/**
* General utilities for SSLSocket.
*
* @since 3.4
*/
public class SSLSocketUtils {
private SSLSocketUtils() {
// Not instantiable
}
/**
* Enable the HTTPS endpoint identification algorithm on an SSLSocket.
*
* @param socket the SSL socket
* @return {@code true} on success (this is only supported on Java 1.7+)
*/
public static boolean enableEndpointNameVerification(SSLSocket socket) {
try {
Class<?> cls = Class.forName("javax.net.ssl.SSLParameters");
Method setEndpointIdentificationAlgorithm =
cls.getDeclaredMethod("setEndpointIdentificationAlgorithm", String.class);
Method getSSLParameters = SSLSocket.class.getDeclaredMethod("getSSLParameters");
Method setSSLParameters = SSLSocket.class.getDeclaredMethod("setSSLParameters", cls);
if (setEndpointIdentificationAlgorithm != null
&& getSSLParameters != null
&& setSSLParameters != null) {
Object sslParams = getSSLParameters.invoke(socket);
if (sslParams != null) {
setEndpointIdentificationAlgorithm.invoke(sslParams, "HTTPS");
setSSLParameters.invoke(socket, sslParams);
return true;
}
}
} catch (SecurityException e) { // Ignored
} catch (ClassNotFoundException e) { // Ignored
} catch (NoSuchMethodException e) { // Ignored
} catch (IllegalArgumentException e) { // Ignored
} catch (IllegalAccessException e) { // Ignored
} catch (InvocationTargetException e) { // Ignored
}
return false;
}
}

View File

@@ -0,0 +1,395 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A class that performs some subnet calculations given a network address and a subnet mask.
*
* @see "http://www.faqs.org/rfcs/rfc1519.html"
* @since 2.0
*/
public class SubnetUtils {
private static final String IP_ADDRESS = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})";
private static final String SLASH_FORMAT = IP_ADDRESS + "/(\\d{1,3})";
private static final Pattern addressPattern = Pattern.compile(IP_ADDRESS);
private static final Pattern cidrPattern = Pattern.compile(SLASH_FORMAT);
private static final int NBITS = 32;
private int netmask = 0;
private int address = 0;
private int network = 0;
private int broadcast = 0;
/** Whether the broadcast/network address are included in host count */
private boolean inclusiveHostCount = false;
/**
* Constructor that takes a CIDR-notation string, e.g. "192.168.0.1/16"
*
* @param cidrNotation A CIDR-notation string, e.g. "192.168.0.1/16"
* @throws IllegalArgumentException if the parameter is invalid,
* i.e. does not match n.n.n.n/m where n=1-3 decimal digits, m = 1-3 decimal digits in range 1-32
*/
public SubnetUtils(String cidrNotation) {
calculate(cidrNotation);
}
/**
* Constructor that takes a dotted decimal address and a dotted decimal mask.
*
* @param address An IP address, e.g. "192.168.0.1"
* @param mask A dotted decimal netmask e.g. "255.255.0.0"
* @throws IllegalArgumentException if the address or mask is invalid,
* i.e. does not match n.n.n.n where n=1-3 decimal digits and the mask is not all zeros
*/
public SubnetUtils(String address, String mask) {
calculate(toCidrNotation(address, mask));
}
/**
* Returns <code>true</code> if the return value of {@link SubnetInfo#getAddressCount()}
* includes the network and broadcast addresses.
*
* @return true if the hostcount includes the network and broadcast addresses
* @since 2.2
*/
public boolean isInclusiveHostCount() {
return inclusiveHostCount;
}
/**
* Set to <code>true</code> if you want the return value of {@link SubnetInfo#getAddressCount()}
* to include the network and broadcast addresses.
*
* @param inclusiveHostCount true if network and broadcast addresses are to be included
* @since 2.2
*/
public void setInclusiveHostCount(boolean inclusiveHostCount) {
this.inclusiveHostCount = inclusiveHostCount;
}
/**
* Convenience container for subnet summary information.
*/
public final class SubnetInfo {
/* Mask to convert unsigned int to a long (i.e. keep 32 bits) */
private static final long UNSIGNED_INT_MASK = 0x0FFFFFFFFL;
private SubnetInfo() {
}
private int netmask() {
return netmask;
}
private int network() {
return network;
}
private int address() {
return address;
}
private int broadcast() {
return broadcast;
}
// long versions of the values (as unsigned int) which are more suitable for range checking
private long networkLong() {
return network & UNSIGNED_INT_MASK;
}
private long broadcastLong() {
return broadcast & UNSIGNED_INT_MASK;
}
private int low() {
return (isInclusiveHostCount() ? network()
: broadcastLong() - networkLong() > 1 ? network() + 1 : 0);
}
private int high() {
return (isInclusiveHostCount() ? broadcast()
: broadcastLong() - networkLong() > 1 ? broadcast() - 1 : 0);
}
/**
* Returns true if the parameter <code>address</code> is in the
* range of usable endpoint addresses for this subnet. This excludes the
* network and broadcast adresses.
*
* @param address A dot-delimited IPv4 address, e.g. "192.168.0.1"
* @return True if in range, false otherwise
*/
public boolean isInRange(String address) {
return isInRange(toInteger(address));
}
/**
* @param address the address to check
* @return true if it is in range
* @since 3.4 (made public)
*/
public boolean isInRange(int address) {
long addLong = address & UNSIGNED_INT_MASK;
long lowLong = low() & UNSIGNED_INT_MASK;
long highLong = high() & UNSIGNED_INT_MASK;
return addLong >= lowLong && addLong <= highLong;
}
public String getBroadcastAddress() {
return format(toArray(broadcast()));
}
public String getNetworkAddress() {
return format(toArray(network()));
}
public String getNetmask() {
return format(toArray(netmask()));
}
public String getAddress() {
return format(toArray(address()));
}
/**
* Return the low address as a dotted IP address.
* Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
*
* @return the IP address in dotted format, may be "0.0.0.0" if there is no valid address
*/
public String getLowAddress() {
return format(toArray(low()));
}
/**
* Return the high address as a dotted IP address.
* Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
*
* @return the IP address in dotted format, may be "0.0.0.0" if there is no valid address
*/
public String getHighAddress() {
return format(toArray(high()));
}
/**
* Get the count of available addresses.
* Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
*
* @return the count of addresses, may be zero.
* @throws RuntimeException if the correct count is greater than {@code Integer.MAX_VALUE}
* @deprecated (3.4) use {@link #getAddressCountLong()} instead
*/
@Deprecated public int getAddressCount() {
long countLong = getAddressCountLong();
if (countLong > Integer.MAX_VALUE) {
throw new RuntimeException("Count is larger than an integer: " + countLong);
}
// N.B. cannot be negative
return (int) countLong;
}
/**
* Get the count of available addresses.
* Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
*
* @return the count of addresses, may be zero.
* @since 3.4
*/
public long getAddressCountLong() {
long b = broadcastLong();
long n = networkLong();
long count = b - n + (isInclusiveHostCount() ? 1 : -1);
return count < 0 ? 0 : count;
}
public int asInteger(String address) {
return toInteger(address);
}
public String getCidrSignature() {
return toCidrNotation(format(toArray(address())), format(toArray(netmask())));
}
public String[] getAllAddresses() {
int ct = getAddressCount();
String[] addresses = new String[ct];
if (ct == 0) {
return addresses;
}
for (int add = low(), j = 0; add <= high(); ++add, ++j) {
addresses[j] = format(toArray(add));
}
return addresses;
}
/**
* {@inheritDoc}
*
* @since 2.2
*/
@Override public String toString() {
final StringBuilder buf = new StringBuilder();
buf.append("CIDR Signature:\t[")
.append(getCidrSignature())
.append("]")
.append(" Netmask: [")
.append(getNetmask())
.append("]\n")
.append("Network:\t[")
.append(getNetworkAddress())
.append("]\n")
.append("Broadcast:\t[")
.append(getBroadcastAddress())
.append("]\n")
.append("First Address:\t[")
.append(getLowAddress())
.append("]\n")
.append("Last Address:\t[")
.append(getHighAddress())
.append("]\n")
.append("# Addresses:\t[")
.append(getAddressCount())
.append("]\n");
return buf.toString();
}
}
/**
* Return a {@link SubnetInfo} instance that contains subnet-specific statistics
*
* @return new instance
*/
public final SubnetInfo getInfo() {
return new SubnetInfo();
}
/*
* Initialize the internal fields from the supplied CIDR mask
*/
private void calculate(String mask) {
Matcher matcher = cidrPattern.matcher(mask);
if (matcher.matches()) {
address = matchAddress(matcher);
/* Create a binary netmask from the number of bits specification /x */
int cidrPart = rangeCheck(Integer.parseInt(matcher.group(5)), 0, NBITS);
for (int j = 0; j < cidrPart; ++j) {
netmask |= (1 << 31 - j);
}
/* Calculate base network address */
network = (address & netmask);
/* Calculate broadcast address */
broadcast = network | ~(netmask);
} else {
throw new IllegalArgumentException("Could not parse [" + mask + "]");
}
}
/*
* Convert a dotted decimal format address to a packed integer format
*/
private int toInteger(String address) {
Matcher matcher = addressPattern.matcher(address);
if (matcher.matches()) {
return matchAddress(matcher);
} else {
throw new IllegalArgumentException("Could not parse [" + address + "]");
}
}
/*
* Convenience method to extract the components of a dotted decimal address and
* pack into an integer using a regex match
*/
private int matchAddress(Matcher matcher) {
int addr = 0;
for (int i = 1; i <= 4; ++i) {
int n = (rangeCheck(Integer.parseInt(matcher.group(i)), 0, 255));
addr |= ((n & 0xff) << 8 * (4 - i));
}
return addr;
}
/*
* Convert a packed integer address into a 4-element array
*/
private int[] toArray(int val) {
int ret[] = new int[4];
for (int j = 3; j >= 0; --j) {
ret[j] |= ((val >>> 8 * (3 - j)) & (0xff));
}
return ret;
}
/*
* Convert a 4-element array into dotted decimal format
*/
private String format(int[] octets) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < octets.length; ++i) {
str.append(octets[i]);
if (i != octets.length - 1) {
str.append(".");
}
}
return str.toString();
}
/*
* Convenience function to check integer boundaries.
* Checks if a value x is in the range [begin,end].
* Returns x if it is in range, throws an exception otherwise.
*/
private int rangeCheck(int value, int begin, int end) {
if (value >= begin && value <= end) { // (begin,end]
return value;
}
throw new IllegalArgumentException(
"Value [" + value + "] not in range [" + begin + "," + end + "]");
}
/*
* Count the number of 1-bits in a 32-bit integer using a divide-and-conquer strategy
* see Hacker's Delight section 5.1
*/
int pop(int x) {
x = x - ((x >>> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
x = (x + (x >>> 4)) & 0x0F0F0F0F;
x = x + (x >>> 8);
x = x + (x >>> 16);
return x & 0x0000003F;
}
/* Convert two dotted decimal addresses to a single xxx.xxx.xxx.xxx/yy format
* by counting the 1-bit population in the mask address. (It may be better to count
* NBITS-#trailing zeroes for this case)
*/
private String toCidrNotation(String addr, String mask) {
return addr + "/" + pop(toInteger(mask));
}
}

View File

@@ -0,0 +1,110 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.util;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
/**
* TrustManager utilities for generating TrustManagers.
*
* @since 3.0
*/
public final class TrustManagerUtils {
private static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[] {};
private static class TrustManager implements X509TrustManager {
private final boolean checkServerValidity;
TrustManager(boolean checkServerValidity) {
this.checkServerValidity = checkServerValidity;
}
/**
* Never generates a CertificateException.
*/
@Override public void checkClientTrusted(X509Certificate[] certificates, String authType) {
return;
}
@Override public void checkServerTrusted(X509Certificate[] certificates, String authType)
throws CertificateException {
if (checkServerValidity) {
for (X509Certificate certificate : certificates) {
certificate.checkValidity();
}
}
}
/**
* @return an empty array of certificates
*/
@Override public X509Certificate[] getAcceptedIssuers() {
return EMPTY_X509CERTIFICATE_ARRAY;
}
}
private static final X509TrustManager ACCEPT_ALL = new TrustManager(false);
private static final X509TrustManager CHECK_SERVER_VALIDITY = new TrustManager(true);
/**
* Generate a TrustManager that performs no checks.
*
* @return the TrustManager
*/
public static X509TrustManager getAcceptAllTrustManager() {
return ACCEPT_ALL;
}
/**
* Generate a TrustManager that checks server certificates for validity,
* but otherwise performs no checks.
*
* @return the validating TrustManager
*/
public static X509TrustManager getValidateServerCertificateTrustManager() {
return CHECK_SERVER_VALIDITY;
}
/**
* Return the default TrustManager provided by the JVM.
* <p>
* This should be the same as the default used by
* {@link javax.net.ssl.SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], * java.security.SecureRandom)
* SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}
* when the TrustManager parameter is set to {@code null}
*
* @param keyStore the KeyStore to use, may be {@code null}
* @return the default TrustManager
* @throws GeneralSecurityException if an error occurs
*/
public static X509TrustManager getDefaultTrustManager(KeyStore keyStore)
throws GeneralSecurityException {
String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory instance = TrustManagerFactory.getInstance(defaultAlgorithm);
instance.init(keyStore);
return (X509TrustManager) instance.getTrustManagers()[0];
}
}

View File

@@ -0,0 +1,21 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Utility classes
*/
package aria.apache.commons.net.util;