diff --git a/nhterm/build.gradle b/nhterm/build.gradle index 810c8da..8963a4b 100644 --- a/nhterm/build.gradle +++ b/nhterm/build.gradle @@ -15,7 +15,7 @@ android { externalNativeBuild { cmake { cppFlags "-std=c++11" - abiFilters 'arm64-v8a', 'armeabi-v7a' + abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64' } } signingConfigs { @@ -80,6 +80,10 @@ dependencies { implementation 'androidx.preference:preference:1.1.0' implementation "androidx.compose.material:material:1.0.0" + // Backports for lower api levels + implementation 'com.llamalab.safs:safs-core:0.2.0' + implementation 'me.zhanghai.android.retrofile:library:1.1.1' + implementation project(':chrome-tabs') implementation project(':NeoLang') implementation project(':NeoTermBridge') diff --git a/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/comp.kt b/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/comp.kt index a75b45b..1ecef8f 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/comp.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/comp.kt @@ -1,6 +1,7 @@ package com.offsec.nhterm.component.colorscheme import android.content.Context +import android.os.Build import io.neolang.frontend.ConfigVisitor import com.offsec.nhterm.App import com.offsec.nhterm.R @@ -18,7 +19,7 @@ import java.nio.file.Files class ColorSchemeComponent : ConfigFileBasedComponent(NeoTermPath.COLORS_PATH) { companion object { fun colorFile(colorName: String): File { - return File("${NeoTermPath.COLORS_PATH}/$colorName.nl") + return File("${NeoTermPath.COLORS_PATH}/$colorName.nl") } } @@ -49,18 +50,22 @@ class ColorSchemeComponent : ConfigFileBasedComponent(NeoTermPat fun reloadColorSchemes(): Boolean { colors.clear() - File(baseDir) - .listFiles(NEOLANG_FILTER) - .mapNotNull { this.loadConfigure(it) } - .forEach { - colors.put(it.colorName, it) - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + File(baseDir) + .listFiles(NEOLANG_FILTER) + .mapNotNull { this.loadConfigure(it) } + .forEach { + colors.put(it.colorName, it) + } - if (colors.containsKey(DefaultColorScheme.colorName)) { - DEFAULT_COLOR = colors[DefaultColorScheme.colorName]!! - return true + if (colors.containsKey(DefaultColorScheme.colorName)) { + DEFAULT_COLOR = colors[DefaultColorScheme.colorName]!! + return true + } + return false + } else { + return false } - return false } fun applyColorScheme(view: TerminalView?, extraKeysView: ExtraKeysView?, colorScheme: NeoColorScheme?) { @@ -112,7 +117,11 @@ class ColorSchemeComponent : ConfigFileBasedComponent(NeoTermPat val content = component.newGenerator(colorScheme).generateCode(colorScheme) kotlin.runCatching { - Files.write(colorFile.toPath(), content.toByteArray()) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Files.write(colorFile.toPath(), content.toByteArray()) + } else { + return + } }.onFailure { throw RuntimeException("Failed to save file ${colorFile.absolutePath}") } diff --git a/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/data.kt b/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/data.kt index 113e660..fb20665 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/data.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/component/colorscheme/data.kt @@ -1,5 +1,7 @@ package com.offsec.nhterm.component.colorscheme +import android.os.Build +import com.offsec.nhterm.R import io.neolang.frontend.ConfigVisitor import com.offsec.nhterm.backend.TerminalColorScheme import com.offsec.nhterm.backend.TerminalColors @@ -139,12 +141,16 @@ open class NeoColorScheme : CodeGenObject, ConfigFileBasedObject { if (session != null && session.emulator != null) { session.emulator.setColorScheme(scheme) } - view.setBackgroundColor(TerminalColors.parse(backgroundColor)) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + view.setBackgroundColor(TerminalColors.parse(backgroundColor)) + } } if (extraKeysView != null) { - extraKeysView.setBackgroundColor(TerminalColors.parse(backgroundColor)) - extraKeysView.setTextColor(TerminalColors.parse(foregroundColor)) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + extraKeysView.setBackgroundColor(TerminalColors.parse(backgroundColor)) + extraKeysView.setTextColor(TerminalColors.parse(foregroundColor)) + } } } diff --git a/nhterm/src/main/java/com/offsec/nhterm/component/config/comp.kt b/nhterm/src/main/java/com/offsec/nhterm/component/config/comp.kt index 7c68e5c..fc96042 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/component/config/comp.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/component/config/comp.kt @@ -2,6 +2,7 @@ package com.offsec.nhterm.component.config import android.content.Context import android.content.SharedPreferences +import android.os.Build import android.preference.PreferenceManager import android.system.ErrnoException import android.system.Os @@ -49,14 +50,17 @@ open class NeoConfigureFile(val configureFile: File) { fun getVisitor() = configVisitor ?: throw IllegalStateException("Configure file not loaded or parse failed.") - open fun parseConfigure() = kotlin.runCatching { - val programCode = String(Files.readAllBytes(configureFile.toPath())) - configParser.setInputSource(programCode) - val ast = configParser.parse() - val astVisitor = ast.visit().getVisitor(ConfigVisitor::class.java) ?: return false - astVisitor.start() - configVisitor = astVisitor.getCallback() + open fun parseConfigure() = kotlin.runCatching { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val programCode = String(Files.readAllBytes(configureFile.toPath())) + configParser.setInputSource(programCode) + + val ast = configParser.parse() + val astVisitor = ast.visit().getVisitor(ConfigVisitor::class.java) ?: return false + astVisitor.start() + configVisitor = astVisitor.getCallback() + } }.isSuccess } @@ -85,14 +89,16 @@ object NeoPreference { MIN_FONT_SIZE = (4f * dipInPixels).toInt() MAX_FONT_SIZE = 256 - // load apt source - val sourceFile = File(NeoTermPath.SOURCE_FILE) - kotlin.runCatching { - Files.readAllBytes(sourceFile.toPath())?.let { - val source = String(it).trim().trimEnd() - val array = source.split(" ") - if (array.size >= 2 && array[0] == "deb") { - store(R.string.key_package_source, array[1]) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // load apt source + val sourceFile = File(NeoTermPath.SOURCE_FILE) + kotlin.runCatching { + Files.readAllBytes(sourceFile.toPath())?.let { + val source = String(it).trim().trimEnd() + val array = source.split(" ") + if (array.size >= 2 && array[0] == "deb") { + store(R.string.key_package_source, array[1]) + } } } } diff --git a/nhterm/src/main/java/com/offsec/nhterm/component/extrakey/comp.kt b/nhterm/src/main/java/com/offsec/nhterm/component/extrakey/comp.kt index 6b49bc3..118938f 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/component/extrakey/comp.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/component/extrakey/comp.kt @@ -1,6 +1,7 @@ package com.offsec.nhterm.component.extrakey import android.content.Context +import android.os.Build import io.neolang.frontend.ConfigVisitor import com.offsec.nhterm.App import com.offsec.nhterm.component.ConfigFileBasedComponent @@ -57,12 +58,14 @@ class ExtraKeyComponent : ConfigFileBasedComponent(NeoTermPath.EKS_ private fun reloadExtraKeyConfig() { extraKeys.clear() - File(baseDir) - .listFiles(NEOLANG_FILTER) - .filter { it.absolutePath != NeoTermPath.EKS_DEFAULT_FILE } - .mapNotNull { this.loadConfigure(it) } - .forEach { - registerShortcutKeys(it) - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + File(baseDir) + .listFiles(NEOLANG_FILTER) + .filter { it.absolutePath != NeoTermPath.EKS_DEFAULT_FILE } + .mapNotNull { this.loadConfigure(it) } + .forEach { + registerShortcutKeys(it) + } + } } } diff --git a/nhterm/src/main/java/com/offsec/nhterm/component/userscript/comp.kt b/nhterm/src/main/java/com/offsec/nhterm/component/userscript/comp.kt index 6bbdd2b..874c4e1 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/component/userscript/comp.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/component/userscript/comp.kt @@ -16,8 +16,8 @@ class UserScript(val scriptFile: File) class UserScriptComponent : NeoComponent { var userScripts = listOf() var binFiles = listOf() - private val scriptDir = File(NeoTermPath.USER_SCRIPT_PATH) - private val binDir = File(NeoTermPath.BIN_PATH) + val scriptDir = File(NeoTermPath.USER_SCRIPT_PATH) + val binDir = File(NeoTermPath.BIN_PATH) override fun onServiceInit() = checkForFiles() diff --git a/nhterm/src/main/java/com/offsec/nhterm/frontend/floating/dialog.kt b/nhterm/src/main/java/com/offsec/nhterm/frontend/floating/dialog.kt index f1ec729..99e21a9 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/frontend/floating/dialog.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/frontend/floating/dialog.kt @@ -6,6 +6,7 @@ import android.content.DialogInterface import android.view.LayoutInflater import android.view.View import androidx.appcompat.app.AlertDialog +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.offsec.nhterm.R import com.offsec.nhterm.backend.TerminalSession import com.offsec.nhterm.component.config.DefaultValues.initialCommand @@ -42,7 +43,7 @@ class TerminalDialog(val context: Context) { terminalSession?.finishIfRunning() } - dialog = AlertDialog.Builder(context) + dialog = MaterialAlertDialogBuilder(context, R.style.DialogStyle) .setView(termWindowView.rootView) .setOnCancelListener { terminalSession?.finishIfRunning() diff --git a/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/ExtraKeysView.kt b/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/ExtraKeysView.kt index 5f76d40..469528f 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/ExtraKeysView.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/ExtraKeysView.kt @@ -2,6 +2,7 @@ package com.offsec.nhterm.frontend.session.view.extrakey import android.content.Context import android.graphics.Typeface +import android.os.Build import android.os.VibrationEffect import android.os.Vibrator import android.util.AttributeSet @@ -29,6 +30,7 @@ class ExtraKeysView(context: Context, attrs: AttributeSet) : LinearLayout(contex private val ARROW_DOWN = ArrowButton(IExtraButton.KEY_ARROW_DOWN) private val ARROW_LEFT = ArrowButton(IExtraButton.KEY_ARROW_LEFT) private val ARROW_RIGHT = ArrowButton(IExtraButton.KEY_ARROW_RIGHT) + private val SLASH = ControlButton(IExtraButton.KEY_SLASH) private val TOGGLE_IME = object : ControlButton(KEY_TOGGLE_IME) { override fun onClick(view: View) { EventBus.getDefault().post(ToggleImeEvent()) @@ -55,6 +57,7 @@ class ExtraKeysView(context: Context, attrs: AttributeSet) : LinearLayout(contex private val SHIFT = StatedControlButton(IExtraButton.KEY_SHIFT) private var buttonPanelExpanded = false + private val EXPAND_BUTTONS = object : ControlButton(IExtraButton.KEY_SHOW_ALL_BUTTONS) { override fun onClick(view: View) { expandButtonPanel() @@ -241,7 +244,12 @@ class ExtraKeysView(context: Context, attrs: AttributeSet) : LinearLayout(contex addBuiltinKey(HOME) addBuiltinKey(ARROW_UP) addBuiltinKey(END) - addBuiltinKey(EXPAND_BUTTONS) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + addBuiltinKey(EXPAND_BUTTONS) + } else { + addBuiltinKey(SLASH) + } } private fun calculateButtonWidth(): Int { diff --git a/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/buttons.kt b/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/buttons.kt index 92782a0..edf8f17 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/buttons.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/frontend/session/view/extrakey/buttons.kt @@ -50,6 +50,7 @@ abstract class IExtraButton : View.OnClickListener { const val KEY_ARROW_LEFT_TEXT = "Left" const val KEY_ARROW_RIGHT_TEXT = "Right" const val KEY_SHOW_ALL_BUTTONS = "···" + const val KEY_SLASH = "/" const val KEY_TOGGLE_IME = "⌨" const val KEY_ARROW_UP = "▲" @@ -100,6 +101,7 @@ abstract class IExtraButton : View.OnClickListener { KEY_END -> keyCode = KeyEvent.KEYCODE_MOVE_END KEY_FN -> keyCode = KeyEvent.KEYCODE_FUNCTION KEY_SHIFT -> keyCode = KeyEvent.KEYCODE_SHIFT_LEFT + KEY_SLASH -> keyCode = KeyEvent.KEYCODE_SLASH "―" -> chars = "-" // Function keys diff --git a/nhterm/src/main/java/com/offsec/nhterm/ui/pm/PackageManagerActivity.kt b/nhterm/src/main/java/com/offsec/nhterm/ui/pm/PackageManagerActivity.kt index d045f08..e9c8233 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/ui/pm/PackageManagerActivity.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/ui/pm/PackageManagerActivity.kt @@ -15,6 +15,7 @@ import androidx.appcompat.widget.Toolbar import androidx.core.view.MenuItemCompat import androidx.recyclerview.widget.LinearLayoutManager import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.offsec.nhterm.R import com.offsec.nhterm.component.ComponentManager import com.offsec.nhterm.component.config.NeoPreference @@ -51,7 +52,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen recyclerView.setHasFixedSize(true) adapter = PackageAdapter(this, comparator, object : PackageAdapter.Listener { override fun onModelClicked(model: PackageModel) { - AlertDialog.Builder(this@PackageManagerActivity) + MaterialAlertDialogBuilder(this@PackageManagerActivity, R.style.DialogStyle) .setTitle(model.packageInfo.packageName) .setMessage(model.getPackageDetails(this@PackageManagerActivity)) .setPositiveButton(R.string.install) { _, _ -> @@ -121,7 +122,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen val repoEditor = view.findViewById(R.id.dialog_edit_text2_editor) repoEditor.setText("kali-rolling main") - AlertDialog.Builder(this) + MaterialAlertDialogBuilder(this, R.style.DialogStyle) .setTitle(R.string.pref_package_source) .setView(view) .setNegativeButton(android.R.string.no, null) diff --git a/nhterm/src/main/java/com/offsec/nhterm/ui/settings/BasePreferenceActivity.kt b/nhterm/src/main/java/com/offsec/nhterm/ui/settings/BasePreferenceActivity.kt index bfb6a82..899aa9b 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/ui/settings/BasePreferenceActivity.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/ui/settings/BasePreferenceActivity.kt @@ -16,14 +16,20 @@ package com.offsec.nhterm.ui.settings import android.content.res.Configuration +import android.content.res.Resources.Theme import android.os.Bundle import android.preference.PreferenceActivity import android.view.MenuInflater import android.view.View import android.view.ViewGroup import androidx.annotation.LayoutRes +import androidx.annotation.StyleRes import androidx.appcompat.app.ActionBar import androidx.appcompat.app.AppCompatDelegate +import androidx.core.content.res.ResourcesCompat.ThemeCompat +import androidx.preference.Preference +import androidx.preference.PreferenceScreen +import com.offsec.nhterm.R /** * A [android.preference.PreferenceActivity] which implements and proxies the necessary calls @@ -39,6 +45,7 @@ abstract class BasePreferenceActivity : PreferenceActivity() { override fun onCreate(savedInstanceState: Bundle?) { delegate.installViewFactory() delegate.onCreate(savedInstanceState) + delegate.setTheme(R.style.AppTheme) super.onCreate(savedInstanceState) } diff --git a/nhterm/src/main/java/com/offsec/nhterm/ui/settings/GeneralSettingsActivity.kt b/nhterm/src/main/java/com/offsec/nhterm/ui/settings/GeneralSettingsActivity.kt index 01b3c1d..81ac909 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/ui/settings/GeneralSettingsActivity.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/ui/settings/GeneralSettingsActivity.kt @@ -1,7 +1,9 @@ package com.offsec.nhterm.ui.settings import android.os.Bundle +import android.preference.PreferenceActivity import android.view.MenuItem +import androidx.preference.Preference import com.offsec.nhterm.R /** @@ -16,7 +18,7 @@ class GeneralSettingsActivity : BasePreferenceActivity() { addPreferencesFromResource(R.xml.setting_general) } - override fun onBuildHeaders(target: MutableList
?) { + override fun onBuildHeaders(target: MutableList?) { } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/nhterm/src/main/java/com/offsec/nhterm/ui/settings/SettingActivity.kt b/nhterm/src/main/java/com/offsec/nhterm/ui/settings/SettingActivity.kt index 299da40..f78c555 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/ui/settings/SettingActivity.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/ui/settings/SettingActivity.kt @@ -1,5 +1,6 @@ package com.offsec.nhterm.ui.settings +import android.os.Build import android.os.Bundle import android.view.MenuItem import com.offsec.nhterm.R @@ -13,7 +14,11 @@ class SettingActivity : BasePreferenceActivity() { super.onCreate(savedInstanceState) supportActionBar?.title = getString(R.string.settings) supportActionBar?.setDisplayHomeAsUpEnabled(true) - addPreferencesFromResource(R.xml.settings_main) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + addPreferencesFromResource(R.xml.settings_main) + } else { + addPreferencesFromResource(R.xml.older_settings_main) + } } override fun onBuildHeaders(target: MutableList
?) { diff --git a/nhterm/src/main/java/com/offsec/nhterm/ui/term/NeoTermActivity.kt b/nhterm/src/main/java/com/offsec/nhterm/ui/term/NeoTermActivity.kt index d9dd2a4..ffc17b2 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/ui/term/NeoTermActivity.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/ui/term/NeoTermActivity.kt @@ -143,7 +143,11 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference } override fun onCreateOptionsMenu(menu: Menu?): Boolean { - menuInflater.inflate(R.menu.menu_main, menu) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + menuInflater.inflate(R.menu.menu_main, menu) + } else { + menuInflater.inflate(R.menu.older_menu_main, menu) + } TabSwitcher.setupWithMenu( tabSwitcher, toolbar.menu, @@ -170,15 +174,19 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference true } R.id.menu_item_new_session -> { - addNewNetHunterSession("KALI LINUX") + addNewNetHunterSession("Kali Shell") true } - R.id.menu_item_new_system_session -> { - addNewAndroidSession("Android") + R.id.menu_item_new_emergency_session -> { + addNewEmergencySession("Emergency Shell") + true + } + R.id.menu_item_new_bash_session -> { + addNewAndroidSession("Android Shell") true } R.id.menu_item_new_root_session -> { - addNewRootSession("Android SU") + addNewRootSession("Root Shell") true } R.id.menu_item_package_settings -> { @@ -489,11 +497,11 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference } private fun addNewSession() { - addNewNetHunterSession("KALI LINUX") + addNewNetHunterSession("Kali Shell") } private fun addNewSession(sessionName: String?, systemShell: Boolean, animation: Animation) { - addNewNetHunterSession("KALI LINUX") + addNewNetHunterSession("Kali Shell") } private fun addNewSessionWithProfile(profile: ShellProfile) { @@ -519,7 +527,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference .profile(profile) val session = termService!!.createTermSession(parameter) - session.mSessionName = sessionName ?: generateSessionName("Kali Linux") + session.mSessionName = sessionName ?: generateSessionName("Kali Shell") val tab = createTab(session.mSessionName) as TermTab tab.termData.initializeSessionWith(session, sessionCallback, viewClient) @@ -528,6 +536,27 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference switchToSession(tab) } + @SuppressLint("SdCardPath") + private fun addNewEmergencySession(sessionName: String?) { + val sessionCallback = TermSessionCallback() + val viewClient = TermViewClient(this) + + val parameter = ShellParameter() + .callback(sessionCallback) + .executablePath("/system/bin/sh") + .systemShell(true) + + val session = termService!!.createTermSession(parameter) + + session.mSessionName = sessionName ?: generateSessionName("Emergency Shell") + + val tab = createTab(session.mSessionName) as TermTab + tab.termData.initializeSessionWith(session, sessionCallback, viewClient) + + addNewTab(tab, createRevealAnimation()) + switchToSession(tab) + } + @SuppressLint("SdCardPath") private fun addNewAndroidSession(sessionName: String?) { val sessionCallback = TermSessionCallback() @@ -540,7 +569,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference val session = termService!!.createTermSession(parameter) - session.mSessionName = sessionName ?: generateSessionName("Android") + session.mSessionName = sessionName ?: generateSessionName("Android Shell") val tab = createTab(session.mSessionName) as TermTab tab.termData.initializeSessionWith(session, sessionCallback, viewClient) @@ -558,7 +587,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference .executablePath("/data/data/com.offsec.nhterm/files/usr/bin/kali") val session = termService!!.createTermSession(parameter) - session.mSessionName = sessionName ?: generateSessionName("KALI LINUX") + session.mSessionName = sessionName ?: generateSessionName("Kali Shell") val tab = createTab(session.mSessionName) as TermTab tab.termData.initializeSessionWith(session, sessionCallback, viewClient) @@ -580,7 +609,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference val session = termService!!.createTermSession(parameter) generateSessionName("Android") - session.mSessionName = sessionName ?: generateSessionName("ANDROID SU") + session.mSessionName = sessionName ?: generateSessionName("Root Shell") val tab = createTab(session.mSessionName) as TermTab tab.termData.initializeSessionWith(session, sessionCallback, viewClient) @@ -699,7 +728,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference } private fun createXTab(tabTitle: String?): Tab { - return postTabCreated(XSessionTab(tabTitle ?: "Kali Linux")) + return postTabCreated(XSessionTab(tabTitle ?: "Kali Shell")) } private fun postTabCreated(tab: T): T { diff --git a/nhterm/src/main/java/com/offsec/nhterm/ui/term/tabs.kt b/nhterm/src/main/java/com/offsec/nhterm/ui/term/tabs.kt index 3572044..9883375 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/ui/term/tabs.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/ui/term/tabs.kt @@ -3,6 +3,7 @@ package com.offsec.nhterm.ui.term import android.content.Context import android.content.res.Configuration import android.graphics.Rect +import android.os.Build import android.os.Bundle import android.util.Log import android.view.LayoutInflater @@ -60,10 +61,12 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { Terminals.setupExtraKeysView(extraKeysView) val colorSchemeManager = ComponentManager.getComponent() - colorSchemeManager.applyColorScheme( - terminalView, extraKeysView, - colorSchemeManager.getCurrentColorScheme() - ) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + colorSchemeManager.applyColorScheme( + terminalView, extraKeysView, + colorSchemeManager.getCurrentColorScheme() + ) + } view } diff --git a/nhterm/src/main/java/com/offsec/nhterm/utils/utils.kt b/nhterm/src/main/java/com/offsec/nhterm/utils/utils.kt index 6487407..ac087da 100644 --- a/nhterm/src/main/java/com/offsec/nhterm/utils/utils.kt +++ b/nhterm/src/main/java/com/offsec/nhterm/utils/utils.kt @@ -3,6 +3,7 @@ package com.offsec.nhterm.utils import android.content.ContentUris import android.content.Context import android.net.Uri +import android.os.Build import android.os.Environment import android.provider.DocumentsContract import android.provider.MediaStore @@ -37,17 +38,33 @@ fun Long.formatSizeInKB(): String { } fun Context.extractAssetsDir(assetDir: String, extractDir: String) = kotlin.runCatching { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val targetDir = Paths.get(extractDir) - Files.createDirectories(targetDir) - val assets = this.assets - assets.list(assetDir)?.let { - it.map { targetDir.resolve(it) } - .takeWhile { !Files.exists(it) } - .forEach { targetPath -> - assets.open("$assetDir/${targetPath.fileName}").use { - Files.copy(it, targetPath) + Paths.get(extractDir) + Files.createDirectories(targetDir) + val assets = this.assets + assets.list(assetDir)?.let { + it.map { targetDir.resolve(it) } + .takeWhile { !Files.exists(it) } + .forEach { targetPath -> + assets.open("$assetDir/${targetPath.fileName}").use { + Files.copy(it, targetPath) + } } - } + } + } else { + val targetDir = com.llamalab.safs.Paths.get(extractDir) + com.llamalab.safs.Files.createDirectories(targetDir) + val assets = this.assets + assets.list(assetDir)?.let { + it.map { targetDir.resolve(it) } + .takeWhile { !com.llamalab.safs.Files.exists(it) } + .forEach { targetPath -> + assets.open("$assetDir/${targetPath.fileName}").use { + com.llamalab.safs.Files.copy(it, targetPath) + } + } + } } } diff --git a/nhterm/src/main/res/layout/ui_main.xml b/nhterm/src/main/res/layout/ui_main.xml index 11ceb02..663e088 100644 --- a/nhterm/src/main/res/layout/ui_main.xml +++ b/nhterm/src/main/res/layout/ui_main.xml @@ -6,7 +6,7 @@ android:background="@color/terminal_background" android:orientation="vertical"> - + + + + + + + + + + + + + + + + + + + diff --git a/nhterm/src/main/res/values/strings.xml b/nhterm/src/main/res/values/strings.xml index 1fb22d8..399d155 100644 --- a/nhterm/src/main/res/values/strings.xml +++ b/nhterm/src/main/res/values/strings.xml @@ -8,7 +8,8 @@ Toggle Tabs New Session New Session… - New System Shell + New Emergency Shell + New Bash Shell New Root Shell %d session(s) (Wake Locked) @@ -47,6 +48,7 @@ Package Settings Source, Updates, Upgrades Font, ColorScheme + Disabled as of no required functions available by old android api Customization Toggle Keyboard @@ -61,7 +63,7 @@ APT source changed, you may get it updated by executing: apt update Done Install - Package: %s\nVersion: %s\nDepends: %s\nInstalled Size: %s\nDescription: %s\nHome + Package: %s\n\nVersion: %s\n\nDepends: %s\n\nInstalled Size: %s\n\nDescription: %s\n\nHome Page: %s Package list is empty, please check your source. diff --git a/nhterm/src/main/res/values/styles.xml b/nhterm/src/main/res/values/styles.xml index 4799fc9..778e62e 100644 --- a/nhterm/src/main/res/values/styles.xml +++ b/nhterm/src/main/res/values/styles.xml @@ -9,6 +9,8 @@ @style/AppTheme.ActionBar @style/AppTheme.ActionBar + + @style/DialogStyleCompat - +