mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-29 13:17:43 +00:00
Added support to send payload over ssl
This commit is contained in:
parent
41100ad371
commit
8128c42824
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
package org.kde.kdeconnect.Backends;
|
package org.kde.kdeconnect.Backends;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.NetworkPackage;
|
import org.kde.kdeconnect.NetworkPackage;
|
||||||
|
|
||||||
@ -30,12 +32,14 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public abstract class BaseLink {
|
public abstract class BaseLink {
|
||||||
|
|
||||||
|
protected final Context context;
|
||||||
private final BaseLinkProvider linkProvider;
|
private final BaseLinkProvider linkProvider;
|
||||||
private final String deviceId;
|
protected final String deviceId;
|
||||||
private final ArrayList<PackageReceiver> receivers = new ArrayList<PackageReceiver>();
|
private final ArrayList<PackageReceiver> receivers = new ArrayList<PackageReceiver>();
|
||||||
protected PrivateKey privateKey;
|
protected PrivateKey privateKey;
|
||||||
|
|
||||||
protected BaseLink(String deviceId, BaseLinkProvider linkProvider) {
|
protected BaseLink(Context context,String deviceId, BaseLinkProvider linkProvider) {
|
||||||
|
this.context = context;
|
||||||
this.linkProvider = linkProvider;
|
this.linkProvider = linkProvider;
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
package org.kde.kdeconnect.Backends.LanBackend;
|
package org.kde.kdeconnect.Backends.LanBackend;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@ -27,6 +28,7 @@ import org.kde.kdeconnect.Backends.BaseLink;
|
|||||||
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||||
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
||||||
import org.kde.kdeconnect.NetworkPackage;
|
import org.kde.kdeconnect.NetworkPackage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -37,9 +39,9 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.channels.NotYetConnectedException;
|
import java.nio.channels.NotYetConnectedException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
import javax.net.ssl.SSLContext;
|
||||||
import java.util.concurrent.TimeoutException;
|
import javax.net.ssl.SSLServerSocketFactory;
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
@ -61,8 +63,8 @@ public class LanLink extends BaseLink {
|
|||||||
this.onSsl = value;
|
this.onSsl = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LanLink(Channel channel, String deviceId, BaseLinkProvider linkProvider) {
|
public LanLink(Context context,Channel channel, String deviceId, BaseLinkProvider linkProvider) {
|
||||||
super(deviceId, linkProvider);
|
super(context,deviceId, linkProvider);
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ public class LanLink extends BaseLink {
|
|||||||
//Prepare socket for the payload
|
//Prepare socket for the payload
|
||||||
final ServerSocket server;
|
final ServerSocket server;
|
||||||
if (np.hasPayload()) {
|
if (np.hasPayload()) {
|
||||||
server = openTcpSocketOnFreePort();
|
server = openTcpSocketOnFreePort(context, deviceId, onSsl);
|
||||||
JSONObject payloadTransferInfo = new JSONObject();
|
JSONObject payloadTransferInfo = new JSONObject();
|
||||||
payloadTransferInfo.put("port", server.getLocalPort());
|
payloadTransferInfo.put("port", server.getLocalPort());
|
||||||
np.setPayloadTransferInfo(payloadTransferInfo);
|
np.setPayloadTransferInfo(payloadTransferInfo);
|
||||||
@ -182,11 +184,19 @@ public class LanLink extends BaseLink {
|
|||||||
|
|
||||||
Socket socket = null;
|
Socket socket = null;
|
||||||
try {
|
try {
|
||||||
socket = new Socket();
|
// Use ssl if existing link is on ssl
|
||||||
|
if (onSsl) {
|
||||||
|
SSLContext sslContext = SslHelper.getSslContext(context, deviceId, true);
|
||||||
|
socket = sslContext.getSocketFactory().createSocket();
|
||||||
|
} else {
|
||||||
|
socket = new Socket();
|
||||||
|
}
|
||||||
|
|
||||||
int tcpPort = np.getPayloadTransferInfo().getInt("port");
|
int tcpPort = np.getPayloadTransferInfo().getInt("port");
|
||||||
InetSocketAddress address = (InetSocketAddress)channel.remoteAddress();
|
InetSocketAddress address = (InetSocketAddress)channel.remoteAddress();
|
||||||
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
|
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
|
||||||
np.setPayload(socket.getInputStream(), np.getPayloadSize());
|
np.setPayload(socket.getInputStream(), np.getPayloadSize());
|
||||||
|
Log.e("KDE/LanLink", "Has payload ");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
try { socket.close(); } catch(Exception ignored) { }
|
try { socket.close(); } catch(Exception ignored) { }
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -198,8 +208,16 @@ public class LanLink extends BaseLink {
|
|||||||
packageReceived(np);
|
packageReceived(np);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ServerSocket openTcpSocketOnFreePort(Context context, String deviceId, boolean onSsl) throws IOException {
|
||||||
|
if (onSsl) {
|
||||||
|
return openSecureServerSocket(context, deviceId);
|
||||||
|
} else {
|
||||||
|
return openUnsecureSocketOnFreePort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ServerSocket openTcpSocketOnFreePort() throws IOException {
|
|
||||||
|
static ServerSocket openUnsecureSocketOnFreePort() throws IOException {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
int tcpPort = 1739;
|
int tcpPort = 1739;
|
||||||
ServerSocket candidateServer = null;
|
ServerSocket candidateServer = null;
|
||||||
@ -221,4 +239,30 @@ public class LanLink extends BaseLink {
|
|||||||
return candidateServer;
|
return candidateServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ServerSocket openSecureServerSocket(Context context, String deviceId) throws IOException{
|
||||||
|
boolean success = false;
|
||||||
|
int tcpPort = 1739;
|
||||||
|
|
||||||
|
SSLContext tlsContext = SslHelper.getSslContext(context, deviceId, true);
|
||||||
|
SSLServerSocketFactory sslServerSocketFactory = tlsContext.getServerSocketFactory();
|
||||||
|
|
||||||
|
ServerSocket candidateServer = null;
|
||||||
|
while(!success) {
|
||||||
|
try {
|
||||||
|
candidateServer = sslServerSocketFactory.createServerSocket();
|
||||||
|
candidateServer.bind(new InetSocketAddress(tcpPort));
|
||||||
|
success = true;
|
||||||
|
Log.i("LanLink", "Using port "+tcpPort);
|
||||||
|
} catch(IOException e) {
|
||||||
|
//Log.e("LanLink", "Exception opening serversocket: "+e);
|
||||||
|
tcpPort++;
|
||||||
|
if (tcpPort >= 1764) {
|
||||||
|
Log.e("LanLink", "No more ports available");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return candidateServer;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final NetworkPackage np = NetworkPackage.unserialize(theMessage);
|
final NetworkPackage np = NetworkPackage.unserialize(theMessage);
|
||||||
|
Log.e("KDE/LanLinkProvider", theMessage);
|
||||||
|
|
||||||
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
|
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
|
||||||
|
|
||||||
@ -159,7 +160,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
|
|
||||||
//Log.i("KDE/LanLinkProvider", "Identity package received from " + np.getString("deviceName"));
|
//Log.i("KDE/LanLinkProvider", "Identity package received from " + np.getString("deviceName"));
|
||||||
|
|
||||||
final LanLink link = new LanLink(ctx.channel(), np.getString("deviceId"), LanLinkProvider.this);
|
final LanLink link = new LanLink(context, ctx.channel(), np.getString("deviceId"), LanLinkProvider.this);
|
||||||
nioLinks.put(ctx.channel().hashCode(), link);
|
nioLinks.put(ctx.channel().hashCode(), link);
|
||||||
//Log.i("KDE/LanLinkProvider","nioLinks.size(): " + nioLinks.size());
|
//Log.i("KDE/LanLinkProvider","nioLinks.size(): " + nioLinks.size());
|
||||||
|
|
||||||
@ -258,7 +259,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
Log.e("KDE/LanLinkProvider", "Remote device supports ssl, ssl handler added");
|
Log.e("KDE/LanLinkProvider", "Remote device supports ssl, ssl handler added");
|
||||||
}
|
}
|
||||||
|
|
||||||
final LanLink link = new LanLink(channel, identityPackage.getString("deviceId"), LanLinkProvider.this);
|
final LanLink link = new LanLink(context, channel, identityPackage.getString("deviceId"), LanLinkProvider.this);
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
package org.kde.kdeconnect.Backends.LoopbackBackend;
|
package org.kde.kdeconnect.Backends.LoopbackBackend;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
import org.kde.kdeconnect.Backends.BaseLink;
|
import org.kde.kdeconnect.Backends.BaseLink;
|
||||||
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
import org.kde.kdeconnect.Backends.BaseLinkProvider;
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
@ -30,8 +32,8 @@ import java.security.PublicKey;
|
|||||||
|
|
||||||
public class LoopbackLink extends BaseLink {
|
public class LoopbackLink extends BaseLink {
|
||||||
|
|
||||||
public LoopbackLink(BaseLinkProvider linkProvider) {
|
public LoopbackLink(Context context, BaseLinkProvider linkProvider) {
|
||||||
super("loopback", linkProvider);
|
super(context, "loopback", linkProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,7 +45,7 @@ public class LoopbackLinkProvider extends BaseLinkProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void onNetworkChange() {
|
public void onNetworkChange() {
|
||||||
NetworkPackage np = NetworkPackage.createIdentityPackage(context);
|
NetworkPackage np = NetworkPackage.createIdentityPackage(context);
|
||||||
connectionAccepted(np, new LoopbackLink(this));
|
connectionAccepted(np, new LoopbackLink(context, this));
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,6 +45,7 @@ import java.security.SecureRandom;
|
|||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.net.ssl.KeyManager;
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
@ -121,13 +122,8 @@ public class SslHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SSLEngine getSslEngine(final Context context, final String deviceId, SslMode sslMode) {
|
public static SSLContext getSslContext(Context context, String deviceId, boolean isDeviceTrusted) {
|
||||||
|
try {
|
||||||
try{
|
|
||||||
// Check whether device is trusted or not
|
|
||||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
|
||||||
final boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
|
|
||||||
|
|
||||||
// Get device private key
|
// Get device private key
|
||||||
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
|
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
|
||||||
|
|
||||||
@ -181,7 +177,23 @@ public class SslHelper {
|
|||||||
}else {
|
}else {
|
||||||
tlsContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom());
|
tlsContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom());
|
||||||
}
|
}
|
||||||
|
return tlsContext;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("KDE/SslHelper", "Error creating tls context");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SSLEngine getSslEngine(final Context context, final String deviceId, SslMode sslMode) {
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||||
|
final boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
|
||||||
|
|
||||||
|
SSLContext tlsContext = getSslContext(context, deviceId, isDeviceTrusted);
|
||||||
SSLEngine sslEngine = tlsContext.createSSLEngine();
|
SSLEngine sslEngine = tlsContext.createSSLEngine();
|
||||||
|
|
||||||
if (sslMode == SslMode.Client){
|
if (sslMode == SslMode.Client){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user