diff --git a/app/build.gradle b/app/build.gradle index 7d098aa..ba3614d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,11 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' +ext { + enableCryFS = true + enableGocryptfs = true +} + android { compileSdkVersion 31 buildToolsVersion "31" @@ -21,6 +26,16 @@ android { ndk { abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a" } + + externalNativeBuild.cmake { + targets "mux" + if (project.ext.enableGocryptfs) { + targets += "gocryptfs_jni" + } + if (project.ext.enableCryFS) { + targets += "cryfs_jni" + } + } } if (!file("fdroid").exists()) { @@ -34,6 +49,8 @@ android { applicationVariants.all { variant -> variant.resValue "string", "versionName", variant.versionName + buildConfigField "boolean", "CRYFS_ENABLED", "${project.ext.enableCryFS}" + buildConfigField "boolean", "GOCRYPTFS_ENABLED", "${project.ext.enableGocryptfs}" } buildFeatures { diff --git a/app/libcryfs b/app/libcryfs index 6cd6d9e..fb593c4 160000 --- a/app/libcryfs +++ b/app/libcryfs @@ -1 +1 @@ -Subproject commit 6cd6d9ef5d2f3f41581fbac5d3eb413364714dcf +Subproject commit fb593c468c62c2f92b0420e80e1f77c001dd3a24 diff --git a/app/src/main/java/sushi/hardcore/droidfs/ChangePasswordActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/ChangePasswordActivity.kt index a73e973..498090b 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/ChangePasswordActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/ChangePasswordActivity.kt @@ -9,6 +9,7 @@ import android.view.View import android.widget.Toast import androidx.lifecycle.lifecycleScope import sushi.hardcore.droidfs.databinding.ActivityChangePasswordBinding +import sushi.hardcore.droidfs.filesystems.GocryptfsVolume import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder import java.util.* diff --git a/app/src/main/java/sushi/hardcore/droidfs/ConstValues.kt b/app/src/main/java/sushi/hardcore/droidfs/ConstValues.kt index bbcf554..ece664b 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/ConstValues.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/ConstValues.kt @@ -11,6 +11,7 @@ object ConstValues { val FAKE_URI: Uri = Uri.parse("fakeuri://droidfs") const val MAX_KERNEL_WRITE = 128*1024 const val WIPE_PASSES = 2 + const val IO_BUFF_SIZE = 16384 const val SLIDESHOW_DELAY: Long = 4000 const val DEFAULT_THEME_VALUE = "dark_green" const val THUMBNAIL_MAX_SIZE_KEY = "thumbnail_max_size" diff --git a/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt index 39dda28..31f602f 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt @@ -31,13 +31,12 @@ import sushi.hardcore.droidfs.explorers.ExplorerActivityDrop import sushi.hardcore.droidfs.explorers.ExplorerActivityPick import sushi.hardcore.droidfs.file_operations.FileOperationService import sushi.hardcore.droidfs.filesystems.EncryptedVolume +import sushi.hardcore.droidfs.filesystems.GocryptfsVolume import sushi.hardcore.droidfs.util.PathUtils import sushi.hardcore.droidfs.util.WidgetUtil import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder import sushi.hardcore.droidfs.widgets.EditTextDialog import java.io.File -import java.nio.CharBuffer -import java.nio.charset.StandardCharsets import java.util.* class MainActivity : BaseActivity(), VolumeAdapter.Listener { @@ -346,6 +345,7 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { menu.findItem(R.id.change_password).isVisible = onlyOneAndWriteable && // Only gocryptfs volumes support password change + BuildConfig.GOCRYPTFS_ENABLED && volumeAdapter.volumes[volumeAdapter.selectedItems.first()].type == EncryptedVolume.GOCRYPTFS_VOLUME_TYPE menu.findItem(R.id.remove_default_open).isVisible = onlyOneSelected && @@ -461,6 +461,13 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { @SuppressLint("NewApi") // fingerprintProtector is non-null only when SDK_INT >= 23 private fun openVolume(volume: SavedVolume, position: Int) { + if (volume.type == EncryptedVolume.GOCRYPTFS_VOLUME_TYPE && !BuildConfig.GOCRYPTFS_ENABLED) { + Toast.makeText(this, R.string.gocryptfs_disabled, Toast.LENGTH_SHORT).show() + return + } else if (volume.type == EncryptedVolume.CRYFS_VOLUME_TYPE && !BuildConfig.CRYFS_ENABLED) { + Toast.makeText(this, R.string.cryfs_disabled, Toast.LENGTH_SHORT).show() + return + } var askForPassword = true fingerprintProtector?.let { fingerprintProtector -> volume.encryptedHash?.let { encryptedHash -> @@ -646,11 +653,8 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { if (pickMode && !usfKeepOpen) { finish() if (shouldCloseVolume) { - val sessionID = intent.getIntExtra("sessionID", -1) - if (sessionID != -1) { - GocryptfsVolume(sessionID).close() - RestrictedFileProvider.wipeAll(this) - } + intent.getParcelableExtra("volume")?.close() + RestrictedFileProvider.wipeAll(this) } } } diff --git a/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt b/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt index 672efb9..3e252bd 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt @@ -17,10 +17,12 @@ import sushi.hardcore.droidfs.* import sushi.hardcore.droidfs.databinding.FragmentCreateVolumeBinding import sushi.hardcore.droidfs.filesystems.CryfsVolume import sushi.hardcore.droidfs.filesystems.EncryptedVolume +import sushi.hardcore.droidfs.filesystems.GocryptfsVolume import sushi.hardcore.droidfs.util.WidgetUtil import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder import java.io.File import java.util.* +import kotlin.collections.ArrayList class CreateVolumeFragment: Fragment() { companion object { @@ -51,6 +53,7 @@ class CreateVolumeFragment: Fragment() { private lateinit var binding: FragmentCreateVolumeBinding private var themeValue = ConstValues.DEFAULT_THEME_VALUE + private val volumeTypes = ArrayList(2) private lateinit var volumePath: String private var isHiddenVolume: Boolean = false private var usfFingerprint: Boolean = false @@ -82,10 +85,16 @@ class CreateVolumeFragment: Fragment() { if (!usfFingerprint || fingerprintProtector == null) { binding.checkboxSavePassword.visibility = View.GONE } + if (BuildConfig.GOCRYPTFS_ENABLED) { + volumeTypes.add(resources.getString(R.string.gocryptfs)) + } + if (BuildConfig.CRYFS_ENABLED) { + volumeTypes.add(resources.getString(R.string.cryfs)) + } binding.spinnerVolumeType.adapter = ArrayAdapter( requireContext(), android.R.layout.simple_spinner_item, - resources.getStringArray(R.array.volume_types) + volumeTypes ).apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } @@ -98,8 +107,10 @@ class CreateVolumeFragment: Fragment() { } binding.spinnerVolumeType.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - val ciphersArray = if (position == 0) { // Gocryptfs - binding.checkboxSavePassword.visibility = View.VISIBLE + val ciphersArray = if (volumeTypes[position] == resources.getString(R.string.gocryptfs)) { + if (usfFingerprint && fingerprintProtector != null) { + binding.checkboxSavePassword.visibility = View.VISIBLE + } R.array.gocryptfs_encryption_ciphers } else { binding.checkboxSavePassword.visibility = View.GONE @@ -164,7 +175,7 @@ class CreateVolumeFragment: Fragment() { val volumeFile = File(volumePath) if (!volumeFile.exists()) volumeFile.mkdirs() - val volume = if (binding.spinnerVolumeType.selectedItem == 0) { // Gocryptfs + val volume = if (volumeTypes[binding.spinnerVolumeType.selectedItemPosition] == resources.getString(R.string.gocryptfs)) { val xchacha = when (binding.spinnerCipher.selectedItemPosition) { 0 -> 0 1 -> 1 diff --git a/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt index 87011c7..f017c46 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt @@ -32,7 +32,6 @@ import sushi.hardcore.droidfs.ConstValues.isImage import sushi.hardcore.droidfs.ConstValues.isPDF import sushi.hardcore.droidfs.ConstValues.isText import sushi.hardcore.droidfs.ConstValues.isVideo -import sushi.hardcore.droidfs.GocryptfsVolume import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.adapters.ExplorerElementAdapter import sushi.hardcore.droidfs.adapters.OpenAsDialogAdapter diff --git a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt index 6a6257d..ef0fc29 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt @@ -3,7 +3,6 @@ package sushi.hardcore.droidfs.explorers import android.app.Activity import android.content.Intent import android.net.Uri -import android.util.Log import android.view.Menu import android.view.MenuItem import android.widget.Toast @@ -12,7 +11,6 @@ import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch import sushi.hardcore.droidfs.CameraActivity -import sushi.hardcore.droidfs.GocryptfsVolume import sushi.hardcore.droidfs.MainActivity import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.adapters.IconTextDialogAdapter @@ -24,7 +22,6 @@ import sushi.hardcore.droidfs.filesystems.Stat import sushi.hardcore.droidfs.util.PathUtils import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder import sushi.hardcore.droidfs.widgets.EditTextDialog -import java.io.File class ExplorerActivity : BaseExplorerActivity() { companion object { diff --git a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityPick.kt b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityPick.kt index d289ec2..7327db8 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityPick.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityPick.kt @@ -2,14 +2,11 @@ package sushi.hardcore.droidfs.explorers import android.app.Activity import android.content.Intent -import android.util.Log import android.view.Menu import android.view.MenuItem import sushi.hardcore.droidfs.R -import sushi.hardcore.droidfs.GocryptfsVolume import sushi.hardcore.droidfs.filesystems.EncryptedVolume import sushi.hardcore.droidfs.util.PathUtils -import java.util.* class ExplorerActivityPick : BaseExplorerActivity() { private var resultIntent = Intent() diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt b/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt index ed231ae..22201ed 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt @@ -14,7 +14,7 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.documentfile.provider.DocumentFile import kotlinx.coroutines.* -import sushi.hardcore.droidfs.GocryptfsVolume +import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.explorers.ExplorerElement import sushi.hardcore.droidfs.filesystems.EncryptedVolume @@ -129,7 +129,7 @@ class FileOperationService : Service() { val dstFileHandle = encryptedVolume.openFile(dstPath) if (dstFileHandle != -1L) { var offset: Long = 0 - val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS) + val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE) var length: Int while (remoteEncryptedVolume.read(srcFileHandle, ioBuffer, offset).also { length = it } > 0) { val written = encryptedVolume.write(dstFileHandle, offset, ioBuffer, length).toLong() diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt index ba2b5a1..96c798f 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt @@ -6,7 +6,6 @@ import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import sushi.hardcore.droidfs.BaseActivity import sushi.hardcore.droidfs.ConstValues -import sushi.hardcore.droidfs.GocryptfsVolume import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.content_providers.RestrictedFileProvider import sushi.hardcore.droidfs.explorers.ExplorerElement diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt index 65c5da1..a875ba0 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt @@ -3,12 +3,11 @@ package sushi.hardcore.droidfs.file_viewers import android.annotation.SuppressLint import android.text.Editable import android.text.TextWatcher -import android.util.Log import android.view.Menu import android.view.MenuItem import android.widget.EditText import android.widget.Toast -import sushi.hardcore.droidfs.GocryptfsVolume +import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder import java.io.ByteArrayInputStream @@ -73,7 +72,7 @@ class TextEditor: FileViewerActivity() { if (fileHandle != -1L) { val buff = ByteArrayInputStream(content) var offset: Long = 0 - val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS) + val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE) var length: Int while (buff.read(ioBuffer).also { length = it } > 0) { val written = encryptedVolume.write(fileHandle, offset, ioBuffer, length).toLong() diff --git a/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt b/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt index 3e709bf..3b44686 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/filesystems/CryfsVolume.kt @@ -1,7 +1,6 @@ package sushi.hardcore.droidfs.filesystems import android.os.Parcel -import android.util.Log import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.explorers.ExplorerElement import sushi.hardcore.droidfs.util.PathUtils diff --git a/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt b/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt index 79a5c80..0ea6465 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/filesystems/EncryptedVolume.kt @@ -5,7 +5,6 @@ import android.net.Uri import android.os.Parcel import android.os.Parcelable import sushi.hardcore.droidfs.ConstValues -import sushi.hardcore.droidfs.GocryptfsVolume import sushi.hardcore.droidfs.SavedVolume import sushi.hardcore.droidfs.explorers.ExplorerElement import sushi.hardcore.droidfs.util.PathUtils @@ -80,7 +79,7 @@ abstract class EncryptedVolume: Parcelable { fun exportFile(fileHandle: Long, os: OutputStream): Boolean { var offset: Long = 0 - val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS) + val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE) var length: Int while (read(fileHandle, ioBuffer, offset).also { length = it } > 0){ os.write(ioBuffer, 0, length) @@ -117,7 +116,7 @@ abstract class EncryptedVolume: Parcelable { if (dstfileHandle != -1L) { var success = true var offset: Long = 0 - val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS) + val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE) var length: Int while (inputStream.read(ioBuffer).also { length = it } > 0) { val written = write(dstfileHandle, offset, ioBuffer, length).toLong() @@ -159,7 +158,7 @@ abstract class EncryptedVolume: Parcelable { Pair(null, 3) } else { var offset: Long = 0 - val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS) + val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE) var length: Int while (read(fileHandle, ioBuffer, offset).also { length = it } > 0) { System.arraycopy(ioBuffer, 0, fileBuff, offset.toInt(), length) diff --git a/app/src/main/java/sushi/hardcore/droidfs/GocryptfsVolume.kt b/app/src/main/java/sushi/hardcore/droidfs/filesystems/GocryptfsVolume.kt similarity index 95% rename from app/src/main/java/sushi/hardcore/droidfs/GocryptfsVolume.kt rename to app/src/main/java/sushi/hardcore/droidfs/filesystems/GocryptfsVolume.kt index 5a60814..22d60a8 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/GocryptfsVolume.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/filesystems/GocryptfsVolume.kt @@ -1,14 +1,12 @@ -package sushi.hardcore.droidfs +package sushi.hardcore.droidfs.filesystems import android.os.Parcel import sushi.hardcore.droidfs.explorers.ExplorerElement -import sushi.hardcore.droidfs.filesystems.EncryptedVolume -import sushi.hardcore.droidfs.filesystems.Stat class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() { private external fun native_close(sessionID: Int) private external fun native_is_closed(sessionID: Int): Boolean - private external fun native_list_dir(sessionID: Int, dir_path: String): MutableList + private external fun native_list_dir(sessionID: Int, dir_path: String): MutableList? private external fun native_open_read_mode(sessionID: Int, file_path: String): Int private external fun native_open_write_mode(sessionID: Int, file_path: String, mode: Int): Int private external fun native_read_file(sessionID: Int, handleID: Int, offset: Long, buff: ByteArray): Int @@ -24,7 +22,6 @@ class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() { companion object { const val KeyLen = 32 const val ScryptDefaultLogN = 16 - const val DefaultBS = 4096 const val CONFIG_FILE_NAME = "gocryptfs.conf" external fun createVolume(root_cipher_dir: String, password: ByteArray, plainTextNames: Boolean, xchacha: Int, logN: Int, creator: String, returnedHash: ByteArray?): Boolean private external fun nativeInit(root_cipher_dir: String, password: ByteArray?, givenHash: ByteArray?, returnedHash: ByteArray?): Int diff --git a/app/src/main/native/gocryptfs_jni.c b/app/src/main/native/gocryptfs_jni.c index dc38404..0dc3113 100644 --- a/app/src/main/native/gocryptfs_jni.c +++ b/app/src/main/native/gocryptfs_jni.c @@ -30,7 +30,7 @@ void jbyteArray_to_unsignedCharArray(const jbyte* src, unsigned char* dst, const } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_00024Companion_createVolume(JNIEnv *env, jclass clazz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_00024Companion_createVolume(JNIEnv *env, jclass clazz, jstring jroot_cipher_dir, jbyteArray jpassword, jboolean plainTextNames, @@ -77,7 +77,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_00024Companion_createVolume(JNIEnv * } JNIEXPORT jint JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_00024Companion_nativeInit(JNIEnv *env, jobject clazz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_00024Companion_nativeInit(JNIEnv *env, jobject clazz, jstring jroot_cipher_dir, jbyteArray jpassword, jbyteArray jgiven_hash, @@ -145,13 +145,13 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_00024Companion_nativeInit(JNIEnv *en } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1is_1closed(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1is_1closed(JNIEnv *env, jobject thiz, jint sessionID) { return gcf_is_closed(sessionID); } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_00024Companion_changePassword(JNIEnv *env, jclass clazz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_00024Companion_changePassword(JNIEnv *env, jclass clazz, jstring jroot_cipher_dir, jcharArray jold_password, jbyteArray jgiven_hash, @@ -220,6 +220,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_00024Companion_changePassword(JNIEnv } wipe(new_password, new_password_len); + free(new_password); (*env)->ReleaseCharArrayElements(env, jnew_password, jchar_new_password, 0); if (!(*env)->IsSameObject(env, jreturned_hash, NULL)) { @@ -233,12 +234,12 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_00024Companion_changePassword(JNIEnv } JNIEXPORT void JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1close(JNIEnv *env, jobject thiz, jint sessionID) { +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1close(JNIEnv *env, jobject thiz, jint sessionID) { gcf_close(sessionID); } JNIEXPORT jobject JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1list_1dir(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1list_1dir(JNIEnv *env, jobject thiz, jint sessionID, jstring jplain_dir) { const char* plain_dir = (*env)->GetStringUTFChars(env, jplain_dir, NULL); const size_t plain_dir_len = strlen(plain_dir); @@ -246,55 +247,59 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1list_1dir(JNIEnv *env, jobje struct gcf_list_dir_return elements = gcf_list_dir(sessionID, go_plain_dir); - jclass java_ArrayList = (*env)->NewLocalRef(env, (*env)->FindClass(env, "java/util/ArrayList")); - jmethodID java_ArrayList_init = (*env)->GetMethodID(env, java_ArrayList, "", "(I)V"); - jmethodID java_ArrayList_add = (*env)->GetMethodID(env, java_ArrayList, "add", "(Ljava/lang/Object;)Z"); + jobject elementList = NULL; + if (elements.r0 != NULL) { + jclass arrayList = (*env)->NewLocalRef(env, (*env)->FindClass(env, "java/util/ArrayList")); + jmethodID arrayListInit = (*env)->GetMethodID(env, arrayList, "", "(I)V"); + jmethodID arrayListAdd = (*env)->GetMethodID(env, arrayList, "add", "(Ljava/lang/Object;)Z"); + jclass classExplorerElement = (*env)->NewLocalRef(env, (*env)->FindClass(env, "sushi/hardcore/droidfs/explorers/ExplorerElement")); + jmethodID explorerElementNew = (*env)->GetStaticMethodID(env, classExplorerElement, "new", "(Ljava/lang/String;IJJLjava/lang/String;)Lsushi/hardcore/droidfs/explorers/ExplorerElement;"); + elementList = (*env)->NewObject(env, arrayList, arrayListInit, elements.r2); - jclass classExplorerElement = (*env)->NewLocalRef(env, (*env)->FindClass(env, "sushi/hardcore/droidfs/explorers/ExplorerElement")); - jmethodID explorerElement_new = (*env)->GetStaticMethodID(env, classExplorerElement, "new", "(Ljava/lang/String;IJJLjava/lang/String;)Lsushi/hardcore/droidfs/explorers/ExplorerElement;"); - jobject element_list = (*env)->NewObject(env, java_ArrayList, java_ArrayList_init, elements.r2); - unsigned int c = 0; - for (unsigned int i=0; iNewStringUTF(env, name); + jobject explorerElement = (*env)->CallStaticObjectMethod( + env, + classExplorerElement, + explorerElementNew, + jname, + elements.r1[i], + (long long) attrs.r1, + (long long) attrs.r2, + jplain_dir + ); + (*env)->CallBooleanMethod(env, elementList, arrayListAdd, explorerElement); + (*env)->DeleteLocalRef(env, explorerElement); + (*env)->DeleteLocalRef(env, jname); + c += nameLen + 1; } - strcat(gcf_full_path, name); - GoString go_name = {gcf_full_path, strlen(gcf_full_path)}; - struct gcf_get_attrs_return attrs = gcf_get_attrs(sessionID, go_name); - - jstring jname = (*env)->NewStringUTF(env, name); - jobject explorerElement = (*env)->CallStaticObjectMethod( - env, - classExplorerElement, - explorerElement_new, - jname, - elements.r1[i], - (long long) attrs.r1, - attrs.r2, - jplain_dir - ); - (*env)->CallBooleanMethod(env, element_list, java_ArrayList_add, explorerElement); - (*env)->DeleteLocalRef(env, explorerElement); - (*env)->DeleteLocalRef(env, jname); - c += name_len+1; + free(elements.r0); + free(elements.r1); } - free(elements.r0); - free(elements.r1); - (*env)->ReleaseStringUTFChars(env, jplain_dir, plain_dir); - return element_list; + return elementList; } JNIEXPORT jobject JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1get_1attr(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1get_1attr(JNIEnv *env, jobject thiz, jint sessionID, jstring jfile_path) { const char* file_path = (*env)->GetStringUTFChars(env, jfile_path, NULL); GoString go_file_path = {file_path, strlen(file_path)}; @@ -318,7 +323,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1get_1attr(JNIEnv *env, jobje } JNIEXPORT jint JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1open_1read_1mode(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1open_1read_1mode(JNIEnv *env, jobject thiz, jint sessionID, jstring jfile_path) { const char* file_path = (*env)->GetStringUTFChars(env, jfile_path, NULL); @@ -332,7 +337,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1open_1read_1mode(JNIEnv *env } JNIEXPORT jint JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1open_1write_1mode(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1open_1write_1mode(JNIEnv *env, jobject thiz, jint sessionID, jstring jfile_path, jint mode) { @@ -347,7 +352,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1open_1write_1mode(JNIEnv *en } JNIEXPORT jint JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1write_1file(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1write_1file(JNIEnv *env, jobject thiz, jint sessionID, jint handleID, jlong offset, jbyteArray jbuff, jint buff_size) { jbyte* buff = (*env)->GetByteArrayElements(env, jbuff, NULL); @@ -361,24 +366,24 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1write_1file(JNIEnv *env, job } JNIEXPORT jint JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1read_1file(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1read_1file(JNIEnv *env, jobject thiz, jint sessionID, jint handleID, jlong offset, jbyteArray jbuff) { const size_t buff_size = (*env)->GetArrayLength(env, jbuff); - unsigned char buff[buff_size]; + unsigned char* buff = malloc(sizeof(char)*buff_size); GoSlice go_buff = {buff, buff_size, buff_size}; int read = gcf_read_file(sessionID, handleID, offset, go_buff); if (read > 0){ - (*env)->SetByteArrayRegion(env, jbuff, 0, read, buff); + (*env)->SetByteArrayRegion(env, jbuff, 0, read, (const jbyte*)buff); } - + free(buff); return read; } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1truncate(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1truncate(JNIEnv *env, jobject thiz, jint sessionID, jstring jpath, jlong offset) { @@ -392,14 +397,14 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1truncate(JNIEnv *env, jobjec } JNIEXPORT void JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1close_1file(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1close_1file(JNIEnv *env, jobject thiz, jint sessionID, jint handleID) { gcf_close_file(sessionID, handleID); } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1remove_1file(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1remove_1file(JNIEnv *env, jobject thiz, jint sessionID, jstring jfile_path) { const char* file_path = (*env)->GetStringUTFChars(env, jfile_path, NULL); GoString go_file_path = {file_path, strlen(file_path)}; @@ -412,7 +417,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1remove_1file(JNIEnv *env, jo } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1mkdir(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1mkdir(JNIEnv *env, jobject thiz, jint sessionID, jstring jdir_path, jint mode) { const char* dir_path = (*env)->GetStringUTFChars(env, jdir_path, NULL); GoString go_dir_path = {dir_path, strlen(dir_path)}; @@ -425,7 +430,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1mkdir(JNIEnv *env, jobject t } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1rmdir(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1rmdir(JNIEnv *env, jobject thiz, jint sessionID, jstring jdir_path) { const char* dir_path = (*env)->GetStringUTFChars(env, jdir_path, NULL); GoString go_dir_path = {dir_path, strlen(dir_path)}; @@ -438,7 +443,7 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1rmdir(JNIEnv *env, jobject t } JNIEXPORT jboolean JNICALL -Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1rename(JNIEnv *env, jobject thiz, +Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1rename(JNIEnv *env, jobject thiz, jint sessionID, jstring jold_path, jstring jnew_path) { const char* old_path = (*env)->GetStringUTFChars(env, jold_path, NULL); @@ -452,4 +457,4 @@ Java_sushi_hardcore_droidfs_GocryptfsVolume_native_1rename(JNIEnv *env, jobject (*env)->ReleaseStringUTFChars(env, jnew_path, new_path); return result; -} +} \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 2ca30eb..8e75c9e 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,9 +1,4 @@ - - Gocryptfs - CryFS - - AES-GCM XChaCha20-Poly1305 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 09ed838..58216ae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -242,4 +242,8 @@ Numeric keypad layout Use a numeric keypad layout when entering volume passwords Volume type: + Gocryptfs + CryFS + Gocryptfs support has been disabled + CryFS support has been disabled