mirror of
https://github.com/wismna/ModernKeePassLib.git
synced 2025-10-03 15:40:20 -04:00
Update to version 2.42.1
Some changes Removed FutureAccesList code as it works only with UWP
This commit is contained in:
@@ -36,20 +36,20 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
||||
if(pwProfile.Length == 0) return PwgError.Success;
|
||||
|
||||
PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString());
|
||||
PwGenerator.PrepareCharSet(pcs, pwProfile);
|
||||
if(!PwGenerator.PrepareCharSet(pcs, pwProfile))
|
||||
return PwgError.InvalidCharSet;
|
||||
|
||||
char[] v = new char[pwProfile.Length];
|
||||
try
|
||||
{
|
||||
for(int i = 0; i < v.Length; ++i)
|
||||
{
|
||||
char ch = PwGenerator.GenerateCharacter(pwProfile,
|
||||
pcs, crsRandomSource);
|
||||
|
||||
char ch = PwGenerator.GenerateCharacter(pcs, crsRandomSource);
|
||||
if(ch == char.MinValue)
|
||||
return PwgError.TooFewCharacters;
|
||||
|
||||
v[i] = ch;
|
||||
if(pwProfile.NoRepeatingCharacters) pcs.Remove(ch);
|
||||
}
|
||||
|
||||
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(v);
|
||||
|
@@ -34,92 +34,61 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
||||
{
|
||||
psOut = ProtectedString.Empty;
|
||||
|
||||
string strPattern = pwProfile.Pattern;
|
||||
if(string.IsNullOrEmpty(strPattern)) return PwgError.Success;
|
||||
|
||||
CharStream cs = new CharStream(strPattern);
|
||||
LinkedList<char> llGenerated = new LinkedList<char>();
|
||||
PwCharSet pcsCurrent = new PwCharSet();
|
||||
PwCharSet pcsCustom = new PwCharSet();
|
||||
PwCharSet pcsUsed = new PwCharSet();
|
||||
bool bInCharSetDef = false;
|
||||
PwCharSet pcs = new PwCharSet();
|
||||
|
||||
string strPattern = ExpandPattern(pwProfile.Pattern);
|
||||
if(strPattern.Length == 0) return PwgError.Success;
|
||||
|
||||
CharStream csStream = new CharStream(strPattern);
|
||||
char ch = csStream.ReadChar();
|
||||
|
||||
while(ch != char.MinValue)
|
||||
while(true)
|
||||
{
|
||||
pcsCurrent.Clear();
|
||||
char ch = cs.ReadChar();
|
||||
if(ch == char.MinValue) break;
|
||||
|
||||
bool bGenerateChar = false;
|
||||
pcs.Clear();
|
||||
|
||||
if(ch == '\\')
|
||||
{
|
||||
ch = csStream.ReadChar();
|
||||
if(ch == char.MinValue) // Backslash at the end
|
||||
{
|
||||
llGenerated.AddLast('\\');
|
||||
break;
|
||||
}
|
||||
ch = cs.ReadChar();
|
||||
if(ch == char.MinValue) return PwgError.InvalidPattern;
|
||||
|
||||
if(bInCharSetDef) pcsCustom.Add(ch);
|
||||
else
|
||||
{
|
||||
llGenerated.AddLast(ch);
|
||||
pcsUsed.Add(ch);
|
||||
}
|
||||
}
|
||||
else if(ch == '^')
|
||||
{
|
||||
ch = csStream.ReadChar();
|
||||
if(ch == char.MinValue) // ^ at the end
|
||||
{
|
||||
llGenerated.AddLast('^');
|
||||
break;
|
||||
}
|
||||
|
||||
if(bInCharSetDef) pcsCustom.Remove(ch);
|
||||
pcs.Add(ch); // Allow "{...}" support and char check
|
||||
}
|
||||
else if(ch == '[')
|
||||
{
|
||||
pcsCustom.Clear();
|
||||
bInCharSetDef = true;
|
||||
if(!ReadCustomCharSet(cs, pcs))
|
||||
return PwgError.InvalidPattern;
|
||||
}
|
||||
else if(ch == ']')
|
||||
else
|
||||
{
|
||||
pcsCurrent.Add(pcsCustom.ToString());
|
||||
if(!pcs.AddCharSet(ch))
|
||||
return PwgError.InvalidPattern;
|
||||
}
|
||||
|
||||
bInCharSetDef = false;
|
||||
bGenerateChar = true;
|
||||
}
|
||||
else if(bInCharSetDef)
|
||||
int nCount = 1;
|
||||
if(cs.PeekChar() == '{')
|
||||
{
|
||||
if(pcsCustom.AddCharSet(ch) == false)
|
||||
pcsCustom.Add(ch);
|
||||
nCount = ReadCount(cs);
|
||||
if(nCount < 0) return PwgError.InvalidPattern;
|
||||
}
|
||||
else if(pcsCurrent.AddCharSet(ch) == false)
|
||||
{
|
||||
llGenerated.AddLast(ch);
|
||||
pcsUsed.Add(ch);
|
||||
}
|
||||
else bGenerateChar = true;
|
||||
|
||||
if(bGenerateChar)
|
||||
for(int i = 0; i < nCount; ++i)
|
||||
{
|
||||
PwGenerator.PrepareCharSet(pcsCurrent, pwProfile);
|
||||
|
||||
if(!PwGenerator.PrepareCharSet(pcs, pwProfile))
|
||||
return PwgError.InvalidCharSet;
|
||||
if(pwProfile.NoRepeatingCharacters)
|
||||
pcsCurrent.Remove(pcsUsed.ToString());
|
||||
|
||||
char chGen = PwGenerator.GenerateCharacter(pwProfile,
|
||||
pcsCurrent, crsRandomSource);
|
||||
{
|
||||
foreach(char chUsed in llGenerated)
|
||||
pcs.Remove(chUsed);
|
||||
}
|
||||
|
||||
char chGen = PwGenerator.GenerateCharacter(pcs,
|
||||
crsRandomSource);
|
||||
if(chGen == char.MinValue) return PwgError.TooFewCharacters;
|
||||
|
||||
llGenerated.AddLast(chGen);
|
||||
pcsUsed.Add(chGen);
|
||||
}
|
||||
|
||||
ch = csStream.ReadChar();
|
||||
}
|
||||
|
||||
if(llGenerated.Count == 0) return PwgError.Success;
|
||||
@@ -135,53 +104,70 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
||||
MemUtil.ZeroByteArray(pbUtf8);
|
||||
|
||||
MemUtil.ZeroArray<char>(v);
|
||||
llGenerated.Clear();
|
||||
|
||||
return PwgError.Success;
|
||||
}
|
||||
|
||||
private static string ExpandPattern(string strPattern)
|
||||
private static bool ReadCustomCharSet(CharStream cs, PwCharSet pcsOut)
|
||||
{
|
||||
if(strPattern == null) { Debug.Assert(false); return string.Empty; }
|
||||
|
||||
string str = strPattern;
|
||||
Debug.Assert(cs.PeekChar() != '['); // Consumed already
|
||||
Debug.Assert(pcsOut.Size == 0);
|
||||
|
||||
bool bAdd = true;
|
||||
while(true)
|
||||
{
|
||||
int nOpen = FindFirstUnescapedChar(str, '{');
|
||||
int nClose = FindFirstUnescapedChar(str, '}');
|
||||
char ch = cs.ReadChar();
|
||||
if(ch == char.MinValue) return false;
|
||||
if(ch == ']') break;
|
||||
|
||||
if((nOpen >= 0) && (nOpen < nClose))
|
||||
if(ch == '\\')
|
||||
{
|
||||
string strCount = str.Substring(nOpen + 1, nClose - nOpen - 1);
|
||||
str = str.Remove(nOpen, nClose - nOpen + 1);
|
||||
ch = cs.ReadChar();
|
||||
if(ch == char.MinValue) return false;
|
||||
|
||||
uint uRepeat;
|
||||
if(StrUtil.TryParseUInt(strCount, out uRepeat) && (nOpen >= 1))
|
||||
{
|
||||
if(uRepeat == 0)
|
||||
str = str.Remove(nOpen - 1, 1);
|
||||
else
|
||||
str = str.Insert(nOpen, new string(str[nOpen - 1], (int)uRepeat - 1));
|
||||
}
|
||||
if(bAdd) pcsOut.Add(ch);
|
||||
else pcsOut.Remove(ch);
|
||||
}
|
||||
else if(ch == '^')
|
||||
{
|
||||
if(bAdd) bAdd = false;
|
||||
else return false; // '^' toggles the mode only once
|
||||
}
|
||||
else
|
||||
{
|
||||
PwCharSet pcs = new PwCharSet();
|
||||
if(!pcs.AddCharSet(ch)) return false;
|
||||
|
||||
if(bAdd) pcsOut.Add(pcs.ToString());
|
||||
else pcsOut.Remove(pcs.ToString());
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
return str;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int FindFirstUnescapedChar(string str, char ch)
|
||||
private static int ReadCount(CharStream cs)
|
||||
{
|
||||
for(int i = 0; i < str.Length; ++i)
|
||||
{
|
||||
char chCur = str[i];
|
||||
if(cs.ReadChar() != '{') { Debug.Assert(false); return -1; }
|
||||
|
||||
if(chCur == '\\') ++i; // Next is escaped, skip it
|
||||
else if(chCur == ch) return i;
|
||||
// Ensure not empty
|
||||
char chFirst = cs.PeekChar();
|
||||
if((chFirst < '0') || (chFirst > '9')) return -1;
|
||||
|
||||
long n = 0;
|
||||
while(true)
|
||||
{
|
||||
char ch = cs.ReadChar();
|
||||
if(ch == '}') break;
|
||||
|
||||
if((ch >= '0') && (ch <= '9'))
|
||||
{
|
||||
n = (n * 10L) + (long)(ch - '0');
|
||||
if(n > int.MaxValue) return -1;
|
||||
}
|
||||
else return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return (int)n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -43,7 +43,6 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
||||
public static readonly string UpperHex = "0123456789ABCDEF";
|
||||
public static readonly string LowerHex = "0123456789abcdef";
|
||||
|
||||
public static readonly string Invalid = "\t\r\n";
|
||||
public static readonly string LookAlike = @"O0l1I|";
|
||||
|
||||
internal static readonly string MenuAccels = PwCharSet.LowerCase + PwCharSet.Digits;
|
||||
|
@@ -36,7 +36,9 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
||||
Success = 0,
|
||||
Unknown = 1,
|
||||
TooFewCharacters = 2,
|
||||
UnknownAlgorithm = 3
|
||||
UnknownAlgorithm = 3,
|
||||
InvalidCharSet = 4,
|
||||
InvalidPattern = 5
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -94,30 +96,33 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
||||
return new CryptoRandomStream(CrsAlgorithm.ChaCha20, pbKey);
|
||||
}
|
||||
|
||||
internal static char GenerateCharacter(PwProfile pwProfile,
|
||||
PwCharSet pwCharSet, CryptoRandomStream crsRandomSource)
|
||||
internal static char GenerateCharacter(PwCharSet pwCharSet,
|
||||
CryptoRandomStream crsRandomSource)
|
||||
{
|
||||
if(pwCharSet.Size == 0) return char.MinValue;
|
||||
uint cc = pwCharSet.Size;
|
||||
if(cc == 0) return char.MinValue;
|
||||
|
||||
ulong uIndex = crsRandomSource.GetRandomUInt64();
|
||||
uIndex %= (ulong)pwCharSet.Size;
|
||||
|
||||
char ch = pwCharSet[(uint)uIndex];
|
||||
|
||||
if(pwProfile.NoRepeatingCharacters)
|
||||
pwCharSet.Remove(ch);
|
||||
|
||||
return ch;
|
||||
uint i = (uint)crsRandomSource.GetRandomUInt64(cc);
|
||||
return pwCharSet[i];
|
||||
}
|
||||
|
||||
internal static void PrepareCharSet(PwCharSet pwCharSet, PwProfile pwProfile)
|
||||
internal static bool PrepareCharSet(PwCharSet pwCharSet, PwProfile pwProfile)
|
||||
{
|
||||
pwCharSet.Remove(PwCharSet.Invalid);
|
||||
uint cc = pwCharSet.Size;
|
||||
for(uint i = 0; i < cc; ++i)
|
||||
{
|
||||
char ch = pwCharSet[i];
|
||||
if((ch == char.MinValue) || (ch == '\t') || (ch == '\r') ||
|
||||
(ch == '\n') || char.IsSurrogate(ch))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(pwProfile.ExcludeLookAlike) pwCharSet.Remove(PwCharSet.LookAlike);
|
||||
|
||||
if(pwProfile.ExcludeCharacters.Length > 0)
|
||||
if(!string.IsNullOrEmpty(pwProfile.ExcludeCharacters))
|
||||
pwCharSet.Remove(pwProfile.ExcludeCharacters);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void Shuffle(char[] v, CryptoRandomStream crsRandomSource)
|
||||
@@ -127,8 +132,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
||||
|
||||
for(int i = v.Length - 1; i >= 1; --i)
|
||||
{
|
||||
ulong r = crsRandomSource.GetRandomUInt64();
|
||||
int j = (int)(r % (ulong)(i + 1));
|
||||
int j = (int)crsRandomSource.GetRandomUInt64((ulong)(i + 1));
|
||||
|
||||
char t = v[i];
|
||||
v[i] = v[j];
|
||||
|
Reference in New Issue
Block a user