Skip to content

Commit

Permalink
move TOTP button on keyboard to third position (after User/Pwd) and d…
Browse files Browse the repository at this point in the history
…isable TOTP "internal fields"

closes #1341
closes #2394
closes #1844
  • Loading branch information
PhilippC committed Jan 4, 2024
1 parent 059280e commit 31255f0
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 16 deletions.
4 changes: 3 additions & 1 deletion src/keepass2android/Totp/KeeOtpPluginAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ public TotpData GetData()
{
TotpData res = new TotpData();
string data;
if (!_entryFields.TryGetValue("otp", out data))
var otpKey = "otp";
if (!_entryFields.TryGetValue(otpKey, out data))
{
return res;
}
NameValueCollection parameters = ParseQueryString(data);
res.InternalFields.Add(otpKey);

if (parameters[KeyParameter] == null)
{
Expand Down
1 change: 1 addition & 0 deletions src/keepass2android/Totp/KeeWebOtpPluginAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public TotpData GetTotpData(IDictionary<string, string> entryFields, Context ctx
{
return res;
}
res.InternalFields.Add("otp");

string otpUriStart = "otpauth://totp/";

Expand Down
32 changes: 22 additions & 10 deletions src/keepass2android/Totp/Keepass2TotpPluginAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ class Keepass2TotpPluginAdapter : ITotpPluginAdapter
public TotpData GetTotpData(IDictionary<string, string> entryFields, Context ctx, bool muteWarnings)
{
TotpData res = new TotpData();
byte[] pbSecret = (GetOtpSecret(entryFields, "TimeOtp-") ?? MemUtil.EmptyByteArray);
byte[] pbSecret = (GetOtpSecret(entryFields, "TimeOtp-", out string secretFieldKey) ?? MemUtil.EmptyByteArray);

if (pbSecret.Length == 0)
return res;

res.InternalFields.Add(secretFieldKey);

string strPeriod;
uint uPeriod = 0;
if (entryFields.TryGetValue("TimeOtp-Period", out strPeriod))
{
res.InternalFields.Add("TimeOtp-Period");
uint.TryParse(strPeriod, out uPeriod);
}

Expand All @@ -33,6 +37,7 @@ public TotpData GetTotpData(IDictionary<string, string> entryFields, Context ctx
uint uLength = 0;
if (entryFields.TryGetValue("TimeOtp-Length", out strLength))
{
res.InternalFields.Add("TimeOtp-Length");
uint.TryParse(strLength, out uLength);
}

Expand All @@ -41,6 +46,8 @@ public TotpData GetTotpData(IDictionary<string, string> entryFields, Context ctx

string strAlg;
entryFields.TryGetValue("TimeOtp-Algorithm", out strAlg);
if (!string.IsNullOrEmpty(strAlg))
res.InternalFields.Add("TimeOtp-Algorithm");

res.HashAlgorithm = strAlg;
res.TotpSecret = pbSecret;
Expand All @@ -51,32 +58,37 @@ public TotpData GetTotpData(IDictionary<string, string> entryFields, Context ctx
}


private static byte[] GetOtpSecret(IDictionary<string, string> entryFields, string strPrefix)
private static byte[] GetOtpSecret(IDictionary<string, string> entryFields, string strPrefix, out string secretFieldKey)
{
try
{
string str;
entryFields.TryGetValue(strPrefix + "Secret", out str);
if (!string.IsNullOrEmpty(str))
secretFieldKey = strPrefix + "Secret";
entryFields.TryGetValue(secretFieldKey, out str);
if (!string.IsNullOrEmpty(str))
return StrUtil.Utf8.GetBytes(str);

entryFields.TryGetValue(strPrefix + "Secret-Hex", out str);

secretFieldKey = strPrefix + "Secret-Hex";
entryFields.TryGetValue(secretFieldKey, out str);
if (!string.IsNullOrEmpty(str))
return MemUtil.HexStringToByteArray(str);

entryFields.TryGetValue(strPrefix + "Secret-Base32", out str);

secretFieldKey = strPrefix + "Secret-Base32";
entryFields.TryGetValue(secretFieldKey, out str);
if (!string.IsNullOrEmpty(str))
return MemUtil.ParseBase32(str);

entryFields.TryGetValue(strPrefix + "Secret-Base64", out str);
secretFieldKey = strPrefix + "Secret-Base64";
entryFields.TryGetValue(secretFieldKey, out str);
if (!string.IsNullOrEmpty(str))
return Convert.FromBase64String(str);

}
catch (Exception e)
{
Kp2aLog.LogUnexpectedError(e);
}

secretFieldKey = null;
return null;
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/keepass2android/Totp/TotpData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ public string TotpSeed
public string TimeCorrectionUrl { get; set; }

public string HashAlgorithm { get; set; }

public bool IsDefaultRfc6238
{
get { return Length == "6" && Duration == "30" && (HashAlgorithm == null || HashAlgorithm == HashSha1); }
}

public List<string> InternalFields { get; set; } = new List<string>();

public static TotpData MakeDefaultRfc6238()
{
return new TotpData()
Expand Down
2 changes: 2 additions & 0 deletions src/keepass2android/Totp/TrayTotpPluginAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ public TotpData GetTotpData(IDictionary<string, string> entryFields)
{
bool NoTimeCorrection = false;
string[] Settings = SettingsGet(entryFields);
res.InternalFields.Add(SettingsFieldName);
res.InternalFields.Add(SeedFieldName);
res.Duration = Settings[0];
res.Length = Settings[1];
if (res.Length == "S")
Expand Down
12 changes: 8 additions & 4 deletions src/keepass2android/services/CopyToClipboardService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ private bool ClearNotifications()
return hadKeyboardData;
}


bool MakeAccessibleForKeyboard(PwEntryOutput entry, string searchUrl)
{
#if EXCLUDE_KEYBOARD
Expand All @@ -554,38 +555,41 @@ bool MakeAccessibleForKeyboard(PwEntryOutput entry, string searchUrl)
bool hasData = false;
Keepass2android.Kbbridge.KeyboardDataBuilder kbdataBuilder = new Keepass2android.Kbbridge.KeyboardDataBuilder();

String[] keys = {PwDefs.UserNameField,
String[] standardKeys = {PwDefs.UserNameField,
PwDefs.PasswordField,
Kp2aTotp.TotpKey,
PwDefs.UrlField,
PwDefs.NotesField,
PwDefs.TitleField
};
int[] resIds = {Resource.String.entry_user_name,
Resource.String.entry_password,
0,
Resource.String.entry_url,
Resource.String.entry_comment,
Resource.String.entry_title };

//add standard fields:
int i = 0;
foreach (string key in keys)
foreach (string key in standardKeys)
{
String value = entry.OutputStrings.ReadSafe(key);

if (value.Length > 0)
{
kbdataBuilder.AddString(key, GetString(resIds[i]), value);
kbdataBuilder.AddString(key, resIds[i] > 0 ? GetString(resIds[i]) : key, value);
hasData = true;
}
i++;
}
//add additional fields:
var totpData = new Kp2aTotp().TryGetTotpData(entry);
foreach (var pair in entry.OutputStrings)
{
var key = pair.Key;
var value = pair.Value.ReadString();

if (!PwDefs.IsStandardField(key))
if (!standardKeys.Contains(key) && totpData?.InternalFields.Contains(key) != true)
{
kbdataBuilder.AddString(pair.Key, pair.Key, value);
hasData = true;
Expand Down

0 comments on commit 31255f0

Please sign in to comment.