2022-06-18 21:13:16 +02:00
|
|
|
package sushi.hardcore.droidfs.filesystems
|
|
|
|
|
|
|
|
import android.os.Parcel
|
2022-09-30 21:22:37 +02:00
|
|
|
import android.util.Log
|
2022-06-18 21:13:16 +02:00
|
|
|
import sushi.hardcore.droidfs.explorers.ExplorerElement
|
2022-09-30 21:22:37 +02:00
|
|
|
import sushi.hardcore.droidfs.util.ObjRef
|
2022-09-23 20:58:16 +02:00
|
|
|
import kotlin.math.min
|
2022-06-18 21:13:16 +02:00
|
|
|
|
|
|
|
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<ExplorerElement>?
|
|
|
|
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
|
2022-09-23 20:58:16 +02:00
|
|
|
private external fun native_read_file(sessionID: Int, handleID: Int, fileOffset: Long, buff: ByteArray, dstOffset: Long, length: Int): Int
|
|
|
|
private external fun native_write_file(sessionID: Int, handleID: Int, fileOffset: Long, buff: ByteArray, srcOffset: Long, length: Int): Int
|
2022-06-18 21:13:16 +02:00
|
|
|
private external fun native_truncate(sessionID: Int, path: String, offset: Long): Boolean
|
|
|
|
private external fun native_close_file(sessionID: Int, handleID: Int)
|
|
|
|
private external fun native_remove_file(sessionID: Int, file_path: String): Boolean
|
|
|
|
private external fun native_mkdir(sessionID: Int, dir_path: String, mode: Int): Boolean
|
|
|
|
private external fun native_rmdir(sessionID: Int, dir_path: String): Boolean
|
|
|
|
private external fun native_get_attr(sessionID: Int, file_path: String): Stat?
|
|
|
|
private external fun native_rename(sessionID: Int, old_path: String, new_path: String): Boolean
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
const val KeyLen = 32
|
2022-09-30 21:22:37 +02:00
|
|
|
private const val ScryptDefaultLogN = 16
|
|
|
|
private const val VOLUME_CREATOR = "DroidFS"
|
|
|
|
private const val MAX_KERNEL_WRITE = 128*1024
|
2022-06-18 21:13:16 +02:00
|
|
|
const val CONFIG_FILE_NAME = "gocryptfs.conf"
|
2022-09-30 21:22:37 +02:00
|
|
|
private external fun nativeCreateVolume(
|
|
|
|
root_cipher_dir: String,
|
|
|
|
password: ByteArray,
|
|
|
|
plainTextNames: Boolean,
|
|
|
|
xchacha: Int,
|
|
|
|
logN: Int,
|
|
|
|
creator: String,
|
|
|
|
returnedHash: ByteArray?,
|
|
|
|
): Int
|
2022-06-18 21:13:16 +02:00
|
|
|
private external fun nativeInit(root_cipher_dir: String, password: ByteArray?, givenHash: ByteArray?, returnedHash: ByteArray?): Int
|
2022-06-30 21:43:40 +02:00
|
|
|
external fun changePassword(
|
|
|
|
root_cipher_dir: String,
|
|
|
|
currentPassword: ByteArray?,
|
|
|
|
givenHash: ByteArray?,
|
|
|
|
newPassword: ByteArray,
|
|
|
|
returnedHash: ByteArray?
|
|
|
|
): Boolean
|
2022-06-18 21:13:16 +02:00
|
|
|
|
2022-09-30 21:22:37 +02:00
|
|
|
fun createAndOpenVolume(
|
|
|
|
root_cipher_dir: String,
|
|
|
|
password: ByteArray,
|
|
|
|
plainTextNames: Boolean,
|
|
|
|
xchacha: Int,
|
|
|
|
returnedHash: ByteArray?,
|
2023-03-07 23:25:17 +01:00
|
|
|
volume: ObjRef<EncryptedVolume?>
|
2022-09-30 21:22:37 +02:00
|
|
|
): Boolean {
|
2023-03-07 23:25:17 +01:00
|
|
|
return when (val result = nativeCreateVolume(
|
|
|
|
root_cipher_dir,
|
|
|
|
password,
|
|
|
|
plainTextNames,
|
|
|
|
xchacha,
|
|
|
|
ScryptDefaultLogN,
|
|
|
|
VOLUME_CREATOR,
|
|
|
|
returnedHash,
|
|
|
|
)) {
|
|
|
|
-1 -> {
|
|
|
|
Log.e("gocryptfs", "Failed to open volume after creation")
|
|
|
|
true
|
|
|
|
}
|
|
|
|
-2 -> false
|
|
|
|
else -> {
|
|
|
|
volume.value = GocryptfsVolume(result)
|
|
|
|
true
|
|
|
|
}
|
2022-09-30 21:22:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-18 21:13:16 +02:00
|
|
|
fun init(root_cipher_dir: String, password: ByteArray?, givenHash: ByteArray?, returnedHash: ByteArray?): GocryptfsVolume? {
|
|
|
|
val sessionId = nativeInit(root_cipher_dir, password, givenHash, returnedHash)
|
|
|
|
return if (sessionId == -1) {
|
|
|
|
null
|
|
|
|
} else {
|
|
|
|
GocryptfsVolume(sessionId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
init {
|
|
|
|
System.loadLibrary("gocryptfs_jni")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(parcel: Parcel) : this(parcel.readInt())
|
|
|
|
|
|
|
|
override fun openFile(path: String): Long {
|
2022-09-30 21:22:37 +02:00
|
|
|
return native_open_write_mode(sessionID, path, 384).toLong() // 0600
|
2022-06-18 21:13:16 +02:00
|
|
|
}
|
|
|
|
|
2022-09-23 20:58:16 +02:00
|
|
|
override fun read(fileHandle: Long, fileOffset: Long, buffer: ByteArray, dstOffset: Long, length: Long): Int {
|
|
|
|
return native_read_file(sessionID, fileHandle.toInt(), fileOffset, buffer, dstOffset, min(length.toInt(), MAX_KERNEL_WRITE))
|
2022-06-18 21:13:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun readDir(path: String): MutableList<ExplorerElement>? {
|
|
|
|
return native_list_dir(sessionID, path)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getAttr(path: String): Stat? {
|
|
|
|
return native_get_attr(sessionID, path)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun writeToParcel(parcel: Parcel, flags: Int) = with(parcel) {
|
|
|
|
writeByte(GOCRYPTFS_VOLUME_TYPE)
|
|
|
|
writeInt(sessionID)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun close() {
|
|
|
|
native_close(sessionID)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun isClosed(): Boolean {
|
|
|
|
return native_is_closed(sessionID)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun mkdir(path: String): Boolean {
|
2022-09-30 21:22:37 +02:00
|
|
|
return native_mkdir(sessionID, path, 448) // 0700
|
2022-06-18 21:13:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun rmdir(path: String): Boolean {
|
|
|
|
return native_rmdir(sessionID, path)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun closeFile(fileHandle: Long): Boolean {
|
|
|
|
native_close_file(sessionID, fileHandle.toInt())
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2022-09-23 20:58:16 +02:00
|
|
|
override fun write(fileHandle: Long, fileOffset: Long, buffer: ByteArray, srcOffset: Long, length: Long): Int {
|
|
|
|
return native_write_file(sessionID, fileHandle.toInt(), fileOffset, buffer, srcOffset, min(length.toInt(), MAX_KERNEL_WRITE))
|
2022-06-18 21:13:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun truncate(path: String, size: Long): Boolean {
|
|
|
|
return native_truncate(sessionID, path, size)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun deleteFile(path: String): Boolean {
|
|
|
|
return native_remove_file(sessionID, path)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun rename(srcPath: String, dstPath: String): Boolean {
|
|
|
|
return native_rename(sessionID, srcPath, dstPath)
|
|
|
|
}
|
|
|
|
}
|