This commit is contained in:
1056
AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Base64.java
Normal file
1056
AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Base64.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user