/******************************************************************************/
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Text;
using System.Threading.Tasks;
+using com.muldersoft.slunkcrypt.gui.utils;
+
namespace com.muldersoft.slunkcrypt.gui.process
{
public static class PasswordGen
{
- private static readonly TimeSpan TIMEOUT_MSEC = TimeSpan.FromSeconds(90);
+ private static readonly TimeSpan TIMEOUT = TimeSpan.FromSeconds(180);
- private const string COMMAND_PASSWRD = "-p {0:D}";
+ private const string COMMAND_PASSWRD = "-p";
// =============================================================================
// Exception classes
public class GenerationFailedException : IOException
{
- public GenerationFailedException(string message, Exception innerException) : base(message, innerException)
+ public GenerationFailedException(string message) : base(message)
{
}
}
public static async Task<string> GeneratePassword(int length)
{
+ if (length <= 0)
+ {
+ throw new ArgumentOutOfRangeException("Password length must be a positive value!");
+ }
using (FileStream executableFile = ExecutableHelper.GetExecutableFile())
{
- try
+ string[] arguments = new string[] { COMMAND_PASSWRD, string.Format("{0:D}", length) };
+ Tuple<int, string[]> result = await ProcessRunner.ExecAsnyc(executableFile.Name, arguments, null, ProcessPriorityClass.BelowNormal, TIMEOUT);
+ if (result.Item1 == 0)
{
- string password = await StartProcess(executableFile, length);
- if (IsWeakPassword(password))
+ foreach (string password in result.Item2)
{
- throw new InvalidDataException("The generated password string is invalid!");
+ if ((password.Length >= length) && (!IsWeakPassword(password)))
+ {
+ return password;
+ }
}
- return password;
- }
- catch (Exception e)
- {
- throw new GenerationFailedException("Failed to generate password string!", e);
}
+ throw new GenerationFailedException("Failed to generate password string!");
}
}
}
return (flags != 0xF);
}
-
- // =============================================================================
- // Internal methods
- // =============================================================================
-
- private static async Task<string> StartProcess(FileStream executableFile, int length)
- {
- using (Process process = new Process())
- {
- process.StartInfo.UseShellExecute = false;
- process.StartInfo.CreateNoWindow = true;
- process.StartInfo.RedirectStandardOutput = true;
- process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
- process.StartInfo.FileName = executableFile.Name;
- process.StartInfo.Arguments = string.Format(COMMAND_PASSWRD, length);
- process.Start();
-
- Stack<string> outputLines = await WaitForExit(process, TIMEOUT_MSEC);
-
- if (process.ExitCode == 0)
- {
- while (outputLines.Count > 0)
- {
- string line = outputLines.Pop();
- if (line.Length >= length)
- {
- return line;
- }
- }
- }
- return string.Empty;
- }
- }
-
- private static async Task<Stack<string>> WaitForExit(Process process, TimeSpan timeout)
- {
- Task<Stack<string>> readTask;
- await Task.WhenAny(readTask = Task.Run(() => ReadOutput(process)), Task.Delay(timeout));
- if (!process.WaitForExit(125))
- {
- process.Kill();
- process.WaitForExit();
- }
- return await readTask;
- }
-
- private static Stack<string> ReadOutput(Process process)
- {
- Stack<string> result = new Stack<string>();
- using (StreamReader reader = process.StandardOutput)
- {
- string line;
- while ((line = reader.ReadLine()) != null)
- {
- line = line.Trim();
- if (line.Length != 0)
- {
- result.Push(line.Trim());
- }
- }
- }
- return result;
- }
}
}