tls-psk: improve error handling on connection error

This commit is contained in:
Vincent Breitmoser 2017-05-30 22:54:09 +02:00
parent a441df2bd7
commit 7df2619232
3 changed files with 80 additions and 33 deletions

View File

@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.network;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
@ -38,6 +39,7 @@ import android.net.Uri;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.Base64;
@ -59,6 +61,8 @@ public class KeyTransferInteractor {
private static final int CONNECTION_SEND_OK = 3;
private static final int CONNECTION_RECEIVE_OK = 4;
private static final int CONNECTION_LOST = 5;
private static final int CONNECTION_ERROR_CONNECT = 6;
private static final int CONNECTION_ERROR_LISTEN = 7;
private TransferThread transferThread;
@ -119,41 +123,56 @@ public class KeyTransferInteractor {
Socket socket = null;
try {
if (isServer) {
socket = getSocketListenOrConnect(sslContext);
if (socket == null) {
return;
}
try {
handleOpenConnection(socket);
Log.d(Constants.TAG, "connection closed ok!");
} catch (IOException e) {
Log.e(Constants.TAG, "error!", e);
}
} finally {
closeQuietly(socket);
closeQuietly(serverSocket);
}
}
@Nullable
private Socket getSocketListenOrConnect(SSLContext sslContext) {
Socket socket;
if (isServer) {
try {
int port = 1336;
serverSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(port);
String presharedKeyEncoded = Base64.encodeToString(presharedKey, Base64.URL_SAFE | Base64.NO_PADDING);
String qrCodeData = "pgp+transfer://" + presharedKeyEncoded + "@" + getIPAddress(true) + ":" + port;
String presharedKeyEncoded =
Base64.encodeToString(presharedKey, Base64.URL_SAFE | Base64.NO_PADDING);
String qrCodeData =
"pgp+transfer://" + presharedKeyEncoded + "@" + getIPAddress(true) + ":" + port;
invokeListener(CONNECTION_LISTENING, qrCodeData);
socket = serverSocket.accept();
invokeListener(CONNECTION_ESTABLISHED, socket.getInetAddress().toString());
} else {
socket = sslContext.getSocketFactory().createSocket(InetAddress.getByName(clientHost), clientPort);
} catch (IOException e) {
Log.e(Constants.TAG, "error while listening!", e);
invokeListener(CONNECTION_ERROR_LISTEN, null);
return null;
}
} else {
try {
socket = sslContext.getSocketFactory()
.createSocket(InetAddress.getByName(clientHost), clientPort);
invokeListener(CONNECTION_ESTABLISHED, socket.getInetAddress().toString());
}
handleOpenConnection(socket);
Log.d(Constants.TAG, "connection closed ok!");
} catch (IOException e) {
Log.e(Constants.TAG, "error!", e);
} finally {
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
// ignore
}
try {
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
// ignore
Log.e(Constants.TAG, "error while connecting!", e);
invokeListener(CONNECTION_ERROR_CONNECT, null);
return null;
}
}
return socket;
}
private static SSLContext createTlsPskSslContext(byte[] presharedKey) {
@ -268,6 +287,13 @@ public class KeyTransferInteractor {
break;
case CONNECTION_LOST:
callback.onConnectionLost();
break;
case CONNECTION_ERROR_CONNECT:
callback.onConnectionErrorConnect();
break;
case CONNECTION_ERROR_LISTEN:
callback.onConnectionErrorListen();
break;
}
}
};
@ -283,16 +309,8 @@ public class KeyTransferInteractor {
@Override
public void interrupt() {
callback = null;
super.interrupt();
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// ignore
}
}
closeQuietly(serverSocket);
}
}
@ -321,6 +339,9 @@ public class KeyTransferInteractor {
void onDataReceivedOk(String receivedData);
void onDataSentOk(String arg);
void onConnectionErrorConnect();
void onConnectionErrorListen();
}
/**
@ -378,4 +399,14 @@ public class KeyTransferInteractor {
return new SecretKeySpec(presharedKey, "AES");
}
}
private static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException e) {
// ignore
}
}
}

View File

@ -249,6 +249,16 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
}, 750);
}
@Override
public void onConnectionErrorConnect() {
view.showErrorConnectionFailed();
}
@Override
public void onConnectionErrorListen() {
view.showErrorListenFailed();
}
private void connectionStartConnect(String qrCodeContent) {
connectionClear();
@ -336,6 +346,7 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
void showErrorBadKey();
void showErrorConnectionFailed();
void showErrorListenFailed();
void showResultNotification(ImportKeyResult result);
void setSecretKeyAdapter(Adapter adapter);

View File

@ -229,6 +229,11 @@ public class TransferFragment extends Fragment implements TransferMvpView {
Notify.create(getActivity(), "Connection failed!", Style.ERROR).show();
}
@Override
public void showErrorListenFailed() {
Notify.create(getActivity(), "Error setting up server!", Style.ERROR).show();
}
@Override
public void showResultNotification(ImportKeyResult result) {
result.createNotify(getActivity()).show();