From ef20cd297b5609e31b17f02a63624b8d080427e7 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Thu, 10 Jan 2019 13:56:09 +0100 Subject: [PATCH] Make the lib more reusable, prepare for desktop UI --- .../ssl/QuasselHostnameVerifier.kt | 1 + .../ui/chat/info/core/CoreInfoFragment.kt | 2 +- desktop/build.gradle.kts | 39 ++++++++++++ .../java/de/kuschku/desktop/CliArguments.kt | 59 +++++++++++++++++++ .../src/main/java/de/kuschku/desktop/Main.kt | 27 +++++++++ .../libquassel/connection/CoreConnection.kt | 14 +++-- .../kuschku/libquassel/protocol/ClientData.kt | 15 ++++- .../quassel/syncables/BacklogManager.kt | 14 ++--- .../quassel/syncables/BufferSyncer.kt | 2 +- .../quassel/syncables/RpcHandler.kt | 6 +- .../libquassel/session/ProtocolHandler.kt | 8 +-- .../de/kuschku/libquassel/session/Session.kt | 33 ++++++----- .../libquassel/session/SessionManager.kt | 12 ++-- .../ssl/BrowserCompatibleHostnameVerifier.kt | 4 +- .../ssl/TrustAllHostnameVerifier.kt | 28 +++++++++ .../kuschku/libquassel/ssl/TrustManagers.kt | 43 ++++++++++++++ .../de/kuschku/libquassel}/ssl/X509Helper.kt | 5 +- settings.gradle | 4 +- 18 files changed, 268 insertions(+), 48 deletions(-) create mode 100644 desktop/build.gradle.kts create mode 100644 desktop/src/main/java/de/kuschku/desktop/CliArguments.kt create mode 100644 desktop/src/main/java/de/kuschku/desktop/Main.kt rename {app/src/main/java/de/kuschku/quasseldroid => lib/src/main/java/de/kuschku/libquassel}/ssl/BrowserCompatibleHostnameVerifier.kt (96%) create mode 100644 lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt create mode 100644 lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt rename {app/src/main/java/de/kuschku/quasseldroid => lib/src/main/java/de/kuschku/libquassel}/ssl/X509Helper.kt (96%) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt b/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt index 4f6ec01b9..9b94a3ca5 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ssl/QuasselHostnameVerifier.kt @@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.ssl import de.kuschku.libquassel.connection.HostnameVerifier import de.kuschku.libquassel.connection.QuasselSecurityException import de.kuschku.libquassel.connection.SocketAddress +import de.kuschku.libquassel.ssl.BrowserCompatibleHostnameVerifier import de.kuschku.quasseldroid.ssl.custom.QuasselHostnameManager import java.security.cert.X509Certificate import javax.net.ssl.SSLException diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt index 65330355e..86f7f5ff1 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt @@ -33,9 +33,9 @@ import androidx.recyclerview.widget.RecyclerView import butterknife.BindView import butterknife.ButterKnife import de.kuschku.libquassel.quassel.QuasselFeatures +import de.kuschku.libquassel.ssl.X509Helper import de.kuschku.libquassel.util.helpers.value import de.kuschku.quasseldroid.R -import de.kuschku.quasseldroid.ssl.X509Helper import de.kuschku.quasseldroid.util.helper.* import de.kuschku.quasseldroid.util.missingfeatures.MissingFeature import de.kuschku.quasseldroid.util.missingfeatures.MissingFeaturesDialog diff --git a/desktop/build.gradle.kts b/desktop/build.gradle.kts new file mode 100644 index 000000000..88efe8d89 --- /dev/null +++ b/desktop/build.gradle.kts @@ -0,0 +1,39 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * 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/>. + */ + +plugins { + application + kotlin("jvm") + kotlin("kapt") +} + +application { + mainClassName = "de.kuschku.cli.MainKt" +} + +dependencies { + implementation(kotlin("stdlib", "1.3.11")) + + implementation("io.reactivex.rxjava2", "rxjava", "2.1.9") + implementation("info.picocli", "picocli", "3.9.0") + + implementation(project(":lib")) + + testImplementation("junit", "junit", "4.12") +} diff --git a/desktop/src/main/java/de/kuschku/desktop/CliArguments.kt b/desktop/src/main/java/de/kuschku/desktop/CliArguments.kt new file mode 100644 index 000000000..c1b577e84 --- /dev/null +++ b/desktop/src/main/java/de/kuschku/desktop/CliArguments.kt @@ -0,0 +1,59 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * 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 de.kuschku.desktop + +import picocli.CommandLine + +class CliArguments { + @CommandLine.Option(names = ["--user"]) + var user: String = "" + @CommandLine.Option(names = ["--pass"]) + var pass: String = "" + @CommandLine.Option(names = ["--host"]) + var host: String = "" + @CommandLine.Option(names = ["--port"]) + var port: Int = 4242 + + override fun toString(): String { + return "CliArguments(user='$user', pass='$pass', host='$host', port='$port')" + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as CliArguments + + if (user != other.user) return false + if (pass != other.pass) return false + if (host != other.host) return false + if (port != other.port) return false + + return true + } + + override fun hashCode(): Int { + var result = user.hashCode() + result = 31 * result + pass.hashCode() + result = 31 * result + host.hashCode() + result = 31 * result + port.hashCode() + return result + } +} diff --git a/desktop/src/main/java/de/kuschku/desktop/Main.kt b/desktop/src/main/java/de/kuschku/desktop/Main.kt new file mode 100644 index 000000000..d521760f1 --- /dev/null +++ b/desktop/src/main/java/de/kuschku/desktop/Main.kt @@ -0,0 +1,27 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * 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 de.kuschku.desktop + +import picocli.CommandLine + +fun main(vararg args: String) { + val cliArguments = CliArguments() + CommandLine(cliArguments).parse(*args) +} diff --git a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt index 6b2f08735..fd50ab783 100644 --- a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt +++ b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt @@ -27,13 +27,17 @@ import de.kuschku.libquassel.protocol.primitive.serializer.IntSerializer import de.kuschku.libquassel.protocol.primitive.serializer.ProtocolInfoSerializer import de.kuschku.libquassel.protocol.primitive.serializer.VariantListSerializer import de.kuschku.libquassel.quassel.ProtocolFeature +import de.kuschku.libquassel.quassel.QuasselFeatures import de.kuschku.libquassel.session.ProtocolHandler +import de.kuschku.libquassel.ssl.BrowserCompatibleHostnameVerifier +import de.kuschku.libquassel.ssl.TrustManagers import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.compatibility.CompatibilityUtils import de.kuschku.libquassel.util.compatibility.HandlerService import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN +import de.kuschku.libquassel.util.compatibility.reference.JavaHandlerService import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.helpers.hexDump import de.kuschku.libquassel.util.helpers.write @@ -49,12 +53,12 @@ import javax.net.ssl.SSLSession import javax.net.ssl.X509TrustManager class CoreConnection( - private val clientData: ClientData, - private val features: Features, - private val trustManager: X509TrustManager, - private val hostnameVerifier: HostnameVerifier, private val address: SocketAddress, - private val handlerService: HandlerService + private val clientData: ClientData = ClientData.DEFAULT, + private val features: Features = Features(clientData.clientFeatures, QuasselFeatures.empty()), + private val handlerService: HandlerService = JavaHandlerService(), + private val trustManager: X509TrustManager = TrustManagers.default(), + private val hostnameVerifier: HostnameVerifier = BrowserCompatibleHostnameVerifier() ) : Thread(), Closeable { companion object { private const val TAG = "CoreConnection" diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt index 1a39495f9..5b48da237 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt @@ -28,4 +28,17 @@ data class ClientData( val clientFeatures: QuasselFeatures, val protocolFeatures: Protocol_Features, val supportedProtocols: List<Protocol> -) +) { + companion object { + val DEFAULT = ClientData( + identifier = "libquassel-java", + buildDate = Instant.EPOCH, + clientFeatures = QuasselFeatures.all(), + protocolFeatures = Protocol_Features.of( + Protocol_Feature.Compression, + Protocol_Feature.TLS + ), + supportedProtocols = listOf(Protocol.Datastream) + ) + } +} diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt index 0f50ef1e8..369d28711 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt @@ -28,7 +28,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG class BacklogManager( var session: ISession, - private val backlogStorage: BacklogStorage + private val backlogStorage: BacklogStorage? = null ) : SyncableObject(session.proxy, "BacklogManager"), IBacklogManager { private val loading = mutableMapOf<BufferId, (List<Message>) -> Boolean>() private val loadingFiltered = mutableMapOf<BufferId, (List<Message>) -> Boolean>() @@ -42,7 +42,7 @@ class BacklogManager( initialized = true } - fun updateIgnoreRules() = backlogStorage.updateIgnoreRules(session) + fun updateIgnoreRules() = backlogStorage?.updateIgnoreRules(session) fun requestBacklog(bufferId: BufferId, first: MsgId = -1, last: MsgId = -1, limit: Int = -1, additional: Int = 0, callback: (List<Message>) -> Boolean) { @@ -79,7 +79,7 @@ class BacklogManager( val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value) if (loading.remove(bufferId)?.invoke(list) != false) { log(DEBUG, "BacklogManager", "storeMessages(${list.size})") - backlogStorage.storeMessages(session, list) + backlogStorage?.storeMessages(session, list) } } @@ -88,7 +88,7 @@ class BacklogManager( val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value) if (loading.remove(-1)?.invoke(list) != false) { log(DEBUG, "BacklogManager", "storeMessages(${list.size})") - backlogStorage.storeMessages(session, list) + backlogStorage?.storeMessages(session, list) } } @@ -98,7 +98,7 @@ class BacklogManager( val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value) if (loadingFiltered.remove(bufferId)?.invoke(list) != false) { log(DEBUG, "BacklogManager", "storeMessages(${list.size})") - backlogStorage.storeMessages(session, list) + backlogStorage?.storeMessages(session, list) } } @@ -107,11 +107,11 @@ class BacklogManager( val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value) if (loadingFiltered.remove(-1)?.invoke(list) != false) { log(DEBUG, "BacklogManager", "storeMessages(${list.size})") - backlogStorage.storeMessages(session, list) + backlogStorage?.storeMessages(session, list) } } fun removeBuffer(buffer: BufferId) { - backlogStorage.clearMessages(buffer) + backlogStorage?.clearMessages(buffer) } } diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt index 9d431723a..1b63fd425 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt @@ -32,7 +32,7 @@ import io.reactivex.subjects.BehaviorSubject class BufferSyncer constructor( var session: ISession, - private val notificationManager: NotificationManager? + private val notificationManager: NotificationManager? = null ) : SyncableObject(session.proxy, "BufferSyncer"), IBufferSyncer { override fun deinit() { super.deinit() diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt index b106c9b09..8fb675f6c 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt @@ -32,8 +32,8 @@ import java.nio.ByteBuffer class RpcHandler( override val session: Session, - private val backlogStorage: BacklogStorage, - private val notificationManager: NotificationManager? + private val backlogStorage: BacklogStorage? = null, + private val notificationManager: NotificationManager? = null ) : IRpcHandler { override fun displayStatusMsg(net: String, msg: String) { } @@ -61,7 +61,7 @@ class RpcHandler( override fun displayMsg(message: Message) { session.bufferSyncer.bufferInfoUpdated(message.bufferInfo) - backlogStorage.storeMessages(session, message) + backlogStorage?.storeMessages(session, message) notificationManager?.processMessages(session, true, message) } diff --git a/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt index 6fd36247f..ac5799918 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt @@ -32,7 +32,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG import java.io.Closeable abstract class ProtocolHandler( - private val exceptionHandler: (Throwable) -> Unit + private val exceptionHandler: ((Throwable) -> Unit)? = null ) : SignalProxy, AuthHandler, Closeable { protected var closed = false protected abstract val objectStorage: ObjectStorage @@ -61,7 +61,7 @@ abstract class ProtocolHandler( } catch (e: ObjectNotFoundException) { log(DEBUG, "ProtocolHandler", "An error has occured while processing $f", e) } catch (e: Throwable) { - exceptionHandler.invoke(MessageHandlingException.SignalProxy(f, e)) + exceptionHandler?.invoke(MessageHandlingException.SignalProxy(f, e)) } return true } @@ -76,7 +76,7 @@ abstract class ProtocolHandler( } catch (e: ObjectNotFoundException) { log(DEBUG, "ProtocolHandler", "An error has occured while processing $f", e) } catch (e: Throwable) { - exceptionHandler.invoke(MessageHandlingException.Handshake(f, e)) + exceptionHandler?.invoke(MessageHandlingException.Handshake(f, e)) } return true } @@ -103,7 +103,7 @@ abstract class ProtocolHandler( try { this.handle(it) } catch (e: Throwable) { - exceptionHandler.invoke(e) + exceptionHandler?.invoke(e) } } } diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt index ea53f85f3..fbafa47d4 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt @@ -26,9 +26,12 @@ import de.kuschku.libquassel.protocol.message.SignalProxyMessage import de.kuschku.libquassel.quassel.ExtendedFeature import de.kuschku.libquassel.quassel.QuasselFeatures import de.kuschku.libquassel.quassel.syncables.* +import de.kuschku.libquassel.ssl.BrowserCompatibleHostnameVerifier +import de.kuschku.libquassel.ssl.TrustManagers import de.kuschku.libquassel.util.compatibility.HandlerService import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO +import de.kuschku.libquassel.util.compatibility.reference.JavaHandlerService import de.kuschku.libquassel.util.rxjava.ReusableUnicastSubject import io.reactivex.Observable import io.reactivex.subjects.BehaviorSubject @@ -37,19 +40,19 @@ import org.threeten.bp.Instant import javax.net.ssl.X509TrustManager class Session( - clientData: ClientData, - trustManager: X509TrustManager, - hostnameVerifier: HostnameVerifier, address: SocketAddress, - private val handlerService: HandlerService, - backlogStorage: BacklogStorage, - private val notificationManager: NotificationManager?, private var userData: Pair<String, String>, - heartBeatFactory: () -> HeartBeatRunner, - val disconnectFromCore: (() -> Unit)?, - private val initCallback: ((Session) -> Unit)?, - exceptionHandler: (Throwable) -> Unit, - private val hasErroredCallback: (Error) -> Unit + trustManager: X509TrustManager = TrustManagers.default(), + hostnameVerifier: HostnameVerifier = BrowserCompatibleHostnameVerifier(), + clientData: ClientData = ClientData.DEFAULT, + private val handlerService: HandlerService = JavaHandlerService(), + heartBeatFactory: () -> HeartBeatRunner = ::JavaHeartBeatRunner, + val disconnectFromCore: (() -> Unit)? = null, + private val initCallback: ((Session) -> Unit)? = null, + exceptionHandler: ((Throwable) -> Unit)? = null, + private val hasErroredCallback: ((Error) -> Unit)? = null, + private val notificationManager: NotificationManager? = null, + backlogStorage: BacklogStorage? = null ) : ProtocolHandler(exceptionHandler), ISession { override val objectStorage: ObjectStorage = ObjectStorage(this) override val proxy: SignalProxy = this @@ -59,12 +62,12 @@ class Session( get() = coreConnection.sslSession private val coreConnection = CoreConnection( + address, clientData, features, + handlerService, trustManager, - hostnameVerifier, - address, - handlerService + hostnameVerifier ) override val state = coreConnection.state @@ -112,7 +115,7 @@ class Session( } private fun handleError(error: Error) { - hasErroredCallback.invoke(error) + hasErroredCallback?.invoke(error) this.error.onNext(error) } diff --git a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt index 5ed8b2298..b240aa158 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt @@ -124,19 +124,19 @@ class SessionManager( hasErrored = false inProgressSession.onNext( Session( - clientData, + address, + userData, trustManager, hostnameVerifier, - address, + clientData, handlerService, - backlogStorage, - notificationManager, - userData, heartBeatFactory, disconnectFromCore, initCallback, exceptionHandler, - ::hasErroredCallback + ::hasErroredCallback, + notificationManager, + backlogStorage ) ) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ssl/BrowserCompatibleHostnameVerifier.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/BrowserCompatibleHostnameVerifier.kt similarity index 96% rename from app/src/main/java/de/kuschku/quasseldroid/ssl/BrowserCompatibleHostnameVerifier.kt rename to lib/src/main/java/de/kuschku/libquassel/ssl/BrowserCompatibleHostnameVerifier.kt index 72c6e8033..4b5ddaefd 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ssl/BrowserCompatibleHostnameVerifier.kt +++ b/lib/src/main/java/de/kuschku/libquassel/ssl/BrowserCompatibleHostnameVerifier.kt @@ -17,11 +17,11 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.quasseldroid.ssl +package de.kuschku.libquassel.ssl import de.kuschku.libquassel.connection.HostnameVerifier import de.kuschku.libquassel.connection.SocketAddress -import de.kuschku.quasseldroid.ssl.X509Helper.hostnames +import de.kuschku.libquassel.ssl.X509Helper.hostnames import java.net.IDN import java.security.cert.X509Certificate import javax.net.ssl.SSLException diff --git a/lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt new file mode 100644 index 000000000..88d1e4268 --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustAllHostnameVerifier.kt @@ -0,0 +1,28 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * 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 de.kuschku.libquassel.ssl + +import de.kuschku.libquassel.connection.HostnameVerifier +import de.kuschku.libquassel.connection.SocketAddress +import java.security.cert.X509Certificate + +class TrustAllHostnameVerifier : HostnameVerifier { + override fun checkValid(address: SocketAddress, chain: Array<out X509Certificate>) = Unit +} diff --git a/lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt new file mode 100644 index 000000000..3bd19a4f8 --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/ssl/TrustManagers.kt @@ -0,0 +1,43 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * 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 de.kuschku.libquassel.ssl + +import java.security.GeneralSecurityException +import java.security.KeyStore +import java.security.cert.X509Certificate +import javax.net.ssl.KeyManagerFactory +import javax.net.ssl.TrustManagerFactory +import javax.net.ssl.X509TrustManager + +object TrustManagers { + fun default() = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()).apply { + init(null as KeyStore?) + }.trustManagers.mapNotNull { + it as? X509TrustManager + }.firstOrNull() ?: throw GeneralSecurityException("No TrustManager available") + + fun trustAll() = TrustAllX509TrustManager() + + class TrustAllX509TrustManager : X509TrustManager { + override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit + override fun checkServerTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit + override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray() + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/ssl/X509Helper.kt b/lib/src/main/java/de/kuschku/libquassel/ssl/X509Helper.kt similarity index 96% rename from app/src/main/java/de/kuschku/quasseldroid/ssl/X509Helper.kt rename to lib/src/main/java/de/kuschku/libquassel/ssl/X509Helper.kt index 0270a1ea2..a2562c2a2 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ssl/X509Helper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/ssl/X509Helper.kt @@ -17,14 +17,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.quasseldroid.ssl +package de.kuschku.libquassel.ssl import java.security.cert.X509Certificate // FIXME: re-read RFC and check it's actually secure object X509Helper { fun hostnames(certificate: X509Certificate): Sequence<String> = - (sequenceOf(commonName(certificate)) + subjectAlternativeNames(certificate)) + (sequenceOf(commonName(certificate)) + subjectAlternativeNames( + certificate)) .filterNotNull() .distinct() diff --git a/settings.gradle b/settings.gradle index 919e4870e..ee35cd847 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,9 +17,11 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -include ':invokerannotations', ':lifecycle-ktx', +include ':invokerannotations', ':invokergenerator', ':lib', + ':lifecycle-ktx', + ':desktop', ":viewmodel", ":persistence", ':malheur', -- GitLab