mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-31 06:05:12 +00:00
Corrected unit tests
Settings were not save properly when certificate was null Removed LanLinkProvider test, impossible with new design
This commit is contained in:
@@ -196,7 +196,6 @@ public class LanLink extends BaseLink {
|
||||
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();
|
||||
@@ -208,8 +207,8 @@ public class LanLink extends BaseLink {
|
||||
packageReceived(np);
|
||||
}
|
||||
|
||||
static ServerSocket openTcpSocketOnFreePort(Context context, String deviceId, boolean onSsl) throws IOException {
|
||||
if (onSsl) {
|
||||
static ServerSocket openTcpSocketOnFreePort(Context context, String deviceId, boolean useSsl) throws IOException {
|
||||
if (useSsl) {
|
||||
return openSecureServerSocket(context, deviceId);
|
||||
} else {
|
||||
return openUnsecureSocketOnFreePort();
|
||||
|
@@ -85,17 +85,12 @@ public class LanLinkProvider extends BaseLinkProvider {
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
cause.printStackTrace();
|
||||
// TODO : Add necessary action on ssl handshake failure
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
Log.e("KDE/LanLinkProvider", "Channel Active : " + ctx.channel().hashCode());
|
||||
// If certificate changed, getting SocketException, connection reset by peer
|
||||
// Ssl engines closes by itself, so do channel and link is removed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
Log.e("KDE/LanLinkProvider", "Channel In active :" + ctx.channel().hashCode());
|
||||
try {
|
||||
long id = ctx.channel().hashCode();
|
||||
final LanLink brokenLink = nioLinks.get(id);
|
||||
@@ -131,9 +126,9 @@ public class LanLinkProvider extends BaseLinkProvider {
|
||||
}).start();
|
||||
|
||||
}
|
||||
} catch (Exception e) { //If we don't catch it here, Mina will swallow it :/
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("KDE/LanLinkProvider", "sessionClosed exception");
|
||||
Log.e("KDE/LanLinkProvider", "channelInactive exception");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +145,6 @@ public class LanLinkProvider extends BaseLinkProvider {
|
||||
}
|
||||
|
||||
final NetworkPackage np = NetworkPackage.unserialize(theMessage);
|
||||
Log.e("KDE/LanLinkProvider", theMessage);
|
||||
|
||||
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
|
||||
|
||||
@@ -165,8 +159,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
||||
nioLinks.put(ctx.channel().hashCode(), link);
|
||||
//Log.i("KDE/LanLinkProvider","nioLinks.size(): " + nioLinks.size());
|
||||
|
||||
// Check if ssl supported, and add ssl handler
|
||||
// Sslengine is returning null in some cases
|
||||
// Check if ssl supported on other device and enabled on my device, and add ssl handler
|
||||
try {
|
||||
if (myIdentityPackage.getBoolean("sslSupported") && np.getBoolean("sslSupported", false)) {
|
||||
Log.e("KDE/LanLinkProvider", "Remote device " + np.getString("deviceName") + " supports ssl");
|
||||
@@ -190,7 +183,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
addLink(np, link); // If error in ssl engine, which is returning null in some cases
|
||||
addLink(np, link); // If exception getting ssl engine
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -211,7 +204,6 @@ public class LanLinkProvider extends BaseLinkProvider {
|
||||
protected void channelRead0(final ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
|
||||
try {
|
||||
String theMessage = packet.content().toString(CharsetUtil.UTF_8);
|
||||
Log.e("KDE/LanLinkProvider", "Udp message received : " + theMessage);
|
||||
|
||||
final NetworkPackage identityPackage = NetworkPackage.unserialize(theMessage);
|
||||
|
||||
@@ -221,7 +213,6 @@ public class LanLinkProvider extends BaseLinkProvider {
|
||||
} else {
|
||||
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
|
||||
if (identityPackage.getString("deviceId").equals(myId)) {
|
||||
Log.e("KDE/LanLinkProvider", "Oh, its my identity package");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -28,7 +28,6 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -305,17 +304,19 @@ public class Device implements BaseLink.PackageReceiver {
|
||||
preferences.edit().putBoolean(deviceId,true).apply();
|
||||
|
||||
//Store device information needed to create a Device object in a future
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
try {
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putString("deviceName", getName());
|
||||
editor.putString("deviceType", deviceType.toString());
|
||||
String encodedPublicKey = Base64.encodeToString(publicKey.getEncoded(), 0);
|
||||
editor.putString("publicKey", encodedPublicKey);
|
||||
String encodedCertificate = Base64.encodeToString(certificate.getEncoded(), 0);
|
||||
editor.putString("certificate", encodedCertificate);
|
||||
editor.apply();
|
||||
} catch (Exception e){
|
||||
Log.e("KDE/Device", "Exception pairing done");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
reloadPluginsFromSettings();
|
||||
|
@@ -26,7 +26,6 @@ import android.preference.PreferenceManager;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import org.apache.mina.filter.ssl.SslFilter;
|
||||
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
@@ -45,7 +44,6 @@ 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;
|
||||
@@ -53,9 +51,6 @@ import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
|
||||
|
||||
public class SslHelper {
|
||||
|
||||
public enum SslMode{
|
||||
@@ -214,70 +209,4 @@ public class SslHelper {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO : Remove this method, and use the above one, since it trusts all certificates
|
||||
public static SslFilter getTrustAllCertsFilter(Context context, SslMode sslMode){
|
||||
try{
|
||||
|
||||
// Get device private key
|
||||
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
|
||||
|
||||
// Get my certificate
|
||||
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
byte[] myCertificateBytes = Base64.decode(globalSettings.getString("certificate", ""), 0);
|
||||
X509CertificateHolder myCertificateHolder = new X509CertificateHolder(myCertificateBytes);
|
||||
X509Certificate myCertificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(myCertificateHolder);
|
||||
|
||||
|
||||
// Setup keystore
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null, null);
|
||||
keyStore.setKeyEntry("key", privateKey, "".toCharArray(), new java.security.cert.Certificate[]{myCertificate});;
|
||||
|
||||
// Setup key manager factory
|
||||
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
keyManagerFactory.init(keyStore, "".toCharArray());
|
||||
|
||||
|
||||
// Setup default trust manager
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
trustManagerFactory.init(keyStore);
|
||||
|
||||
// Setup custom trust manager if device not trusted
|
||||
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] certs, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] certs, String authType) {
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// TODO : if device trusted, set need client auth
|
||||
|
||||
SSLContext tlsContext = SSLContext.getInstance("TLS");
|
||||
tlsContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom());
|
||||
SslFilter filter = new SslFilter(tlsContext,true);
|
||||
|
||||
if (sslMode == SslMode.Client){
|
||||
filter.setUseClientMode(true);
|
||||
}else{
|
||||
filter.setUseClientMode(false);
|
||||
filter.setWantClientAuth(true);
|
||||
}
|
||||
|
||||
return filter;
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
Log.e("SslHelper", "Error creating ssl filter");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -25,11 +25,9 @@ import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.kde.kdeconnect.BackgroundService;
|
||||
@@ -145,7 +143,6 @@ public class PairActivity extends ActionBarActivity {
|
||||
public void onClick(View view) {
|
||||
pairButton.setVisibility(View.GONE);
|
||||
((TextView) findViewById(R.id.pair_message)).setText("");
|
||||
findViewById(R.id.secret_keys).setVisibility(View.GONE);
|
||||
findViewById(R.id.pair_progress).setVisibility(View.VISIBLE);
|
||||
BackgroundService.RunCommand(PairActivity.this, new BackgroundService.InstanceCallback() {
|
||||
@Override
|
||||
|
@@ -26,13 +26,24 @@ import android.test.AndroidTestCase;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle;
|
||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
|
||||
public class DeviceTest extends AndroidTestCase {
|
||||
|
||||
@@ -140,6 +151,8 @@ public class DeviceTest extends AndroidTestCase {
|
||||
assertEquals(device.getDeviceId(), "unpairedTestDevice");
|
||||
assertEquals(device.getName(), "Unpaired Test Device");
|
||||
assertEquals(device.getDeviceType(), Device.DeviceType.Phone);
|
||||
assertNotNull(device.publicKey);
|
||||
assertNull(device.certificate);
|
||||
|
||||
Method method;
|
||||
try {
|
||||
@@ -166,6 +179,90 @@ public class DeviceTest extends AndroidTestCase {
|
||||
|
||||
}
|
||||
|
||||
public void testPairingDoneWithCertificate() throws Exception{
|
||||
KeyPair keyPair = null;
|
||||
try {
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(2048);
|
||||
keyPair = keyGen.genKeyPair();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("KDE/initializeRsaKeys", "Exception");
|
||||
}
|
||||
|
||||
X509Certificate certificate = null;
|
||||
try {
|
||||
|
||||
BouncyCastleProvider BC = new BouncyCastleProvider();
|
||||
|
||||
X500NameBuilder nameBuilder = new X500NameBuilder(BCStyle.INSTANCE);
|
||||
nameBuilder.addRDN(BCStyle.CN, "testDevice");
|
||||
nameBuilder.addRDN(BCStyle.OU, "KDE Connect");
|
||||
nameBuilder.addRDN(BCStyle.O, "KDE");
|
||||
Date notBefore = new Date(System.currentTimeMillis());
|
||||
Date notAfter = new Date(System.currentTimeMillis() + System.currentTimeMillis());
|
||||
X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
|
||||
nameBuilder.build(),
|
||||
BigInteger.ONE,
|
||||
notBefore,
|
||||
notAfter,
|
||||
nameBuilder.build(),
|
||||
keyPair.getPublic()
|
||||
);
|
||||
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(keyPair.getPrivate());
|
||||
certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateBuilder.build(contentSigner));
|
||||
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("KDE/initialiseCertificate", "Exception");
|
||||
}
|
||||
|
||||
NetworkPackage fakeNetworkPackage = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_IDENTITY);
|
||||
fakeNetworkPackage.set("deviceId", "unpairedTestDevice");
|
||||
fakeNetworkPackage.set("deviceName", "Unpaired Test Device");
|
||||
fakeNetworkPackage.set("protocolVersion", NetworkPackage.ProtocolVersion);
|
||||
fakeNetworkPackage.set("deviceType", Device.DeviceType.Phone.toString());
|
||||
fakeNetworkPackage.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
||||
|
||||
LanLinkProvider linkProvider = Mockito.mock(LanLinkProvider.class);
|
||||
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
|
||||
LanLink link = Mockito.mock(LanLink.class);
|
||||
Mockito.when(link.getLinkProvider()).thenReturn(linkProvider);
|
||||
Device device = new Device(getContext(), fakeNetworkPackage, link);
|
||||
device.publicKey = keyPair.getPublic();
|
||||
|
||||
assertNotNull(device);
|
||||
assertEquals(device.getDeviceId(), "unpairedTestDevice");
|
||||
assertEquals(device.getName(), "Unpaired Test Device");
|
||||
assertEquals(device.getDeviceType(), Device.DeviceType.Phone);
|
||||
assertNotNull(device.publicKey);
|
||||
assertNotNull(device.certificate);
|
||||
|
||||
Method method;
|
||||
try {
|
||||
method = Device.class.getDeclaredMethod("pairingDone");
|
||||
method.setAccessible(true);
|
||||
method.invoke(device);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assertEquals(device.isPaired(), true);
|
||||
|
||||
SharedPreferences preferences = getContext().getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
assertEquals(preferences.getBoolean(device.getDeviceId(), false), true);
|
||||
|
||||
SharedPreferences settings = getContext().getSharedPreferences(device.getDeviceId(),Context.MODE_PRIVATE);
|
||||
assertEquals(settings.getString("deviceName", "Unknown device"), "Unpaired Test Device");
|
||||
assertEquals(settings.getString("deviceType", "tablet"), "phone");
|
||||
assertEquals(settings.getString("publicKey", ""), Base64.encodeToString(keyPair.getPublic().getEncoded(), 0));
|
||||
assertEquals(settings.getString("certificate", ""), Base64.encodeToString(certificate.getEncoded(), 0));;
|
||||
|
||||
// Cleanup for unpaired test device
|
||||
preferences.edit().remove(device.getDeviceId()).apply();
|
||||
settings.edit().clear().apply();
|
||||
}
|
||||
|
||||
public void testUnpair(){
|
||||
|
||||
Device device = new Device(getContext(), "testDevice");
|
||||
|
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Vineet Garg <grg.vineet@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.kde.kdeconnect;
|
||||
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.util.Log;
|
||||
|
||||
import org.apache.mina.core.service.IoHandler;
|
||||
import org.apache.mina.core.service.IoHandlerAdapter;
|
||||
import org.apache.mina.core.session.IoSession;
|
||||
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
|
||||
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class LanLinkProviderTest extends AndroidTestCase {
|
||||
|
||||
private NioSocketAcceptor tcpAcceptor = null;
|
||||
private NioDatagramAcceptor udpAcceptor = null;
|
||||
private LanLinkProvider linkProvider;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());
|
||||
|
||||
linkProvider = new LanLinkProvider(getContext());
|
||||
|
||||
try {
|
||||
Field field = LanLinkProvider.class.getDeclaredField("tcpAcceptor");
|
||||
field.setAccessible(true);
|
||||
tcpAcceptor = (NioSocketAcceptor)field.get(linkProvider);
|
||||
assertNotNull(tcpAcceptor);
|
||||
}catch (Exception e){
|
||||
fail("Error getting tcpAcceptor from LanLinkProvider");
|
||||
}
|
||||
|
||||
try{
|
||||
Field field = LanLinkProvider.class.getDeclaredField("udpAcceptor");
|
||||
field.setAccessible(true);
|
||||
udpAcceptor = (NioDatagramAcceptor)field.get(linkProvider);
|
||||
assertNotNull(udpAcceptor);
|
||||
}catch (Exception e){
|
||||
fail("Error getting udp acceptor from LanLinkProvider");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
|
||||
tcpAcceptor.dispose();
|
||||
udpAcceptor.dispose();
|
||||
}
|
||||
|
||||
public void testTcpAcceptor(){
|
||||
|
||||
assertNotNull(tcpAcceptor.getHandler());
|
||||
assertEquals(tcpAcceptor.getSessionConfig().isKeepAlive(), true);
|
||||
assertEquals(tcpAcceptor.getSessionConfig().isReuseAddress(), true);
|
||||
assertNotNull(tcpAcceptor.getFilterChain().get("codec"));
|
||||
|
||||
}
|
||||
|
||||
public void testUdpAcceptor(){
|
||||
|
||||
assertNull(udpAcceptor.getHandler());
|
||||
assertEquals(udpAcceptor.getSessionConfig().isReuseAddress(), true);
|
||||
assertNotNull(udpAcceptor.getFilterChain().get("codec"));
|
||||
}
|
||||
|
||||
public void testOnStart() throws Exception{
|
||||
|
||||
IoSession session = Mockito.mock(IoSession.class);
|
||||
Mockito.when(session.getId()).thenReturn(12345l);
|
||||
Mockito.when(session.getRemoteAddress()).thenReturn(new InetSocketAddress(5000));
|
||||
|
||||
linkProvider.onStart();
|
||||
|
||||
assertNotNull(udpAcceptor.getHandler());
|
||||
assertEquals(udpAcceptor.getLocalAddress().getPort(), 1714);
|
||||
}
|
||||
|
||||
public void testUdpPackageReceived() throws Exception {
|
||||
|
||||
final int port = 5000;
|
||||
|
||||
NetworkPackage networkPackage = Mockito.mock(NetworkPackage.class);
|
||||
Mockito.when(networkPackage.getType()).thenReturn("kdeconnect.identity");
|
||||
Mockito.when(networkPackage.getString("deviceId")).thenReturn("testDevice");
|
||||
Mockito.when(networkPackage.getString("deviceName")).thenReturn("Test Device");
|
||||
Mockito.when(networkPackage.getInt("protocolVersion")).thenReturn(NetworkPackage.ProtocolVersion);
|
||||
Mockito.when(networkPackage.getString("deviceType")).thenReturn("phone");
|
||||
Mockito.when(networkPackage.getInt("tcpPort")).thenReturn(port);
|
||||
|
||||
final String serialized = "{\"type\":\"kdeconnect.identity\",\"id\":12345,\"body\":{\"deviceName\":\"Test Device\",\"deviceType\":\"phone\",\"deviceId\":\"testDevice\",\"protocolVersion\":5,\"tcpPort\": "+ port +"}}";
|
||||
Mockito.when(networkPackage.serialize()).thenReturn(serialized);
|
||||
|
||||
// Mocking udp session
|
||||
IoSession session = Mockito.mock(IoSession.class);
|
||||
Mockito.when(session.getId()).thenReturn(12345l);
|
||||
Mockito.when(session.getRemoteAddress()).thenReturn(new InetSocketAddress(port));
|
||||
|
||||
|
||||
// Making a server socket, so that original LanLinkProvider can connect to it when it receives our fake package
|
||||
final ServerSocket serverSocket = new ServerSocket();
|
||||
serverSocket.bind(new InetSocketAddress(port));
|
||||
|
||||
final Thread thread = new Thread (new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Socket socket = serverSocket.accept();
|
||||
InputStream inputStream = socket.getInputStream();
|
||||
while (true) {
|
||||
if (inputStream.available() != 0) {
|
||||
// Data received from socket should be an identity package
|
||||
byte[] inputData = new byte[inputStream.available()];
|
||||
inputStream.read(inputData);
|
||||
|
||||
NetworkPackage receivedPackage = NetworkPackage.unserialize(new String(inputData));
|
||||
NetworkPackage identityPackage = NetworkPackage.createIdentityPackage(getContext());
|
||||
|
||||
// If any assertion fails, its output will be in logcat, not on test case thread anymore
|
||||
assertEquals(receivedPackage.getType(), identityPackage.getType());
|
||||
assertEquals(receivedPackage.getString("deviceName"), identityPackage.getString("deviceName"));
|
||||
assertEquals(receivedPackage.getString("deviceId"), identityPackage.getString("deviceId"));
|
||||
assertEquals(receivedPackage.getInt("protocolVersion"), identityPackage.getInt("protocolVersion"));
|
||||
|
||||
serverSocket.close();
|
||||
// Socket not closed to ensure visibleComputers contains entry for testDevice
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}catch (Exception e){
|
||||
assertEquals("Exception in thread",1,5);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
thread.start();
|
||||
linkProvider.onStart();
|
||||
udpAcceptor.getHandler().messageReceived(session, networkPackage.serialize());
|
||||
}catch (Exception e){
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Wait 1 secs for our server, and then end test
|
||||
thread.join(1 * 1000);
|
||||
|
||||
// visibleComputers should contain an entry for testDevice
|
||||
HashMap<String, LanLink> visibleComputers;
|
||||
try {
|
||||
Field field = LanLinkProvider.class.getDeclaredField("visibleComputers");
|
||||
field.setAccessible(true);
|
||||
visibleComputers = (HashMap<String, LanLink>)field.get(linkProvider);
|
||||
}catch (Exception e){
|
||||
throw e;
|
||||
}
|
||||
assertNotNull(visibleComputers.get("testDevice"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testTcpIdentityPackageReceived() throws Exception{
|
||||
|
||||
IoSession session = Mockito.mock(IoSession.class);
|
||||
Mockito.when(session.getId()).thenReturn(12345l);
|
||||
|
||||
NetworkPackage networkPackage = Mockito.mock(NetworkPackage.class);
|
||||
Mockito.when(networkPackage.getType()).thenReturn("kdeconnect.identity");
|
||||
Mockito.when(networkPackage.getString("deviceId")).thenReturn("testDevice");
|
||||
Mockito.when(networkPackage.getString("deviceName")).thenReturn("Test Device");
|
||||
Mockito.when(networkPackage.getInt("protocolVersion")).thenReturn(NetworkPackage.ProtocolVersion);
|
||||
Mockito.when(networkPackage.getString("deviceType")).thenReturn("phone");
|
||||
|
||||
String serialized = "{\"type\":\"kdeconnect.identity\",\"id\":12345,\"body\":{\"deviceName\":\"Test Device\",\"deviceType\":\"phone\",\"deviceId\":\"testDevice\",\"protocolVersion\":5}}";
|
||||
Mockito.when(networkPackage.serialize()).thenReturn(serialized);
|
||||
|
||||
try {
|
||||
tcpAcceptor.getHandler().messageReceived(session, networkPackage.serialize());
|
||||
}catch (Exception e){
|
||||
throw e;
|
||||
}
|
||||
|
||||
LongSparseArray<LanLink> nioSessions;
|
||||
try {
|
||||
Field field = LanLinkProvider.class.getDeclaredField("nioSessions");
|
||||
field.setAccessible(true);
|
||||
nioSessions = (LongSparseArray<LanLink>)field.get(linkProvider);
|
||||
}catch (Exception e){
|
||||
throw e;
|
||||
}
|
||||
assertNotNull(nioSessions.get(12345l));
|
||||
|
||||
|
||||
HashMap<String, LanLink> visibleComputers;
|
||||
try {
|
||||
Field field = LanLinkProvider.class.getDeclaredField("visibleComputers");
|
||||
field.setAccessible(true);
|
||||
visibleComputers = (HashMap<String, LanLink>)field.get(linkProvider);
|
||||
}catch (Exception e){
|
||||
throw e;
|
||||
}
|
||||
assertNotNull(visibleComputers.get("testDevice"));
|
||||
|
||||
|
||||
// Testing session closed
|
||||
try {
|
||||
tcpAcceptor.getHandler().sessionClosed(session);
|
||||
}catch (Exception e){
|
||||
throw e;
|
||||
}
|
||||
assertNull(nioSessions.get(12345l));
|
||||
assertNull(visibleComputers.get("testDevice"));
|
||||
}
|
||||
}
|
@@ -23,8 +23,6 @@ package org.kde.kdeconnect;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.util.Log;
|
||||
|
||||
import org.apache.mina.core.future.WriteFuture;
|
||||
import org.apache.mina.core.session.IoSession;
|
||||
import org.json.JSONObject;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
|
||||
@@ -34,17 +32,21 @@ import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
|
||||
public class LanLinkTest extends AndroidTestCase {
|
||||
|
||||
LanLink lanLink;
|
||||
IoSession session;
|
||||
Channel channel;
|
||||
Device.SendPackageStatusCallback callback;
|
||||
|
||||
WriteFuture writeFutureSuccess, writeFutureFailure;
|
||||
ChannelFuture channelFutureSuccess, channelFutureFailure;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
@@ -55,9 +57,10 @@ public class LanLinkTest extends AndroidTestCase {
|
||||
LanLinkProvider linkProvider = Mockito.mock(LanLinkProvider.class);
|
||||
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
|
||||
|
||||
session = Mockito.mock(IoSession.class);
|
||||
Mockito.when(session.getId()).thenReturn(12345l);
|
||||
Mockito.when(session.getRemoteAddress()).thenReturn(new InetSocketAddress(5000));
|
||||
channel = Mockito.mock(Channel.class);
|
||||
// Mockito.when(channel.hashCode()).thenReturn(12345);
|
||||
Mockito.when(channel.remoteAddress()).thenReturn(new InetSocketAddress(5000));
|
||||
// Mockito.doReturn(new InetSocketAddress(5000)).when(channel).remoteAddress();
|
||||
|
||||
callback = Mockito.mock(Device.SendPackageStatusCallback.class);
|
||||
Mockito.doNothing().when(callback).sendSuccess();
|
||||
@@ -69,18 +72,20 @@ public class LanLinkTest extends AndroidTestCase {
|
||||
}
|
||||
}).when(callback).sendFailure(Mockito.any(Throwable.class));
|
||||
|
||||
writeFutureSuccess = Mockito.mock(WriteFuture.class);
|
||||
Mockito.when(writeFutureSuccess.isWritten()).thenReturn(true);
|
||||
Mockito.when(writeFutureSuccess.getSession()).thenReturn(session);
|
||||
Mockito.when(writeFutureSuccess.isDone()).thenReturn(true);
|
||||
channelFutureSuccess = Mockito.mock(ChannelFuture.class);
|
||||
Mockito.when(channelFutureSuccess.isDone()).thenReturn(true);
|
||||
Mockito.when(channelFutureSuccess.isSuccess()).thenReturn(true);
|
||||
Mockito.when(channelFutureSuccess.channel()).thenReturn(channel);
|
||||
Mockito.when(channelFutureSuccess.sync()).thenReturn(channelFutureSuccess);
|
||||
|
||||
writeFutureFailure = Mockito.mock(WriteFuture.class);
|
||||
Mockito.when(writeFutureFailure.isWritten()).thenReturn(false);
|
||||
Mockito.when(writeFutureFailure.getSession()).thenReturn(session);
|
||||
Mockito.when(writeFutureFailure.isDone()).thenReturn(true);
|
||||
Mockito.when(writeFutureFailure.getException()).thenReturn(new RuntimeException());
|
||||
channelFutureFailure = Mockito.mock(ChannelFuture.class);
|
||||
Mockito.when(channelFutureFailure.isDone()).thenReturn(true);
|
||||
Mockito.when(channelFutureFailure.isSuccess()).thenReturn(false);
|
||||
Mockito.when(channelFutureFailure.cause()).thenReturn(new IOException("Cannot send package"));
|
||||
Mockito.when(channelFutureFailure.channel()).thenReturn(channel);
|
||||
Mockito.when(channelFutureFailure.sync()).thenReturn(channelFutureFailure);
|
||||
|
||||
lanLink = new LanLink(session, "testDevice", linkProvider);
|
||||
lanLink = new LanLink(getContext(), channel, "testDevice", linkProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,8 +101,15 @@ public class LanLinkTest extends AndroidTestCase {
|
||||
Mockito.when(testPackage.getString("testName")).thenReturn("testSendPackageSuccess");
|
||||
Mockito.when(testPackage.serialize()).thenReturn("{\"id\":123,\"type\":\"kdeconnect.test\",\"body\":{\"isTesting\":true,\"testName\":\"testSendPackageSuccess\"}}");
|
||||
|
||||
Mockito.when(session.write(testPackage.serialize())).thenReturn(writeFutureSuccess);
|
||||
lanLink.sendPackage(testPackage, callback);
|
||||
try {
|
||||
Mockito.when(channel.writeAndFlush(testPackage.serialize())).thenReturn(channelFutureSuccess);
|
||||
lanLink.sendPackage(testPackage, callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assertEquals(channelFutureSuccess.isDone(), true);
|
||||
assertEquals(channelFutureSuccess.isSuccess(), true);
|
||||
}
|
||||
|
||||
public void testSendPackageFail(){
|
||||
@@ -108,17 +120,16 @@ public class LanLinkTest extends AndroidTestCase {
|
||||
Mockito.when(testPackage.getString("testName")).thenReturn("testSendPackageFail");
|
||||
Mockito.when(testPackage.serialize()).thenReturn("{\"id\":123,\"type\":\"kdeconnect.test\",\"body\":{\"isTesting\":true,\"testName\":\"testSendPackageFail\"}}");
|
||||
|
||||
Mockito.when(session.write(testPackage.serialize())).thenReturn(writeFutureFailure);
|
||||
try {
|
||||
Mockito.when(channel.writeAndFlush(testPackage.serialize())).thenReturn(channelFutureFailure);
|
||||
lanLink.sendPackage(testPackage, callback);
|
||||
}catch (RuntimeException r){
|
||||
// Do nothing, test is fine, callback should throw this exception
|
||||
}catch (Exception e){
|
||||
// This should not happen
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
assertEquals(channelFutureFailure.isDone(), true);
|
||||
assertEquals(channelFutureFailure.isSuccess(), false);
|
||||
assertEquals(channelFutureFailure.cause() instanceof IOException, true );
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +156,7 @@ public class LanLinkTest extends AndroidTestCase {
|
||||
try {
|
||||
socket = new Socket();
|
||||
int tcpPort = np.getPayloadTransferInfo().getInt("port");
|
||||
InetSocketAddress address = (InetSocketAddress)session.getRemoteAddress();
|
||||
InetSocketAddress address = (InetSocketAddress)channel.remoteAddress();
|
||||
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
|
||||
np.setPayload(socket.getInputStream(), np.getPayloadSize());
|
||||
} catch (Exception e) {
|
||||
@@ -246,9 +257,9 @@ public class LanLinkTest extends AndroidTestCase {
|
||||
downloader.setNetworkPackage(np);
|
||||
downloader.start();
|
||||
|
||||
return writeFutureSuccess;
|
||||
return channelFutureSuccess;
|
||||
}
|
||||
}).when(session).write(Mockito.anyString());
|
||||
}).when(channel).writeAndFlush(Mockito.anyString());
|
||||
|
||||
lanLink.sendPackage(sharePackage, callback);
|
||||
|
||||
|
@@ -23,6 +23,8 @@ package org.kde.kdeconnect;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.util.Log;
|
||||
|
||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
@@ -106,10 +108,10 @@ public class NetworkPackageTest extends AndroidTestCase{
|
||||
// Encrypt and decrypt np
|
||||
assertEquals(original.getType(), "com.test");
|
||||
try {
|
||||
NetworkPackage encrypted = original.encrypt(publicKey);
|
||||
NetworkPackage encrypted = RsaHelper.encrypt(original,publicKey);
|
||||
assertEquals(encrypted.getType(), NetworkPackage.PACKAGE_TYPE_ENCRYPTED);
|
||||
|
||||
decrypted = encrypted.decrypt(privateKey);
|
||||
decrypted = RsaHelper.decrypt(encrypted, privateKey);
|
||||
assertEquals(decrypted.getType(), "com.test");
|
||||
|
||||
}catch (Exception e){
|
||||
@@ -124,8 +126,8 @@ public class NetworkPackageTest extends AndroidTestCase{
|
||||
String json = "{\"body\":{\"nowPlaying\":\"A really long song name - A really long artist name\",\"player\":\"A really long player name\",\"the_meaning_of_life_the_universe_and_everything\":\"42\"},\"id\":\"A really long package id\",\"payloadSize\":0,\"payloadTransferInfo\":{},\"type\":\"kdeconnect.a_really_really_long_package_type\"}\n";
|
||||
NetworkPackage longJsonNp = NetworkPackage.unserialize(json);
|
||||
try {
|
||||
NetworkPackage encrypted = longJsonNp.encrypt(publicKey);
|
||||
decrypted = encrypted.decrypt(privateKey);
|
||||
NetworkPackage encrypted = RsaHelper.encrypt(longJsonNp, publicKey);
|
||||
decrypted = RsaHelper.decrypt(encrypted, privateKey);
|
||||
|
||||
String decryptedJson = decrypted.serialize();
|
||||
assertEquals(json, decryptedJson);
|
||||
|
Reference in New Issue
Block a user