Added anonymous TLS (SSL) support
This commit is contained in:
parent
e3569a49af
commit
fd69b85755
2
pom.xml
2
pom.xml
|
|
@ -34,6 +34,8 @@
|
||||||
<version>2.3.2</version>
|
<version>2.3.2</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<showDeprecation>true</showDeprecation>
|
<showDeprecation>true</showDeprecation>
|
||||||
|
<source>1.5</source>
|
||||||
|
<target>1.5</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ package examples;
|
||||||
public class Config {
|
public class Config {
|
||||||
|
|
||||||
|
|
||||||
public static final String HOST = "10.0.0.3";
|
public static final String HOST = "10.0.1.3";
|
||||||
public static final String USERNAME = "admin";
|
public static final String USERNAME = "admin";
|
||||||
public static final String PASSWORD = "";
|
public static final String PASSWORD = "";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,26 @@ import me.legrange.mikrotik.impl.ApiConnectionImpl;
|
||||||
*/
|
*/
|
||||||
public abstract class ApiConnection {
|
public abstract class ApiConnection {
|
||||||
|
|
||||||
/** default TCP port used by Mikrotik API */
|
/**
|
||||||
public static final int DEFAULT_PORT = 8728;
|
* Create a new API connection to the give device on the supplied port, using anonymous TLS for encryption.
|
||||||
|
* @param host The host to which to connect.
|
||||||
|
* @param port The TCP port to use.
|
||||||
|
* @return The ApiConnection
|
||||||
|
*/
|
||||||
|
public static ApiConnection connectTLS(String host, int port) throws MikrotikApiException {
|
||||||
|
return ApiConnectionImpl.connect(host, port, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new API connection to the give device on the default API port, using anonymous TLS for encryption.
|
||||||
|
* @param host The host to which to connect.
|
||||||
|
* @return The ApiConnection
|
||||||
|
*/
|
||||||
|
public static ApiConnection connectTLS(String host) throws MikrotikApiException {
|
||||||
|
return ApiConnectionImpl.connect(host, DEFAULT_TLS_PORT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new API connection to the give device on the supplied port
|
* Create a new API connection to the give device on the supplied port
|
||||||
|
|
@ -22,11 +40,11 @@ public abstract class ApiConnection {
|
||||||
* @return The ApiConnection
|
* @return The ApiConnection
|
||||||
*/
|
*/
|
||||||
public static ApiConnection connect(String host, int port) throws MikrotikApiException {
|
public static ApiConnection connect(String host, int port) throws MikrotikApiException {
|
||||||
return ApiConnectionImpl.connect(host, port);
|
return ApiConnectionImpl.connect(host, port, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new API connection to the give device on the default API port..
|
* Create a new API connection to the give device on the default API port.
|
||||||
* @param host The host to which to connect.
|
* @param host The host to which to connect.
|
||||||
* @return The ApiConnection
|
* @return The ApiConnection
|
||||||
*/
|
*/
|
||||||
|
|
@ -72,4 +90,9 @@ public abstract class ApiConnection {
|
||||||
/** cancel a command */
|
/** cancel a command */
|
||||||
public abstract void cancel(String tag) throws MikrotikApiException;
|
public abstract void cancel(String tag) throws MikrotikApiException;
|
||||||
|
|
||||||
|
/** default TCP port used by Mikrotik API */
|
||||||
|
private static final int DEFAULT_PORT = 8728;
|
||||||
|
/** default TCP TLS port used by Mikrotik API */
|
||||||
|
private static final int DEFAULT_TLS_PORT = 8729;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -8,16 +8,21 @@ import java.io.UnsupportedEncodingException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.Security;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Mikrotik API connection implementation. This is the class used to connect to a remote
|
* The Mikrotik API connection implementation. This is the class used to connect
|
||||||
* Mikrotik and send commands to it.
|
* to a remote Mikrotik and send commands to it.
|
||||||
*
|
*
|
||||||
* @author GideonLeGrange
|
* @author GideonLeGrange
|
||||||
*/
|
*/
|
||||||
|
|
@ -25,13 +30,14 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new API connection to the give device on the supplied port
|
* Create a new API connection to the give device on the supplied port
|
||||||
|
*
|
||||||
* @param host The host to which to connect.
|
* @param host The host to which to connect.
|
||||||
* @param port The TCP port to use.
|
* @param port The TCP port to use.
|
||||||
* @return The ApiConnection
|
* @return The ApiConnection
|
||||||
*/
|
*/
|
||||||
public static ApiConnection connect(String host, int port) throws ApiConnectionException {
|
public static ApiConnection connect(String host, int port, boolean secure) throws ApiConnectionException {
|
||||||
ApiConnectionImpl con = new ApiConnectionImpl();
|
ApiConnectionImpl con = new ApiConnectionImpl();
|
||||||
con.open(host, port);
|
con.open(host, port, secure);
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +81,9 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
execute("/login name=" + username + " response=00" + chal);
|
execute("/login name=" + username + " response=00" + chal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** execute a command and return a list of results.
|
/**
|
||||||
|
* execute a command and return a list of results.
|
||||||
|
*
|
||||||
* @param cmd Command to execute
|
* @param cmd Command to execute
|
||||||
* @return The list of results
|
* @return The list of results
|
||||||
*/
|
*/
|
||||||
|
|
@ -83,7 +91,8 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
return execute(Parser.parse(cmd));
|
return execute(Parser.parse(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** execute a command and attach a result listener to receive it's results.
|
/**
|
||||||
|
* execute a command and attach a result listener to receive it's results.
|
||||||
*
|
*
|
||||||
* @param cmd Command to execute
|
* @param cmd Command to execute
|
||||||
* @param lis ResultListener that will receive the results
|
* @param lis ResultListener that will receive the results
|
||||||
|
|
@ -94,9 +103,11 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
return execute(Parser.parse(cmd), lis);
|
return execute(Parser.parse(cmd), lis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** cancel a command */
|
/**
|
||||||
|
* cancel a command
|
||||||
|
*/
|
||||||
public void cancel(String tag) throws MikrotikApiException {
|
public void cancel(String tag) throws MikrotikApiException {
|
||||||
execute(String.format("/cancel tag=%s", tag)) ;
|
execute(String.format("/cancel tag=%s", tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Map<String, String>> execute(Command cmd) throws MikrotikApiException {
|
private List<Map<String, String>> execute(Command cmd) throws MikrotikApiException {
|
||||||
|
|
@ -105,7 +116,6 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
return l.getResults();
|
return l.getResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String execute(Command cmd, ResultListener lis) throws MikrotikApiException {
|
private String execute(Command cmd, ResultListener lis) throws MikrotikApiException {
|
||||||
String tag = nextTag();
|
String tag = nextTag();
|
||||||
cmd.setTag(tag);
|
cmd.setTag(tag);
|
||||||
|
|
@ -124,13 +134,24 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the API. Connects to the Mikrotik
|
* Start the API. Connects to the Mikrotik without using encryption
|
||||||
*/
|
*/
|
||||||
private void open(String host, int port) throws ApiConnectionException {
|
private void open(String host, int port) throws ApiConnectionException {
|
||||||
|
open(host, port, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the API. Connects to the Mikrotik
|
||||||
|
*/
|
||||||
|
private void open(String host, int port, boolean secure) throws ApiConnectionException {
|
||||||
try {
|
try {
|
||||||
InetAddress ia = InetAddress.getByName(host);
|
InetAddress ia = InetAddress.getByName(host);
|
||||||
if (ia.isReachable(1000)) {
|
if (ia.isReachable(1000)) {
|
||||||
|
if (secure) {
|
||||||
|
sock = openSSLSocket(ia, port);
|
||||||
|
} else {
|
||||||
sock = new Socket(ia, port);
|
sock = new Socket(ia, port);
|
||||||
|
}
|
||||||
in = new DataInputStream(sock.getInputStream());
|
in = new DataInputStream(sock.getInputStream());
|
||||||
out = new DataOutputStream(sock.getOutputStream());
|
out = new DataOutputStream(sock.getOutputStream());
|
||||||
connected = true;
|
connected = true;
|
||||||
|
|
@ -152,6 +173,21 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* open and configure a SSL socket.
|
||||||
|
*/
|
||||||
|
private Socket openSSLSocket(InetAddress ia, int port) throws IOException {
|
||||||
|
SSLSocket ssl = (SSLSocket) SSLSocketFactory.getDefault().createSocket(ia, port);
|
||||||
|
List<String> cs = new LinkedList<String>();
|
||||||
|
// not happy with this code. Without it, SSL throws a "Remote host closed connection during handshake" error
|
||||||
|
// caused by a "SSL peer shut down incorrectly" error
|
||||||
|
for (String s : ssl.getSupportedCipherSuites()) {
|
||||||
|
if (s.startsWith("TLS_DH_anon")) cs.add(s);
|
||||||
|
}
|
||||||
|
ssl.setEnabledCipherSuites(cs.toArray(new String[]{}));
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
private char[] makePass(String pass) {
|
private char[] makePass(String pass) {
|
||||||
if (true) {
|
if (true) {
|
||||||
return pass.toCharArray();
|
return pass.toCharArray();
|
||||||
|
|
@ -166,7 +202,6 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
_tag++;
|
_tag++;
|
||||||
return Integer.toHexString(_tag);
|
return Integer.toHexString(_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int DEFAULT_PORT = 8728;
|
private static final int DEFAULT_PORT = 8728;
|
||||||
private Socket sock = null;
|
private Socket sock = null;
|
||||||
private DataOutputStream out = null;
|
private DataOutputStream out = null;
|
||||||
|
|
@ -256,9 +291,8 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
ResponseListener rl = (ResponseListener) l;
|
ResponseListener rl = (ResponseListener) l;
|
||||||
if (res instanceof Done) {
|
if (res instanceof Done) {
|
||||||
if (rl instanceof SyncListener) {
|
if (rl instanceof SyncListener) {
|
||||||
((SyncListener)rl).completed((Done)res);
|
((SyncListener) rl).completed((Done) res);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
rl.completed();
|
rl.completed();
|
||||||
}
|
}
|
||||||
} else if (res instanceof Error) {
|
} else if (res instanceof Error) {
|
||||||
|
|
@ -441,7 +475,6 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Map<String, String>> results = new LinkedList<Map<String, String>>();
|
private List<Map<String, String>> results = new LinkedList<Map<String, String>>();
|
||||||
private MikrotikApiException err;
|
private MikrotikApiException err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue