Add JSch (SFTP) debug logging
-App Settings->Log-File for Debugging->SFTP debug logging -Logs to android log (logcat) if log file is not enabled -Logs to Kp2a log file if it is enabled -Logs are tagged as "KP2AJFS[JSch]" -When enabled, logs ALL levels (DEBUG+). NOTE: Sensitive SSH connection information may be logged!!
This commit is contained in:
@@ -58,12 +58,12 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string LogFilename
|
public static string LogFilename
|
||||||
{
|
{
|
||||||
get { return Application.Context.FilesDir.CanonicalPath +"/keepass2android.log"; }
|
get { return Application.Context.FilesDir.CanonicalPath +"/keepass2android.log"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool LogToFile
|
public static bool LogToFile
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package keepass2android.javafilestorage;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.jcraft.jsch.Logger;
|
||||||
|
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Kp2aJSchLogger implements Logger {
|
||||||
|
|
||||||
|
private static final String PREFIX = "KP2AJFS[JSch]";
|
||||||
|
|
||||||
|
private interface ILogger {
|
||||||
|
void log(String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class LogEntry {
|
||||||
|
private final String levelTag;
|
||||||
|
private final ILogger logger;
|
||||||
|
|
||||||
|
LogEntry(String levelTag, ILogger logger) {
|
||||||
|
this.levelTag = levelTag;
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static final ILogger DEBUG = msg -> Log.d(PREFIX, msg);
|
||||||
|
private static final LogEntry DEBUG_ENTRY = new LogEntry("D", DEBUG);
|
||||||
|
private static final ILogger ERROR = msg -> Log.e(PREFIX, msg);
|
||||||
|
private static final LogEntry DEFAULT_ENTRY = DEBUG_ENTRY;
|
||||||
|
|
||||||
|
private static final Map<Integer, LogEntry> loggers = Map.of(
|
||||||
|
Logger.DEBUG, DEBUG_ENTRY,
|
||||||
|
Logger.INFO, new LogEntry("I", msg -> Log.i(PREFIX, msg)),
|
||||||
|
Logger.WARN, new LogEntry("W", msg -> Log.w(PREFIX, msg)),
|
||||||
|
Logger.ERROR, new LogEntry("E", ERROR),
|
||||||
|
Logger.FATAL, new LogEntry("F", msg -> Log.wtf(PREFIX, msg))
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private final String logFilename;
|
||||||
|
|
||||||
|
public Kp2aJSchLogger(String logFilename) {
|
||||||
|
this.logFilename = logFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(int level) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(int level, String message) {
|
||||||
|
if (isEnabled(level))
|
||||||
|
getLogger(level).log(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ILogger getLogger(int level) {
|
||||||
|
LogEntry entry = loggers.get(level);
|
||||||
|
if (entry == null)
|
||||||
|
entry = DEFAULT_ENTRY;
|
||||||
|
|
||||||
|
ILogger logger;
|
||||||
|
if (logFilename != null) {
|
||||||
|
logger = createFileLogger(entry);
|
||||||
|
} else {
|
||||||
|
logger = entry.logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ILogger createFileLogger(LogEntry entry) {
|
||||||
|
try {
|
||||||
|
final PrintWriter p = new PrintWriter(new FileWriter(logFilename, true));
|
||||||
|
return msg -> {
|
||||||
|
try {
|
||||||
|
String fullMsg = String.join(" ", entry.levelTag, PREFIX, msg);
|
||||||
|
p.println(fullMsg);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ERROR.log(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
p.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (Exception e) {
|
||||||
|
ERROR.log(e.getMessage());
|
||||||
|
return entry.logger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -375,6 +375,14 @@ public class SftpStorage extends JavaFileStorageBase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setJschLogging(boolean enabled, String logFilename) {
|
||||||
|
if (enabled) {
|
||||||
|
JSch.setLogger(new Kp2aJSchLogger(logFilename));
|
||||||
|
} else {
|
||||||
|
JSch.setLogger(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String createKeyPair(String key_filename) throws JSchException, IOException {
|
private String createKeyPair(String key_filename) throws JSchException, IOException {
|
||||||
String public_key_filename = key_filename + ".pub";
|
String public_key_filename = key_filename + ".pub";
|
||||||
File file = new File(key_filename);
|
File file = new File(key_filename);
|
||||||
|
|||||||
@@ -98,6 +98,7 @@
|
|||||||
<string name="TrayTotp_SeedField_key">TrayTotp_SeedField_key</string>
|
<string name="TrayTotp_SeedField_key">TrayTotp_SeedField_key</string>
|
||||||
<string name="TrayTotp_prefs_key">TrayTotp_prefs_key</string>
|
<string name="TrayTotp_prefs_key">TrayTotp_prefs_key</string>
|
||||||
<string name="DebugLog_key">DebugLog_key</string>
|
<string name="DebugLog_key">DebugLog_key</string>
|
||||||
|
<string name="JSchDebug_key">JSchDebug_key</string>
|
||||||
<string name="DebugLog_prefs_key">DebugLog_prefs_key</string>
|
<string name="DebugLog_prefs_key">DebugLog_prefs_key</string>
|
||||||
<string name="DebugLog_send_key">DebugLog_send</string>
|
<string name="DebugLog_send_key">DebugLog_send</string>
|
||||||
<string name="AutofillDisabledQueriesPreference_key">AutofillDisabledQueriesPreference_key</string>
|
<string name="AutofillDisabledQueriesPreference_key">AutofillDisabledQueriesPreference_key</string>
|
||||||
|
|||||||
@@ -680,6 +680,7 @@
|
|||||||
<string name="TrayTotp_prefs">TrayTotp</string>
|
<string name="TrayTotp_prefs">TrayTotp</string>
|
||||||
<string name="DebugLog_prefs_prefs">Log-File for Debugging</string>
|
<string name="DebugLog_prefs_prefs">Log-File for Debugging</string>
|
||||||
<string name="DebugLog_title">Use log file</string>
|
<string name="DebugLog_title">Use log file</string>
|
||||||
|
<string name="JSchDebug_title">SFTP debug logging</string>
|
||||||
<string name="DebugLog_summary">Write app output to a local log file</string>
|
<string name="DebugLog_summary">Write app output to a local log file</string>
|
||||||
<string name="DebugLog_send">Send debug log...</string>
|
<string name="DebugLog_send">Send debug log...</string>
|
||||||
|
|
||||||
|
|||||||
@@ -670,10 +670,17 @@
|
|||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:title="@string/DebugLog_title"
|
android:title="@string/DebugLog_title"
|
||||||
android:key="@string/DebugLog_key" />
|
android:key="@string/DebugLog_key" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:title="@string/DebugLog_send"
|
android:title="@string/DebugLog_send"
|
||||||
android:key="@string/DebugLog_send_key" />
|
android:key="@string/DebugLog_send_key" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:enabled="true"
|
||||||
|
android:persistent="true"
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:title="@string/JSchDebug_title"
|
||||||
|
android:key="@string/JSchDebug_key" />
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
FindPreference(GetString(Resource.String.DebugLog_key)).PreferenceChange += OnDebugLogChanged;
|
FindPreference(GetString(Resource.String.DebugLog_key)).PreferenceChange += OnDebugLogChanged;
|
||||||
FindPreference(GetString(Resource.String.DebugLog_send_key)).PreferenceClick += OnSendDebug;
|
FindPreference(GetString(Resource.String.DebugLog_send_key)).PreferenceClick += OnSendDebug;
|
||||||
|
FindPreference(GetString(Resource.String.JSchDebug_key)).PreferenceChange += OnJSchDebugChanged;
|
||||||
|
|
||||||
HashSet<string> supportedLocales = new HashSet<string>() { "en", "af", "ar", "az", "be", "bg", "ca", "cs", "da", "de", "el", "es", "eu", "fa", "fi", "fr", "gl", "he", "hr", "hu", "id", "in", "it", "iw", "ja", "ko", "ml", "nb", "nl", "nn", "no", "pl", "pt", "ro", "ru", "si", "sk", "sl", "sr", "sv", "tr", "uk", "vi", "zh" };
|
HashSet<string> supportedLocales = new HashSet<string>() { "en", "af", "ar", "az", "be", "bg", "ca", "cs", "da", "de", "el", "es", "eu", "fa", "fi", "fr", "gl", "he", "hr", "hu", "id", "in", "it", "iw", "ja", "ko", "ml", "nb", "nl", "nn", "no", "pl", "pt", "ro", "ru", "si", "sk", "sl", "sr", "sv", "tr", "uk", "vi", "zh" };
|
||||||
|
|
||||||
@@ -417,16 +418,31 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void OnDebugLogChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
private void OnDebugLogChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
||||||
{
|
{
|
||||||
if ((bool)e.NewValue)
|
if ((bool)e.NewValue)
|
||||||
{
|
Kp2aLog.CreateLogFile();
|
||||||
Kp2aLog.CreateLogFile();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
Kp2aLog.FinishLogFile();
|
||||||
Kp2aLog.FinishLogFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
bool jschLogEnable = PreferenceManager.GetDefaultSharedPreferences(Application.Context)
|
||||||
|
.GetBoolean(Application.Context.GetString(Resource.String.JSchDebug_key), false);
|
||||||
|
SetJSchLogging(jschLogEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnJSchDebugChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
||||||
|
{
|
||||||
|
SetJSchLogging((bool)e.NewValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetJSchLogging(bool enabled)
|
||||||
|
{
|
||||||
|
var sftpStorage = new Keepass2android.Javafilestorage.SftpStorage(Context);
|
||||||
|
string? logFilename = null;
|
||||||
|
if (Kp2aLog.LogToFile)
|
||||||
|
{
|
||||||
|
logFilename = Kp2aLog.LogFilename;
|
||||||
|
}
|
||||||
|
sftpStorage.SetJschLogging(enabled, logFilename);
|
||||||
|
}
|
||||||
|
|
||||||
private void AlgorithmPrefChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
|
private void AlgorithmPrefChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user