-<?xml version="1.0" encoding="utf-8" ?>
+<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
- <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup>
<appSettings>
- <add key="DisableBusyIndicator" value="false" />
+ <add key="DisableBusyIndicator" value="false"/>
</appSettings>
-</configuration>
\ No newline at end of file
+</configuration>
--- /dev/null
+/******************************************************************************/
+/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+using System;
+using System.Diagnostics;
+using System.IO;
+
+using com.muldersoft.slunkcrypt.gui.utils;
+
+namespace com.muldersoft.slunkcrypt.gui.process
+{
+ static class ExecutableHelper
+ {
+ private const string FILENAME_FORMAT = "slunkcrypt-cli-{0}.exe";
+
+ // =============================================================================
+ // Exception classes
+ // =============================================================================
+
+ public class ExecutableNotFoundException : FileNotFoundException
+ {
+ public ExecutableNotFoundException(string message, string fileName) : base(message, fileName)
+ {
+ }
+ }
+
+ // =============================================================================
+ // Public methods
+ // =============================================================================
+
+ public static FileStream GetExecutableFile()
+ {
+ FileStream executableFile = null;
+ string appBaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
+ CPUFeatures cpuFeatures = CPUFeatures.Features;
+ if (cpuFeatures.x64 && CheckExecutableFile(ref executableFile, appBaseDirectory, "x64"))
+ {
+ Trace.Assert(executableFile != null);
+ return executableFile;
+ }
+ if (cpuFeatures.sse2 && CheckExecutableFile(ref executableFile, appBaseDirectory, "sse2"))
+ {
+ Trace.Assert(executableFile != null);
+ return executableFile;
+ }
+ if (CheckExecutableFile(ref executableFile, appBaseDirectory, "i686"))
+ {
+ Trace.Assert(executableFile != null);
+ return executableFile;
+ }
+ throw new ExecutableNotFoundException("SlunkCrypt executable file not found!", FILENAME_FORMAT);
+ }
+
+ // =============================================================================
+ // Internal methods
+ // =============================================================================
+
+ private static bool CheckExecutableFile(ref FileStream executableFile, string appBaseDirectory, string suffix)
+ {
+ try
+ {
+ executableFile = new FileStream(Path.Combine(appBaseDirectory, String.Format(FILENAME_FORMAT, suffix)), FileMode.Open, FileAccess.Read, FileShare.Read);
+ Version appVersion = VersionInfo.Version;
+ FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(executableFile.Name);
+ if (string.Equals(fileVersion.FileDescription, "SlunkCrypt", StringComparison.OrdinalIgnoreCase) &&
+ string.Equals(fileVersion.CompanyName, "Muldersoft", StringComparison.OrdinalIgnoreCase) &&
+ (fileVersion.FileMajorPart == appVersion.Major) && (fileVersion.FileMinorPart == appVersion.Minor))
+ {
+ return true;
+ }
+ executableFile.Dispose(); /*clean-up*/
+ }
+ catch { }
+ return false;
+ }
+ }
+}
--- /dev/null
+/******************************************************************************/
+/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace com.muldersoft.slunkcrypt.gui.process
+{
+ public static class PasswordGen
+ {
+ private static readonly TimeSpan TIMEOUT_MSEC = TimeSpan.FromSeconds(90);
+
+ private const string COMMAND_PASSWRD = "-p {0:D}";
+
+ // =============================================================================
+ // Exception classes
+ // =============================================================================
+
+ public class GenerationFailedException : IOException
+ {
+ public GenerationFailedException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+ }
+
+ // =============================================================================
+ // Public methods
+ // =============================================================================
+
+ public static async Task<string> GeneratePassword(int length)
+ {
+ using (FileStream executableFile = ExecutableHelper.GetExecutableFile())
+ {
+ try
+ {
+ string password = await StartProcess(executableFile, length);
+ if (IsWeakPassword(password))
+ {
+ throw new InvalidDataException("The generated password string is invalid!");
+ }
+ return password;
+ }
+ catch (Exception e)
+ {
+ throw new GenerationFailedException("Failed to generate password string!", e);
+ }
+ }
+ }
+
+ public static bool IsWeakPassword(string password)
+ {
+ int flags = 0;
+ if (!string.IsNullOrEmpty(password))
+ {
+ foreach (char c in password)
+ {
+ if (char.IsLetter(c))
+ {
+ flags |= char.IsUpper(c) ? 0x2 : 0x1;
+ }
+ else
+ {
+ flags |= char.IsDigit(c) ? 0x8 : 0x4;
+ }
+ }
+ }
+ 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;
+ }
+ }
+}
{
public enum Mode { Encrypt, Decrypt }
- private const string FILENAME_FORMAT = "slunkcrypt-cli-{0}.exe";
private const string COMMAND_ENCRYPT = "-e";
private const string COMMAND_DECRYPT = "-d";
private readonly FileStream m_executableFile;
// =============================================================================
- // Exception classes
- // =============================================================================
-
- public class ExecutableNotFoundException : FileNotFoundException
- {
- public ExecutableNotFoundException(string message, string fileName) : base(message, fileName)
- {
- }
- }
-
- // =============================================================================
// Constructor
// =============================================================================
public SlunkCryptRunner(Dispatcher dispatcher, ProcessPriorityClass? priorityClass = null) : base(dispatcher, priorityClass)
{
- m_executableFile = GetExecutableFile();
+ m_executableFile = ExecutableHelper.GetExecutableFile();
}
// =============================================================================
// Internal methods
// =============================================================================
- private static FileStream GetExecutableFile()
- {
- FileStream executableFile = null;
- string appBaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
- CPUFeatures cpuFeatures = CPUFeatures.Features;
- if (cpuFeatures.x64 && CheckExecutableFile(ref executableFile, appBaseDirectory, "x64"))
- {
- Trace.Assert(executableFile != null);
- return executableFile;
- }
- if (cpuFeatures.sse2 && CheckExecutableFile(ref executableFile, appBaseDirectory, "sse2"))
- {
- Trace.Assert(executableFile != null);
- return executableFile;
- }
- if (CheckExecutableFile(ref executableFile, appBaseDirectory, "i686"))
- {
- Trace.Assert(executableFile != null);
- return executableFile;
- }
- throw new ExecutableNotFoundException("SlunkCrypt executable file not found!", FILENAME_FORMAT);
- }
-
- private static bool CheckExecutableFile(ref FileStream executableFile, string appBaseDirectory, string suffix)
- {
- try
- {
- executableFile = new FileStream(Path.Combine(appBaseDirectory, String.Format(FILENAME_FORMAT, suffix)), FileMode.Open, FileAccess.Read, FileShare.Read);
- Version appVersion = VersionInfo.Version;
- FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(executableFile.Name);
- if (string.Equals(fileVersion.FileDescription, "SlunkCrypt", StringComparison.OrdinalIgnoreCase) &&
- string.Equals(fileVersion.CompanyName, "Muldersoft", StringComparison.OrdinalIgnoreCase) &&
- (fileVersion.FileMajorPart == appVersion.Major) && (fileVersion.FileMinorPart == appVersion.Minor))
- {
- return true;
- }
- executableFile.Dispose(); /*clean-up*/
- }
- catch { }
- return false;
- }
-
protected override double ParseProgressString(StringBuilder currentLine)
{
Match match;
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>com.muldersoft.slunkcrypt.gui</RootNamespace>
<AssemblyName>slunkcrypt-gui</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
+ <TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<Compile Include="Controls\PasswordToggleBox.xaml.cs">
<DependentUpon>PasswordToggleBox.xaml</DependentUpon>
</Compile>
+ <Compile Include="Process\ExecutableHelper.cs" />
<Compile Include="Utilities\ApplicationConfig.cs" />
<Compile Include="Utilities\CPUFeatures.cs" />
<Compile Include="Process\SlunkCryptRunner.cs" />
<Compile Include="Utilities\BusyManager.cs" />
<Compile Include="Utilities\CPU\CPUCapabilities.cs" />
+ <Compile Include="Process\PasswordGen.cs" />
<Compile Include="Utilities\PathUtils.cs" />
- <Compile Include="Utilities\SecureRandom.cs" />
<Compile Include="Utilities\SystemMenu.cs" />
<Compile Include="Utilities\VisibilityConverter.cs" />
<Compile Include="Utilities\FontSizeConverter.cs" />
private volatile SlunkCryptRunner m_processRunner = null;
private uint? m_menuId_disableAnimation = null, m_menuId_enableExpertMode = null;
- private const string ASCII_CHARS = "!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+ public const string ASCII_CHARS = "!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~";
// =============================================================================
// Constructor
using (BusyManager busy = new BusyManager(this))
{
Edit_Encrypt_Password.Password = string.Empty;
- Task<string> password = Task.Run(() => GenerateRandomString(GEN_PASSWD_LENGTH));
- await Task.WhenAll(password, Task.Delay(500));
- Button_Encrypt_Toggle.IsChecked = true;
- Edit_Encrypt_Password.Password = password.Result;
+ string password;
+ if (!string.IsNullOrEmpty(password = await GeneratePassword()))
+ {
+ Button_Encrypt_Toggle.IsChecked = true;
+ Edit_Encrypt_Password.Password = password;
+ }
}
}
return;
}
}
- else if (IsWeakPassword(passwordStr))
+ else if (PasswordGen.IsWeakPassword(passwordStr))
{
if (MessageBox.Show(this, "Passphrase should contain a mix of upper case characters, lower case characters, digits and other characters!", "Weak Passphrase", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) != MessageBoxResult.OK)
{
SetStatus(string.Format("Error: The {0} process could not be created! (Error code: {1:D})", GetModeString(m_modeOfOperation), GetWin32ErrorCode(err)), Status.Failure);
MessageBox.Show(this, "Failed to create SlunkCrypt process:\n\n" + err.InnerException?.Message ?? err.Message, "Process Creation Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
- catch (SlunkCryptRunner.ExecutableNotFoundException)
+ catch (ExecutableHelper.ExecutableNotFoundException)
{
SetStatus("Error: The required SlunkCrypt executable file could not be found!", Status.Failure);
MessageBox.Show(this, "The SlunkCrypt executable file could not be found.\n\nPlease make sure that the SlunkCrypt CLI executable file is located in the same directory as the GUI program!", "Executable Not Found", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
+ private async Task<string> GeneratePassword()
+ {
+ string password = string.Empty;
+ try
+ {
+ Task<string> passwordTask = Task.Run(() => PasswordGen.GeneratePassword(GEN_PASSWD_LENGTH));
+ await Task.WhenAll(passwordTask, Task.Delay(1000));
+ password = passwordTask.Result;
+ }
+ catch (ExecutableHelper.ExecutableNotFoundException)
+ {
+ MessageBox.Show(this, "The SlunkCrypt executable file could not be found.\n\nPlease make sure that the SlunkCrypt CLI executable file is located in the same directory as the GUI program!", "Executable Not Found", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ catch (PasswordGen.GenerationFailedException)
+ {
+ MessageBox.Show(this, "Error: The password could not be generated!", "Generation Failed", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ return password;
+ }
+
private void SetStatus(string text, Status status = Status.Default)
{
switch (status)
}
}
- private static bool IsWeakPassword(string password)
- {
- int flags = 0;
- foreach (char c in password)
- {
- if (char.IsLetter(c))
- {
- flags |= char.IsUpper(c) ? 0x2 : 0x1;
- }
- else
- {
- flags |= char.IsDigit(c) ? 0x8 : 0x4;
- }
- }
- return (flags != 0xF);
- }
-
- private static string GenerateRandomString(int length)
- {
- if (length > 0)
- {
- char[] asciiChars = ASCII_CHARS.ToCharArray();
- using (SecureRandom secureRandom = new SecureRandom())
- {
- string result;
- do
- {
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < length; ++i)
- {
- builder.Append(asciiChars[secureRandom.NextUInt32() % ((uint)asciiChars.Length)]);
- }
- result = builder.ToString();
- }
- while ((!char.IsLetterOrDigit(result[0])) || (!char.IsLetterOrDigit(result[result.Length - 1])) || IsWeakPassword(result));
- return result;
- }
- }
- return string.Empty;
- }
-
private static void SetFocusAndSelectAll(FrameworkElement element)
{
TextBox textBox;
{
return ((c == WILDCARD_ONE) || (c == WILDCARD_ANY));
}
-
}
}
+++ /dev/null
-/******************************************************************************/
-/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
-/* This work has been released under the CC0 1.0 Universal license! */
-/******************************************************************************/
-
-using System;
-using System.IO;
-using System.Security.Cryptography;
-
-namespace com.muldersoft.slunkcrypt.gui.utils
-{
- class SecureRandom : IDisposable
- {
- private volatile bool m_disposed = false;
-
- private readonly RNGCryptoServiceProvider m_provider;
- private readonly byte[] m_tempBuffer = new byte[256];
-
- private int m_offset = int.MaxValue;
-
- // =============================================================================
- // Constructor
- // =============================================================================
-
- public SecureRandom()
- {
- try
- {
- m_provider = new RNGCryptoServiceProvider();
- }
- catch (Exception e)
- {
- throw new IOException("Failed to create RNGCryptoServiceProvider instance!", e);
- }
- }
-
- ~SecureRandom()
- {
- Dispose();
- }
-
- // =============================================================================
- // Public methods
- // =============================================================================
-
- public int NextInt32()
- {
- if (m_disposed)
- {
- throw new ObjectDisposedException("SecureRandom");
- }
- EnsureBytesAvailable(sizeof(int));
- int value = BitConverter.ToInt32(m_tempBuffer, m_offset);
- m_offset += sizeof(int);
- return value;
- }
-
- public uint NextUInt32()
- {
- if (m_disposed)
- {
- throw new ObjectDisposedException("SecureRandom");
- }
- EnsureBytesAvailable(sizeof(uint));
- uint value = BitConverter.ToUInt32(m_tempBuffer, m_offset);
- m_offset += sizeof(uint);
- return value;
- }
-
- public long NextInt64()
- {
- if (m_disposed)
- {
- throw new ObjectDisposedException("SecureRandom");
- }
- EnsureBytesAvailable(sizeof(long));
- long value = BitConverter.ToInt64(m_tempBuffer, m_offset);
- m_offset += sizeof(long);
- return value;
- }
-
- public ulong NextUInt64()
- {
- if (m_disposed)
- {
- throw new ObjectDisposedException("SecureRandom");
- }
- EnsureBytesAvailable(sizeof(ulong));
- ulong value = BitConverter.ToUInt64(m_tempBuffer, m_offset);
- m_offset += sizeof(ulong);
- return value;
- }
-
- public void Dispose()
- {
- if (!m_disposed)
- {
- m_disposed = true;
- GC.SuppressFinalize(this);
- try
- {
- FillArray(m_tempBuffer, 0);
- }
- finally
- {
- try
- {
- m_provider.Dispose();
- }
- catch { }
- }
- }
- }
-
- // =============================================================================
- // Internal methods
- // =============================================================================
-
- private void EnsureBytesAvailable(int length)
- {
- if ((m_offset >= m_tempBuffer.Length) || ((m_tempBuffer.Length - m_offset) < length))
- {
- try
- {
- m_provider.GetBytes(m_tempBuffer);
- m_offset = 0;
- }
- catch (Exception e)
- {
- throw new IOException("Failed to generated random bytes!", e);
- }
- }
- }
-
- private static void FillArray(byte[] array, byte value)
- {
- if (!ReferenceEquals(array, null))
- {
- for (int i = 0; i < array.Length; ++i)
- {
- array[i] = value;
- }
- }
- }
- }
-}