mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 09:58:08 +00:00
Remove compat with protocol 6 with RSA encryption
Since we already removed compat with protocol 7 ^.^u
This commit is contained in:
parent
9a8ae36ef6
commit
168b16527c
@ -26,7 +26,6 @@ import org.kde.kdeconnect.Device;
|
|||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
@ -90,6 +89,4 @@ public abstract class BaseLink {
|
|||||||
|
|
||||||
//TO OVERRIDE, should be sync
|
//TO OVERRIDE, should be sync
|
||||||
public abstract boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback);
|
public abstract boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback);
|
||||||
@Deprecated
|
|
||||||
public abstract boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key);
|
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ import org.json.JSONObject;
|
|||||||
import org.kde.kdeconnect.Backends.BaseLink;
|
import org.kde.kdeconnect.Backends.BaseLink;
|
||||||
import org.kde.kdeconnect.Backends.BasePairingHandler;
|
import org.kde.kdeconnect.Backends.BasePairingHandler;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -41,7 +40,6 @@ import java.io.InputStreamReader;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BluetoothLink extends BaseLink {
|
public class BluetoothLink extends BaseLink {
|
||||||
@ -87,14 +85,6 @@ public class BluetoothLink extends BaseLink {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (np.getType().equals(NetworkPacket.PACKET_TYPE_ENCRYPTED)) {
|
|
||||||
try {
|
|
||||||
np = RsaHelper.decrypt(np, privateKey);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("BluetoothLink/receiving", "Exception decrypting the package", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (np.hasPayloadTransferInfo()) {
|
if (np.hasPayloadTransferInfo()) {
|
||||||
BluetoothSocket transferSocket = null;
|
BluetoothSocket transferSocket = null;
|
||||||
try {
|
try {
|
||||||
@ -158,16 +148,7 @@ public class BluetoothLink extends BaseLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback) {
|
public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) {
|
||||||
return sendPacketInternal(np, callback, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) {
|
|
||||||
return sendPacketInternal(np, callback, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean sendPacketInternal(NetworkPacket np, final Device.SendPacketStatusCallback callback, PublicKey key) {
|
|
||||||
|
|
||||||
/*if (!isConnected()) {
|
/*if (!isConnected()) {
|
||||||
Log.e("BluetoothLink", "sendPacketEncrypted failed: not connected");
|
Log.e("BluetoothLink", "sendPacketEncrypted failed: not connected");
|
||||||
@ -186,15 +167,6 @@ public class BluetoothLink extends BaseLink {
|
|||||||
np.setPayloadTransferInfo(payloadTransferInfo);
|
np.setPayloadTransferInfo(payloadTransferInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key != null) {
|
|
||||||
try {
|
|
||||||
np = RsaHelper.encrypt(np, key);
|
|
||||||
} catch (Exception e) {
|
|
||||||
callback.onFailure(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMessage(np);
|
sendMessage(np);
|
||||||
|
|
||||||
if (serverSocket != null) {
|
if (serverSocket != null) {
|
||||||
|
@ -52,7 +52,7 @@ public class BluetoothPairingHandler extends BasePairingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void packageReceived(NetworkPacket np) throws Exception {
|
public void packageReceived(NetworkPacket np) {
|
||||||
|
|
||||||
boolean wantsPair = np.getBoolean("pair");
|
boolean wantsPair = np.getBoolean("pair");
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ import org.json.JSONObject;
|
|||||||
import org.kde.kdeconnect.Backends.BaseLink;
|
import org.kde.kdeconnect.Backends.BaseLink;
|
||||||
import org.kde.kdeconnect.Backends.BasePairingHandler;
|
import org.kde.kdeconnect.Backends.BasePairingHandler;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
|
||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
||||||
import org.kde.kdeconnect.Helpers.StringsHelper;
|
import org.kde.kdeconnect.Helpers.StringsHelper;
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
@ -42,7 +41,6 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.nio.channels.NotYetConnectedException;
|
import java.nio.channels.NotYetConnectedException;
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
@ -61,7 +59,7 @@ public class LanLink extends BaseLink {
|
|||||||
// because it's probably trying to find me and
|
// because it's probably trying to find me and
|
||||||
// potentially ask for pairing.
|
// potentially ask for pairing.
|
||||||
|
|
||||||
private volatile Socket socket = null;
|
private volatile SSLSocket socket = null;
|
||||||
|
|
||||||
private final LinkDisconnectedCallback callback;
|
private final LinkDisconnectedCallback callback;
|
||||||
|
|
||||||
@ -76,9 +74,9 @@ public class LanLink extends BaseLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Returns the old socket
|
//Returns the old socket
|
||||||
public Socket reset(final Socket newSocket, ConnectionStarted connectionSource) throws IOException {
|
public SSLSocket reset(final SSLSocket newSocket, ConnectionStarted connectionSource) throws IOException {
|
||||||
|
|
||||||
Socket oldSocket = socket;
|
SSLSocket oldSocket = socket;
|
||||||
socket = newSocket;
|
socket = newSocket;
|
||||||
|
|
||||||
this.connectionSource = connectionSource;
|
this.connectionSource = connectionSource;
|
||||||
@ -121,7 +119,7 @@ public class LanLink extends BaseLink {
|
|||||||
return oldSocket;
|
return oldSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LanLink(Context context, String deviceId, LanLinkProvider linkProvider, Socket socket, ConnectionStarted connectionSource) throws IOException {
|
public LanLink(Context context, String deviceId, LanLinkProvider linkProvider, SSLSocket socket, ConnectionStarted connectionSource) throws IOException {
|
||||||
super(context, deviceId, linkProvider);
|
super(context, deviceId, linkProvider);
|
||||||
callback = linkProvider;
|
callback = linkProvider;
|
||||||
reset(socket, connectionSource);
|
reset(socket, connectionSource);
|
||||||
@ -139,7 +137,8 @@ public class LanLink extends BaseLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Blocking, do not call from main thread
|
//Blocking, do not call from main thread
|
||||||
private boolean sendPacketInternal(NetworkPacket np, final Device.SendPacketStatusCallback callback, PublicKey key) {
|
@Override
|
||||||
|
public boolean sendPacket(NetworkPacket np, final Device.SendPacketStatusCallback callback) {
|
||||||
if (socket == null) {
|
if (socket == null) {
|
||||||
Log.e("KDE/sendPacket", "Not yet connected");
|
Log.e("KDE/sendPacket", "Not yet connected");
|
||||||
callback.onFailure(new NotYetConnectedException());
|
callback.onFailure(new NotYetConnectedException());
|
||||||
@ -159,11 +158,6 @@ public class LanLink extends BaseLink {
|
|||||||
server = null;
|
server = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encrypt if key provided
|
|
||||||
if (key != null) {
|
|
||||||
np = RsaHelper.encrypt(np, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Log.e("LanLink/sendPacket", np.getType());
|
//Log.e("LanLink/sendPacket", np.getType());
|
||||||
|
|
||||||
//Send body of the network package
|
//Send body of the network package
|
||||||
@ -188,9 +182,7 @@ public class LanLink extends BaseLink {
|
|||||||
payloadSocket = server.accept();
|
payloadSocket = server.accept();
|
||||||
|
|
||||||
//Convert to SSL if needed
|
//Convert to SSL if needed
|
||||||
if (socket instanceof SSLSocket) {
|
payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, false);
|
||||||
payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
outputStream = payloadSocket.getOutputStream();
|
outputStream = payloadSocket.getOutputStream();
|
||||||
inputStream = np.getPayload().getInputStream();
|
inputStream = np.getPayload().getInputStream();
|
||||||
@ -240,39 +232,15 @@ public class LanLink extends BaseLink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Blocking, do not call from main thread
|
|
||||||
@Override
|
|
||||||
public boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback) {
|
|
||||||
return sendPacketInternal(np, callback, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Blocking, do not call from main thread
|
|
||||||
@Override
|
|
||||||
public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) {
|
|
||||||
return sendPacketInternal(np, callback, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void receivedNetworkPacket(NetworkPacket np) {
|
private void receivedNetworkPacket(NetworkPacket np) {
|
||||||
|
|
||||||
if (np.getType().equals(NetworkPacket.PACKET_TYPE_ENCRYPTED)) {
|
|
||||||
try {
|
|
||||||
np = RsaHelper.decrypt(np, privateKey);
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e("KDE/onPacketReceived","Exception decrypting the package", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (np.hasPayloadTransferInfo()) {
|
if (np.hasPayloadTransferInfo()) {
|
||||||
Socket payloadSocket = new Socket();
|
Socket payloadSocket = new Socket();
|
||||||
try {
|
try {
|
||||||
int tcpPort = np.getPayloadTransferInfo().getInt("port");
|
int tcpPort = np.getPayloadTransferInfo().getInt("port");
|
||||||
InetSocketAddress deviceAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
|
InetSocketAddress deviceAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
|
||||||
payloadSocket.connect(new InetSocketAddress(deviceAddress.getAddress(), tcpPort));
|
payloadSocket.connect(new InetSocketAddress(deviceAddress.getAddress(), tcpPort));
|
||||||
// Use ssl if existing link is on ssl
|
payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, true);
|
||||||
if (socket instanceof SSLSocket) {
|
|
||||||
payloadSocket = SslHelper.convertToSslSocket(context, payloadSocket, getDeviceId(), true, true);
|
|
||||||
}
|
|
||||||
np.setPayload(new NetworkPacket.Payload(payloadSocket, np.getPayloadSize()));
|
np.setPayload(new NetworkPacket.Payload(payloadSocket, np.getPayloadSize()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
try { payloadSocket.close(); } catch(Exception ignored) { }
|
try { payloadSocket.close(); } catch(Exception ignored) { }
|
||||||
|
@ -66,9 +66,6 @@ import javax.net.ssl.SSLSocket;
|
|||||||
*/
|
*/
|
||||||
public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDisconnectedCallback {
|
public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDisconnectedCallback {
|
||||||
|
|
||||||
public static final int MIN_VERSION_WITH_SSL_SUPPORT = 6;
|
|
||||||
private static final int MIN_VERSION_WITH_NEW_PORT_SUPPORT = 7;
|
|
||||||
|
|
||||||
private final static int MIN_PORT = 1716;
|
private final static int MIN_PORT = 1716;
|
||||||
private final static int MAX_PORT = 1764;
|
private final static int MAX_PORT = 1764;
|
||||||
final static int PAYLOAD_TRANSFER_MIN_PORT = 1739;
|
final static int PAYLOAD_TRANSFER_MIN_PORT = 1739;
|
||||||
@ -93,7 +90,7 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
|
|||||||
}
|
}
|
||||||
|
|
||||||
//They received my UDP broadcast and are connecting to me. The first thing they sned should be their identity.
|
//They received my UDP broadcast and are connecting to me. The first thing they sned should be their identity.
|
||||||
private void tcpPacketReceived(Socket socket) throws Exception {
|
private void tcpPacketReceived(Socket socket) {
|
||||||
|
|
||||||
NetworkPacket networkPacket;
|
NetworkPacket networkPacket;
|
||||||
try {
|
try {
|
||||||
@ -116,7 +113,7 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
|
|||||||
}
|
}
|
||||||
|
|
||||||
//I've received their broadcast and should connect to their TCP socket and send my identity.
|
//I've received their broadcast and should connect to their TCP socket and send my identity.
|
||||||
private void udpPacketReceived(DatagramPacket packet) throws Exception {
|
private void udpPacketReceived(DatagramPacket packet) {
|
||||||
|
|
||||||
final InetAddress address = packet.getAddress();
|
final InetAddress address = packet.getAddress();
|
||||||
|
|
||||||
@ -136,11 +133,6 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_NEW_PORT_SUPPORT && identityPacket.getInt("tcpPort") < MIN_PORT) {
|
|
||||||
Log.w("KDE/LanLinkProvider", "Ignoring a udp broadcast from legacy port because it comes from a device which knows about the new port.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i("KDE/LanLinkProvider", "Broadcast identity package received from " + identityPacket.getString("deviceName"));
|
Log.i("KDE/LanLinkProvider", "Broadcast identity package received from " + identityPacket.getString("deviceName"));
|
||||||
|
|
||||||
int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT);
|
int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT);
|
||||||
@ -206,61 +198,56 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
|
|||||||
// If I'm the TCP server I will be the SSL client and viceversa.
|
// If I'm the TCP server I will be the SSL client and viceversa.
|
||||||
final boolean clientMode = (connectionStarted == LanLink.ConnectionStarted.Locally);
|
final boolean clientMode = (connectionStarted == LanLink.ConnectionStarted.Locally);
|
||||||
|
|
||||||
// Add ssl handler if device uses new protocol
|
// Do the SSL handshake
|
||||||
try {
|
try {
|
||||||
if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) {
|
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||||
|
boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
|
||||||
|
|
||||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) {
|
||||||
boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
|
//Device paired with and old version, we can't use it as we lack the certificate
|
||||||
|
BackgroundService.RunCommand(context, service -> {
|
||||||
|
Device device = service.getDevice(deviceId);
|
||||||
|
if (device == null) return;
|
||||||
|
device.unpair();
|
||||||
|
//Retry as unpaired
|
||||||
|
identityPacketReceived(identityPacket, socket, connectionStarted);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) {
|
Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted);
|
||||||
//Device paired with and old version, we can't use it as we lack the certificate
|
|
||||||
|
final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode);
|
||||||
|
sslsocket.addHandshakeCompletedListener(event -> {
|
||||||
|
String mode = clientMode ? "client" : "server";
|
||||||
|
try {
|
||||||
|
Certificate certificate = event.getPeerCertificates()[0];
|
||||||
|
identityPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
||||||
|
Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite());
|
||||||
|
addLink(identityPacket, sslsocket, connectionStarted);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName"), e);
|
||||||
BackgroundService.RunCommand(context, service -> {
|
BackgroundService.RunCommand(context, service -> {
|
||||||
Device device = service.getDevice(deviceId);
|
Device device = service.getDevice(deviceId);
|
||||||
if (device == null) return;
|
if (device == null) return;
|
||||||
device.unpair();
|
device.unpair();
|
||||||
//Retry as unpaired
|
|
||||||
identityPacketReceived(identityPacket, socket, connectionStarted);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted);
|
//Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection
|
||||||
|
new Thread(() -> {
|
||||||
final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode);
|
try {
|
||||||
sslsocket.addHandshakeCompletedListener(event -> {
|
synchronized (this) {
|
||||||
String mode = clientMode ? "client" : "server";
|
sslsocket.startHandshake();
|
||||||
try {
|
|
||||||
Certificate certificate = event.getPeerCertificates()[0];
|
|
||||||
identityPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
|
||||||
Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite());
|
|
||||||
addLink(identityPacket, sslsocket, connectionStarted);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName"), e);
|
|
||||||
BackgroundService.RunCommand(context, service -> {
|
|
||||||
Device device = service.getDevice(deviceId);
|
|
||||||
if (device == null) return;
|
|
||||||
device.unpair();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
} catch (Exception e) {
|
||||||
//Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection
|
Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName"), e);
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
synchronized (this) {
|
|
||||||
sslsocket.startHandshake();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName"), e);
|
|
||||||
|
|
||||||
//String[] ciphers = sslsocket.getSupportedCipherSuites();
|
//String[] ciphers = sslsocket.getSupportedCipherSuites();
|
||||||
//for (String cipher : ciphers) {
|
//for (String cipher : ciphers) {
|
||||||
// Log.i("SupportedCiphers","cipher: " + cipher);
|
// Log.i("SupportedCiphers","cipher: " + cipher);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
} else {
|
|
||||||
addLink(identityPacket, socket, connectionStarted);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("LanLink", "Exception", e);
|
Log.e("LanLink", "Exception", e);
|
||||||
}
|
}
|
||||||
@ -280,7 +267,7 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
|
|||||||
* @param connectionOrigin which side started this connection
|
* @param connectionOrigin which side started this connection
|
||||||
* @throws IOException if an exception is thrown by {@link LanLink#reset(Socket, LanLink.ConnectionStarted)}
|
* @throws IOException if an exception is thrown by {@link LanLink#reset(Socket, LanLink.ConnectionStarted)}
|
||||||
*/
|
*/
|
||||||
private void addLink(final NetworkPacket identityPacket, Socket socket, LanLink.ConnectionStarted connectionOrigin) throws IOException {
|
private void addLink(final NetworkPacket identityPacket, SSLSocket socket, LanLink.ConnectionStarted connectionOrigin) throws IOException {
|
||||||
|
|
||||||
String deviceId = identityPacket.getString("deviceId");
|
String deviceId = identityPacket.getString("deviceId");
|
||||||
LanLink currentLink = visibleComputers.get(deviceId);
|
LanLink currentLink = visibleComputers.get(deviceId);
|
||||||
|
@ -22,7 +22,6 @@ package org.kde.kdeconnect.Backends.LanBackend;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -31,9 +30,7 @@ import org.kde.kdeconnect.Device;
|
|||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
import org.kde.kdeconnect_tp.R;
|
import org.kde.kdeconnect_tp.R;
|
||||||
|
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.cert.CertificateEncodingException;
|
import java.security.cert.CertificateEncodingException;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
@ -54,14 +51,11 @@ public class LanPairingHandler extends BasePairingHandler {
|
|||||||
private NetworkPacket createPairPacket() {
|
private NetworkPacket createPairPacket() {
|
||||||
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
|
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
|
||||||
np.set("pair", true);
|
np.set("pair", true);
|
||||||
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(mDevice.getContext());
|
|
||||||
String publicKey = "-----BEGIN PUBLIC KEY-----\n" + globalSettings.getString("publicKey", "").trim()+ "\n-----END PUBLIC KEY-----\n";
|
|
||||||
np.set("publicKey", publicKey);
|
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void packageReceived(NetworkPacket np) throws Exception{
|
public void packageReceived(NetworkPacket np) {
|
||||||
|
|
||||||
boolean wantsPair = np.getBoolean("pair");
|
boolean wantsPair = np.getBoolean("pair");
|
||||||
|
|
||||||
@ -77,15 +71,6 @@ public class LanPairingHandler extends BasePairingHandler {
|
|||||||
|
|
||||||
if (wantsPair) {
|
if (wantsPair) {
|
||||||
|
|
||||||
//Retrieve their public key
|
|
||||||
try {
|
|
||||||
String publicKeyContent = np.getString("publicKey").replace("-----BEGIN PUBLIC KEY-----\n","").replace("-----END PUBLIC KEY-----\n", "");
|
|
||||||
byte[] publicKeyBytes = Base64.decode(publicKeyContent, 0);
|
|
||||||
mDevice.publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
|
|
||||||
} catch (Exception e) {
|
|
||||||
//IGNORE
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPairStatus == PairStatus.Requested) { //We started pairing
|
if (mPairStatus == PairStatus.Requested) { //We started pairing
|
||||||
|
|
||||||
hidePairingNotification();
|
hidePairingNotification();
|
||||||
@ -204,15 +189,6 @@ public class LanPairingHandler extends BasePairingHandler {
|
|||||||
//Log.e("KDE/PairingDone", "Pairing Done");
|
//Log.e("KDE/PairingDone", "Pairing Done");
|
||||||
SharedPreferences.Editor editor = mDevice.getContext().getSharedPreferences(mDevice.getDeviceId(), Context.MODE_PRIVATE).edit();
|
SharedPreferences.Editor editor = mDevice.getContext().getSharedPreferences(mDevice.getDeviceId(), Context.MODE_PRIVATE).edit();
|
||||||
|
|
||||||
if (mDevice.publicKey != null) {
|
|
||||||
try {
|
|
||||||
String encodedPublicKey = Base64.encodeToString(mDevice.publicKey.getEncoded(), 0);
|
|
||||||
editor.putString("publicKey", encodedPublicKey);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/PairingDone", "Error encoding public key", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String encodedCertificate = Base64.encodeToString(mDevice.certificate.getEncoded(), 0);
|
String encodedCertificate = Base64.encodeToString(mDevice.certificate.getEncoded(), 0);
|
||||||
editor.putString("certificate", encodedCertificate);
|
editor.putString("certificate", encodedCertificate);
|
||||||
|
@ -28,8 +28,6 @@ import org.kde.kdeconnect.Backends.BasePairingHandler;
|
|||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
public class LoopbackLink extends BaseLink {
|
public class LoopbackLink extends BaseLink {
|
||||||
|
|
||||||
public LoopbackLink(Context context, BaseLinkProvider linkProvider) {
|
public LoopbackLink(Context context, BaseLinkProvider linkProvider) {
|
||||||
@ -58,8 +56,4 @@ public class LoopbackLink extends BaseLink {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) {
|
|
||||||
return sendPacket(np, callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class LoopbackPairingHandler extends BasePairingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void packageReceived(NetworkPacket np) throws Exception {
|
public void packageReceived(NetworkPacket np) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.kde.kdeconnect.Backends.BaseLink;
|
import org.kde.kdeconnect.Backends.BaseLink;
|
||||||
import org.kde.kdeconnect.Backends.BasePairingHandler;
|
import org.kde.kdeconnect.Backends.BasePairingHandler;
|
||||||
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
|
|
||||||
import org.kde.kdeconnect.Helpers.NotificationHelper;
|
import org.kde.kdeconnect.Helpers.NotificationHelper;
|
||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
||||||
import org.kde.kdeconnect.Plugins.Plugin;
|
import org.kde.kdeconnect.Plugins.Plugin;
|
||||||
@ -45,10 +44,8 @@ import org.kde.kdeconnect_tp.R;
|
|||||||
|
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -68,7 +65,6 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
|
|
||||||
private final String deviceId;
|
private final String deviceId;
|
||||||
private String name;
|
private String name;
|
||||||
public PublicKey publicKey;
|
|
||||||
public Certificate certificate;
|
public Certificate certificate;
|
||||||
private int notificationId;
|
private int notificationId;
|
||||||
private int protocolVersion;
|
private int protocolVersion;
|
||||||
@ -150,16 +146,6 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
this.protocolVersion = NetworkPacket.ProtocolVersion; //We don't know it yet
|
this.protocolVersion = NetworkPacket.ProtocolVersion; //We don't know it yet
|
||||||
this.deviceType = DeviceType.FromString(settings.getString("deviceType", "desktop"));
|
this.deviceType = DeviceType.FromString(settings.getString("deviceType", "desktop"));
|
||||||
|
|
||||||
try {
|
|
||||||
String publicKeyStr = settings.getString("publicKey", null);
|
|
||||||
if (publicKeyStr != null) {
|
|
||||||
byte[] publicKeyBytes = Base64.decode(publicKeyStr, 0);
|
|
||||||
publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/Device", "Exception deserializing stored public key for device", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Assume every plugin is supported until addLink is called and we can get the actual list
|
//Assume every plugin is supported until addLink is called and we can get the actual list
|
||||||
m_supportedPlugins = new Vector<>(PluginFactory.getAvailablePlugins());
|
m_supportedPlugins = new Vector<>(PluginFactory.getAvailablePlugins());
|
||||||
|
|
||||||
@ -178,7 +164,6 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
this.pairStatus = PairStatus.NotPaired;
|
this.pairStatus = PairStatus.NotPaired;
|
||||||
this.protocolVersion = 0;
|
this.protocolVersion = 0;
|
||||||
this.deviceType = DeviceType.Computer;
|
this.deviceType = DeviceType.Computer;
|
||||||
this.publicKey = null;
|
|
||||||
|
|
||||||
settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
|
settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
|
||||||
|
|
||||||
@ -546,8 +531,6 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
@Override
|
@Override
|
||||||
public void onPacketReceived(NetworkPacket np) {
|
public void onPacketReceived(NetworkPacket np) {
|
||||||
|
|
||||||
hackToMakeRetrocompatiblePacketTypes(np);
|
|
||||||
|
|
||||||
if (NetworkPacket.PACKET_TYPE_PAIR.equals(np.getType())) {
|
if (NetworkPacket.PACKET_TYPE_PAIR.equals(np.getType())) {
|
||||||
|
|
||||||
Log.i("KDE/Device", "Pair package");
|
Log.i("KDE/Device", "Pair package");
|
||||||
@ -651,20 +634,12 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hackToMakeRetrocompatiblePacketTypes(np);
|
|
||||||
|
|
||||||
boolean useEncryption = (protocolVersion < LanLinkProvider.MIN_VERSION_WITH_SSL_SUPPORT && (!np.getType().equals(NetworkPacket.PACKET_TYPE_PAIR) && isPaired()));
|
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
//Make a copy to avoid concurrent modification exception if the original list changes
|
//Make a copy to avoid concurrent modification exception if the original list changes
|
||||||
for (final BaseLink link : links) {
|
for (final BaseLink link : links) {
|
||||||
if (link == null)
|
if (link == null)
|
||||||
continue; //Since we made a copy, maybe somebody destroyed the link in the meanwhile
|
continue; //Since we made a copy, maybe somebody destroyed the link in the meanwhile
|
||||||
if (useEncryption) {
|
success = link.sendPacket(np, callback);
|
||||||
success = link.sendPacketEncrypted(np, callback, publicKey);
|
|
||||||
} else {
|
|
||||||
success = link.sendPacket(np, callback);
|
|
||||||
}
|
|
||||||
if (success) break; //If the link didn't call sendSuccess(), try the next one
|
if (success) break; //If the link didn't call sendSuccess(), try the next one
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,7 +771,6 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
boolean success = addPlugin(pluginKey);
|
boolean success = addPlugin(pluginKey);
|
||||||
if (success) {
|
if (success) {
|
||||||
for (String packageType : pluginInfo.getSupportedPacketTypes()) {
|
for (String packageType : pluginInfo.getSupportedPacketTypes()) {
|
||||||
packageType = hackToMakeRetrocompatiblePacketTypes(packageType);
|
|
||||||
ArrayList<String> plugins = newPluginsByIncomingInterface.get(packageType);
|
ArrayList<String> plugins = newPluginsByIncomingInterface.get(packageType);
|
||||||
if (plugins == null) plugins = new ArrayList<>();
|
if (plugins == null) plugins = new ArrayList<>();
|
||||||
plugins.add(pluginKey);
|
plugins.add(pluginKey);
|
||||||
@ -866,14 +840,4 @@ public class Device implements BaseLink.PacketReceiver {
|
|||||||
return m_supportedPlugins;
|
return m_supportedPlugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hackToMakeRetrocompatiblePacketTypes(NetworkPacket np) {
|
|
||||||
if (protocolVersion >= 6) return;
|
|
||||||
np.mType = np.getType().replace(".request", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private String hackToMakeRetrocompatiblePacketTypes(String type) {
|
|
||||||
if (protocolVersion >= 6) return type;
|
|
||||||
return type.replace(".request", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,6 @@ import android.preference.PreferenceManager;
|
|||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
@ -40,8 +35,6 @@ import java.security.PublicKey;
|
|||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
|
|
||||||
public class RsaHelper {
|
public class RsaHelper {
|
||||||
|
|
||||||
public static void initialiseRsaKeys(Context context) {
|
public static void initialiseRsaKeys(Context context) {
|
||||||
@ -77,67 +70,12 @@ public class RsaHelper {
|
|||||||
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
|
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PublicKey getPublicKey(Context context, String deviceId) throws GeneralSecurityException {
|
|
||||||
SharedPreferences settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
|
|
||||||
byte[] publicKeyBytes = Base64.decode(settings.getString("publicKey", ""), 0);
|
|
||||||
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PrivateKey getPrivateKey(Context context) throws GeneralSecurityException {
|
public static PrivateKey getPrivateKey(Context context) throws GeneralSecurityException {
|
||||||
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
byte[] privateKeyBytes = Base64.decode(globalSettings.getString("privateKey", ""), 0);
|
byte[] privateKeyBytes = Base64.decode(globalSettings.getString("privateKey", ""), 0);
|
||||||
return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
|
return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NetworkPacket encrypt(NetworkPacket np, PublicKey publicKey) throws GeneralSecurityException, JSONException {
|
|
||||||
|
|
||||||
String serialized = np.serialize();
|
|
||||||
|
|
||||||
int chunkSize = 128;
|
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
|
|
||||||
JSONArray chunks = new JSONArray();
|
|
||||||
while (serialized.length() > 0) {
|
|
||||||
if (serialized.length() < chunkSize) {
|
|
||||||
chunkSize = serialized.length();
|
|
||||||
}
|
|
||||||
String chunk = serialized.substring(0, chunkSize);
|
|
||||||
serialized = serialized.substring(chunkSize);
|
|
||||||
byte[] chunkBytes = chunk.getBytes(Charset.defaultCharset());
|
|
||||||
byte[] encryptedChunk;
|
|
||||||
encryptedChunk = cipher.doFinal(chunkBytes);
|
|
||||||
chunks.put(Base64.encodeToString(encryptedChunk, Base64.NO_WRAP));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Log.i("NetworkPacket", "Encrypted " + chunks.length()+" chunks");
|
|
||||||
|
|
||||||
NetworkPacket encrypted = new NetworkPacket(NetworkPacket.PACKET_TYPE_ENCRYPTED);
|
|
||||||
encrypted.set("data", chunks);
|
|
||||||
encrypted.setPayload(np.getPayload());
|
|
||||||
return encrypted;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NetworkPacket decrypt(NetworkPacket np, PrivateKey privateKey) throws GeneralSecurityException, JSONException {
|
|
||||||
|
|
||||||
JSONArray chunks = np.getJSONArray("data");
|
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
|
|
||||||
StringBuilder decryptedJson = new StringBuilder();
|
|
||||||
for (int i = 0; i < chunks.length(); i++) {
|
|
||||||
byte[] encryptedChunk = Base64.decode(chunks.getString(i), Base64.NO_WRAP);
|
|
||||||
String decryptedChunk = new String(cipher.doFinal(encryptedChunk));
|
|
||||||
decryptedJson.append(decryptedChunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkPacket decrypted = NetworkPacket.unserialize(decryptedJson.toString());
|
|
||||||
decrypted.setPayload(np.getPayload());
|
|
||||||
return decrypted;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -65,11 +65,6 @@ import javax.net.ssl.X509TrustManager;
|
|||||||
|
|
||||||
public class SslHelper {
|
public class SslHelper {
|
||||||
|
|
||||||
public enum SslMode {
|
|
||||||
Client,
|
|
||||||
Server
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Certificate certificate; //my device's certificate
|
public static X509Certificate certificate; //my device's certificate
|
||||||
|
|
||||||
public static final BouncyCastleProvider BC = new BouncyCastleProvider();
|
public static final BouncyCastleProvider BC = new BouncyCastleProvider();
|
||||||
|
@ -44,12 +44,10 @@ public class NetworkPacket {
|
|||||||
|
|
||||||
public final static String PACKET_TYPE_IDENTITY = "kdeconnect.identity";
|
public final static String PACKET_TYPE_IDENTITY = "kdeconnect.identity";
|
||||||
public final static String PACKET_TYPE_PAIR = "kdeconnect.pair";
|
public final static String PACKET_TYPE_PAIR = "kdeconnect.pair";
|
||||||
public final static String PACKET_TYPE_ENCRYPTED = "kdeconnect.encrypted";
|
|
||||||
|
|
||||||
public static Set<String> protocolPacketTypes = new HashSet<String>() {{
|
public static Set<String> protocolPacketTypes = new HashSet<String>() {{
|
||||||
add(PACKET_TYPE_IDENTITY);
|
add(PACKET_TYPE_IDENTITY);
|
||||||
add(PACKET_TYPE_PAIR);
|
add(PACKET_TYPE_PAIR);
|
||||||
add(PACKET_TYPE_ENCRYPTED);
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
private long mId;
|
private long mId;
|
||||||
|
@ -25,7 +25,6 @@ import android.content.Context;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
@ -185,21 +184,6 @@ public abstract class Plugin {
|
|||||||
*/
|
*/
|
||||||
public abstract String[] getOutgoingPacketTypes();
|
public abstract String[] getOutgoingPacketTypes();
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a button that will be displayed in the user interface
|
|
||||||
* It can open an activity or perform any other action that the
|
|
||||||
* plugin would wants to expose to the user. Return null if no
|
|
||||||
* button should be displayed.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public Button getInterfaceButton(final Activity activity) {
|
|
||||||
if (!hasMainActivity()) return null;
|
|
||||||
Button b = new Button(activity);
|
|
||||||
b.setText(getActionName());
|
|
||||||
b.setOnClickListener(view -> startMainActivity(activity));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String[] getRequiredPermissions() {
|
protected String[] getRequiredPermissions() {
|
||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ public class AndroidSafSshFile implements SshFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Attribute, Object> getAttributes(boolean followLinks) throws IOException {
|
public Map<Attribute, Object> getAttributes(boolean followLinks) {
|
||||||
Map<SshFile.Attribute, Object> attributes = new HashMap<>();
|
Map<SshFile.Attribute, Object> attributes = new HashMap<>();
|
||||||
for (SshFile.Attribute attr : SshFile.Attribute.values()) {
|
for (SshFile.Attribute attr : SshFile.Attribute.values()) {
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
|
@ -53,7 +53,7 @@ class RootFile implements SshFile {
|
|||||||
return "/";
|
return "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Attribute, Object> getAttributes(boolean followLinks) throws IOException {
|
public Map<Attribute, Object> getAttributes(boolean followLinks) {
|
||||||
Map<Attribute, Object> attrs = new HashMap<>();
|
Map<Attribute, Object> attrs = new HashMap<>();
|
||||||
|
|
||||||
attrs.put(Attribute.Size, 0);
|
attrs.put(Attribute.Size, 0);
|
||||||
|
@ -95,11 +95,8 @@ class SimpleSftpServer {
|
|||||||
sshd.setCommandFactory(new ScpCommandFactory());
|
sshd.setCommandFactory(new ScpCommandFactory());
|
||||||
sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystem.Factory()));
|
sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystem.Factory()));
|
||||||
|
|
||||||
if (device.publicKey != null) {
|
keyAuth.deviceKey = device.certificate.getPublicKey();
|
||||||
keyAuth.deviceKey = device.publicKey;
|
|
||||||
} else {
|
|
||||||
keyAuth.deviceKey = device.certificate.getPublicKey();
|
|
||||||
}
|
|
||||||
sshd.setPublickeyAuthenticator(keyAuth);
|
sshd.setPublickeyAuthenticator(keyAuth);
|
||||||
sshd.setPasswordAuthenticator(passwordAuth);
|
sshd.setPasswordAuthenticator(passwordAuth);
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ public class DeviceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPairingDoneWithCertificate() throws Exception {
|
public void testPairingDoneWithCertificate() {
|
||||||
KeyPair keyPair = null;
|
KeyPair keyPair = null;
|
||||||
try {
|
try {
|
||||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||||
|
@ -43,6 +43,8 @@ import java.io.OutputStream;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
@RunWith(PowerMockRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
@ -71,11 +73,11 @@ public class LanLinkTest {
|
|||||||
Mockito.doThrow(new IOException("AAA")).when(badOutputStream).write(Mockito.any(byte[].class));
|
Mockito.doThrow(new IOException("AAA")).when(badOutputStream).write(Mockito.any(byte[].class));
|
||||||
|
|
||||||
|
|
||||||
Socket socketMock = Mockito.mock(Socket.class);
|
SSLSocket socketMock = Mockito.mock(SSLSocket.class);
|
||||||
Mockito.when(socketMock.getRemoteSocketAddress()).thenReturn(new InetSocketAddress(5000));
|
Mockito.when(socketMock.getRemoteSocketAddress()).thenReturn(new InetSocketAddress(5000));
|
||||||
Mockito.when(socketMock.getOutputStream()).thenReturn(goodOutputStream);
|
Mockito.when(socketMock.getOutputStream()).thenReturn(goodOutputStream);
|
||||||
|
|
||||||
Socket socketBadMock = Mockito.mock(Socket.class);
|
SSLSocket socketBadMock = Mockito.mock(SSLSocket.class);
|
||||||
Mockito.when(socketBadMock.getRemoteSocketAddress()).thenReturn(new InetSocketAddress(5000));
|
Mockito.when(socketBadMock.getRemoteSocketAddress()).thenReturn(new InetSocketAddress(5000));
|
||||||
Mockito.when(socketBadMock.getOutputStream()).thenReturn(badOutputStream);
|
Mockito.when(socketBadMock.getOutputStream()).thenReturn(badOutputStream);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user