2
0
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:
Vineet Garg 2015-06-20 20:54:39 +05:30
parent 41100ad371
commit 8128c42824
6 changed files with 85 additions and 22 deletions

View File

@ -20,6 +20,8 @@
package org.kde.kdeconnect.Backends;
import android.content.Context;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
@ -30,12 +32,14 @@ import java.util.ArrayList;
public abstract class BaseLink {
protected final Context context;
private final BaseLinkProvider linkProvider;
private final String deviceId;
protected final String deviceId;
private final ArrayList<PackageReceiver> receivers = new ArrayList<PackageReceiver>();
protected PrivateKey privateKey;
protected BaseLink(String deviceId, BaseLinkProvider linkProvider) {
protected BaseLink(Context context,String deviceId, BaseLinkProvider linkProvider) {
this.context = context;
this.linkProvider = linkProvider;
this.deviceId = deviceId;
}

View File

@ -20,6 +20,7 @@
package org.kde.kdeconnect.Backends.LanBackend;
import android.content.Context;
import android.util.Log;
import org.json.JSONObject;
@ -27,6 +28,7 @@ import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import org.kde.kdeconnect.NetworkPackage;
import java.io.IOException;
@ -37,9 +39,9 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.NotYetConnectedException;
import java.security.PublicKey;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeoutException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
@ -61,8 +63,8 @@ public class LanLink extends BaseLink {
this.onSsl = value;
}
public LanLink(Channel channel, String deviceId, BaseLinkProvider linkProvider) {
super(deviceId, linkProvider);
public LanLink(Context context,Channel channel, String deviceId, BaseLinkProvider linkProvider) {
super(context,deviceId, linkProvider);
this.channel = channel;
}
@ -79,7 +81,7 @@ public class LanLink extends BaseLink {
//Prepare socket for the payload
final ServerSocket server;
if (np.hasPayload()) {
server = openTcpSocketOnFreePort();
server = openTcpSocketOnFreePort(context, deviceId, onSsl);
JSONObject payloadTransferInfo = new JSONObject();
payloadTransferInfo.put("port", server.getLocalPort());
np.setPayloadTransferInfo(payloadTransferInfo);
@ -182,11 +184,19 @@ public class LanLink extends BaseLink {
Socket socket = null;
try {
// 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");
InetSocketAddress address = (InetSocketAddress)channel.remoteAddress();
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
np.setPayload(socket.getInputStream(), np.getPayloadSize());
Log.e("KDE/LanLink", "Has payload ");
} catch (Exception e) {
try { socket.close(); } catch(Exception ignored) { }
e.printStackTrace();
@ -198,8 +208,16 @@ public class LanLink extends BaseLink {
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;
int tcpPort = 1739;
ServerSocket candidateServer = null;
@ -221,4 +239,30 @@ public class LanLink extends BaseLink {
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;
}
}

View File

@ -149,6 +149,7 @@ public class LanLinkProvider extends BaseLinkProvider {
}
final NetworkPackage np = NetworkPackage.unserialize(theMessage);
Log.e("KDE/LanLinkProvider", theMessage);
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"));
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);
//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");
}
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() {
@Override
public void run() {

View File

@ -20,6 +20,8 @@
package org.kde.kdeconnect.Backends.LoopbackBackend;
import android.content.Context;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Device;
@ -30,8 +32,8 @@ import java.security.PublicKey;
public class LoopbackLink extends BaseLink {
public LoopbackLink(BaseLinkProvider linkProvider) {
super("loopback", linkProvider);
public LoopbackLink(Context context, BaseLinkProvider linkProvider) {
super(context, "loopback", linkProvider);
}
@Override

View File

@ -45,7 +45,7 @@ public class LoopbackLinkProvider extends BaseLinkProvider {
@Override
public void onNetworkChange() {
NetworkPackage np = NetworkPackage.createIdentityPackage(context);
connectionAccepted(np, new LoopbackLink(this));
connectionAccepted(np, new LoopbackLink(context, this));
}
/*
@Override

View File

@ -45,6 +45,7 @@ import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@ -121,13 +122,8 @@ public class SslHelper {
}
}
public static SSLEngine getSslEngine(final Context context, final String deviceId, SslMode sslMode) {
try{
// Check whether device is trusted or not
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
final boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
public static SSLContext getSslContext(Context context, String deviceId, boolean isDeviceTrusted) {
try {
// Get device private key
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
@ -181,7 +177,23 @@ public class SslHelper {
}else {
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();
if (sslMode == SslMode.Client){