From b0d90f32974f6473552d8b1bf5387f9fc4995970 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Thu, 25 Jul 2024 19:09:41 +0200 Subject: samba: Add credentials object Ask for enough permissions to be able to create sockets. --- .idea/misc.xml | 6 +++++ app/src/main/AndroidManifest.xml | 2 ++ .../java/org/the_jk/cleversync/io/TreeFactory.kt | 9 ++++---- libs/samba/src/main/cpp/samba.cpp | 27 ++++++++++++++-------- .../org/the_jk/cleversync/io/samba/NativeSamba.kt | 15 +++++++----- .../the_jk/cleversync/io/samba/SambaConnection.kt | 4 ++-- .../the_jk/cleversync/io/samba/SambaCredentials.kt | 3 +++ .../the_jk/cleversync/samba/SambaTreeFactory.kt | 7 +++--- 8 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaCredentials.kt diff --git a/.idea/misc.xml b/.idea/misc.xml index 8978d23..04537b6 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,10 @@ + + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d6fb563..a1a11d6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + { - return SambaTreeFactory.modifiableTree(uri) + fun sambaModifiableTree(uri: String, credentials: SambaCredentials): Result { + return SambaTreeFactory.modifiableTree(uri, credentials) } - fun sambaTree(uri: String): Result { - return SambaTreeFactory.tree(uri) + fun sambaTree(uri: String, credentials: SambaCredentials): Result { + return SambaTreeFactory.tree(uri, credentials) } } diff --git a/libs/samba/src/main/cpp/samba.cpp b/libs/samba/src/main/cpp/samba.cpp index 5eafacc..e3b689d 100644 --- a/libs/samba/src/main/cpp/samba.cpp +++ b/libs/samba/src/main/cpp/samba.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +53,9 @@ class Url { class Context { public: - Context() : context_(smb2_init_context(), ContextDeleter{}) {} + explicit Context(int timeout) : context_(smb2_init_context(), ContextDeleter{}) { + smb2_set_timeout(context_.get(), timeout); + } ~Context() = default; Context(const Context&) = delete; @@ -63,8 +66,10 @@ class Context { return ptr ? std::make_unique(ptr): nullptr; } - bool Connect(const Url& url) { - return smb2_connect_share(context_.get(), url.server(), url.share(), url.user()) == 0; + bool Connect(const Url& url, const std::optional& username, const std::optional& password) { + if (password.has_value()) smb2_set_password(context_.get(), password->c_str()); + auto* user = username.has_value() ? username->c_str() : url.user(); + return smb2_connect_share(context_.get(), url.server(), url.share(), user) == 0; } [[nodiscard]] std::string_view GetError() { @@ -86,8 +91,8 @@ class Context { std::shared_ptr context_; }; -jlong nativeContextNew(JNIEnv* env, jclass clazz) { - return reinterpret_cast(new Context()); +jlong nativeContextNew(JNIEnv* env, jclass clazz, jint timeout) { + return reinterpret_cast(new Context(static_cast(timeout))); } void nativeContextDestroy(JNIEnv* env, jclass clazz, jlong ptr) { @@ -98,10 +103,14 @@ jlong nativeContextParseUrl(JNIEnv* env, jclass clazz, jlong ptr, jstring url) { return reinterpret_cast(reinterpret_cast(ptr)->ParseUrl(jni::StringToUTF8(env, jni::ParamRef(env, url))).release()); } -jboolean nativeContextConnect(JNIEnv* env, jclass clazz, jlong context_ptr, jlong url_ptr) { +jboolean nativeContextConnect(JNIEnv* env, jclass clazz, jlong context_ptr, jlong url_ptr, jstring j_username, jstring j_password) { auto* url = reinterpret_cast(url_ptr); if (!url) return JNI_FALSE; - return reinterpret_cast(context_ptr)->Connect(*url) ? JNI_TRUE : JNI_FALSE; + std::optional username; + std::optional password; + if (j_username) username = jni::StringToUTF8(env, jni::ParamRef(env, j_username)); + if (j_password) password = jni::StringToUTF8(env, jni::ParamRef(env, j_password)); + return reinterpret_cast(context_ptr)->Connect(*url, username, password) ? JNI_TRUE : JNI_FALSE; } jstring nativeContextGetError(JNIEnv* env, jclass clazz, jlong ptr) { @@ -128,10 +137,10 @@ void RegisterSamba(JNIEnv* env) { auto clazz = jni::FindClass(env, "org/the_jk/cleversync/io/samba/NativeSamba"); ABORT_IF_NULL(env, clazz); static const JNINativeMethod methods[] = { - { "nativeContextNew", "()J", reinterpret_cast(&nativeContextNew) }, + { "nativeContextNew", "(I)J", reinterpret_cast(&nativeContextNew) }, { "nativeContextDestroy", "(J)V", reinterpret_cast(&nativeContextDestroy) }, { "nativeContextParseUrl", "(JLjava/lang/String;)J", reinterpret_cast(&nativeContextParseUrl) }, - { "nativeContextConnect", "(JJ)Z", reinterpret_cast(&nativeContextConnect) }, + { "nativeContextConnect", "(JJLjava/lang/String;Ljava/lang/String;)Z", reinterpret_cast(&nativeContextConnect) }, { "nativeContextGetError", "(J)Ljava/lang/String;", reinterpret_cast(&nativeContextGetError) }, { "nativeContextOpenDir", "(JLjava/lang/String;)J", reinterpret_cast(&nativeContextOpenDir) }, diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt index 360aaa9..e48268d 100644 --- a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt +++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt @@ -4,10 +4,13 @@ package org.the_jk.cleversync.io.samba import androidx.annotation.Keep +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds @Keep internal object NativeSamba { - fun newContext(): Context = NativeContext(nativeContextNew()) + fun newContext(timeout: Duration = 30.seconds): Context = + NativeContext(nativeContextNew(timeout.inWholeSeconds.toInt())) interface Object { fun destroy() @@ -15,7 +18,7 @@ internal object NativeSamba { interface Context : Object { fun parseUrl(url: String): Url? - fun connect(url: Url): Boolean + fun connect(url: Url, credentials: SambaCredentials): Boolean fun lastError(): String fun openDir(path: String): Dir? } @@ -40,8 +43,8 @@ internal object NativeSamba { return if (ptr != 0L) NativeUrl(ptr) else null } - override fun connect(url: Url): Boolean { - return nativeContextConnect(ptr, (url as NativeUrl).get()) + override fun connect(url: Url, credentials: SambaCredentials): Boolean { + return nativeContextConnect(ptr, (url as NativeUrl).get(), credentials.username, credentials.password) } override fun lastError(): String { @@ -78,10 +81,10 @@ internal object NativeSamba { System.loadLibrary("samba") } - private external fun nativeContextNew(): Long + private external fun nativeContextNew(timeoutSeconds: Int): Long private external fun nativeContextDestroy(ptr: Long) private external fun nativeContextParseUrl(ptr: Long, url: String): Long - private external fun nativeContextConnect(ptr: Long, url: Long): Boolean + private external fun nativeContextConnect(ptr: Long, url: Long, username: String?, password: String?): Boolean private external fun nativeContextGetError(ptr: Long): String private external fun nativeContextOpenDir(ptr: Long, path: String): Long diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt index 03d3a9e..05cc831 100644 --- a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt +++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt @@ -1,10 +1,10 @@ package org.the_jk.cleversync.io.samba -internal class SambaConnection(uri: String) { +internal class SambaConnection(uri: String, credentials: SambaCredentials) { private val context = NativeSamba.newContext() private val url = context.parseUrl(uri) - val connected = if (url != null) { context.connect(url) } else false + val connected = if (url != null) { context.connect(url, credentials) } else false val error: String get() = context.lastError() diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaCredentials.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaCredentials.kt new file mode 100644 index 0000000..4b1518b --- /dev/null +++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaCredentials.kt @@ -0,0 +1,3 @@ +package org.the_jk.cleversync.io.samba + +data class SambaCredentials(val username: String?, val password: String?) diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt b/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt index 3455de8..5c9bc4f 100644 --- a/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt +++ b/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt @@ -3,13 +3,14 @@ package org.the_jk.cleversync.samba import org.the_jk.cleversync.io.ModifiableTree import org.the_jk.cleversync.io.Tree import org.the_jk.cleversync.io.samba.SambaConnection +import org.the_jk.cleversync.io.samba.SambaCredentials import org.the_jk.cleversync.io.samba.SambaTree object SambaTreeFactory { - fun tree(uri: String): Result = modifiableTree(uri) + fun tree(uri: String, credentials: SambaCredentials): Result = modifiableTree(uri, credentials) - fun modifiableTree(uri: String): Result { - val connection = SambaConnection(uri) + fun modifiableTree(uri: String, credentials: SambaCredentials): Result { + val connection = SambaConnection(uri, credentials) if (!connection.connected) return Result.failure(Exception(connection.error)) val root = connection.openDir("") ?: return Result.failure(Exception(connection.error)) return Result.success(SambaTree(connection, root)) -- cgit v1.2.3-70-g09d2