Winify

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 13  →  ?path2? @ 14
/trunk/Servers/Server.cs
@@ -95,7 +95,7 @@
{
}
 
public Server(string name, string url, string username, string password)
public Server(string name, string url, string username, string password) : this()
{
Name = name;
Url = url;
/trunk/Servers/Servers.csproj
@@ -9,9 +9,10 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Servers</RootNamespace>
<AssemblyName>Servers</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -33,11 +34,6 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
@@ -53,5 +49,6 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
/trunk/Winify/App.config
@@ -10,7 +10,7 @@
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<userSettings>
<Winify.Properties.Settings>
@@ -25,6 +25,14 @@
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
 
/trunk/Winify/Form1.Designer.cs
@@ -51,7 +51,7 @@
this.settingsToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("settingsToolStripMenuItem.Image")));
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
this.settingsToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.settingsToolStripMenuItem.Text = "Settings";
this.settingsToolStripMenuItem.Text = "Settings...";
this.settingsToolStripMenuItem.Click += new System.EventHandler(this.SettingsToolStripMenuItem_Click);
//
// toolStripSeparator1
/trunk/Winify/Form1.cs
@@ -19,6 +19,8 @@
 
private readonly global::Servers.Servers _servers;
 
private readonly TaskScheduler _taskScheduler;
 
private AboutForm _aboutForm;
 
private GotifyConnectionManager _gotifyConnectionManager;
@@ -51,14 +53,16 @@
_servers = new global::Servers.Servers();
_servers.Server.CollectionChanged += Server_CollectionChanged;
 
_notificationManager = new NotificationManager(TaskScheduler.FromCurrentSynchronizationContext());
_taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
 
_notificationManager = new NotificationManager(_taskScheduler);
 
_gotifyConnectionManager = new GotifyConnectionManager(_servers);
_gotifyConnectionManager.GotifyNotification += GotifyConnectionManager_GotifyNotification;
 
Task.Run(async () =>
LoadServers().ContinueWith(async task =>
{
var restoredServers = await LoadServers();
var restoredServers = await task;
 
foreach (var server in restoredServers.Server)
{
/trunk/Winify/Form1.resx
@@ -127,7 +127,7 @@
<data name="settingsToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABHNCSVQICAgIfAhkiAAAAAFzUkdCAK7O
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA6/AAAOvwE4BVMkAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
aW5rc2NhcGUub3Jnm+48GgAA+IZJREFUeF7s/QeYHFd63otrlYMVruL6ypZt2bLC3yv/ZV0Fh2vJlizt
LgECIAkGEIkJzDnnZk4IDGAOAAGCAIbEgGmZdpkjQBAZRCIySIIgEWa6QW7i1v3eE6pPnX4r9fTM9Myc
73l+z6nuHsxgumvO73tPVVf/VKhQoXq/Kh3Rz1cWfPG3V3TWzq501mZe2XngDRl3Cnuv7Kx9JUT9jfzf
@@ -1195,7 +1195,7 @@
<data name="updateToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABHNCSVQICAgIfAhkiAAAAAFzUkdCAK7O
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7CAAAOwgEVKEqAAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
aW5rc2NhcGUub3Jnm+48GgAAikFJREFUeF7tnQWUHMfVtiXtSloxM1gsi5mZLWZmZmZpVxZLliwmQ8iO
EzvGJIbEzAyyWHaYv8CXfGH8U/97R1lnLV/tVNNM98z7nPOck8i7PVs93XWrq6vuLUAIiQTlYRPYE46F
c+AquA0egnfDB+Ez8E34HjwPv/cf/xf+Fv4Nmhso/z3XX0P5vY+hHOsd+Cz8NnwA3gH3w41wAZwAB8IO
@@ -1792,7 +1792,7 @@
<data name="aboutToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABHNCSVQICAgIfAhkiAAAAAFzUkdCAK7O
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA6/AAAOvwE4BVMkAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
aW5rc2NhcGUub3Jnm+48GgAAYplJREFUeF7t3QeUFUXaBmAYGHLOSSQLiAEUMKCsrigGDCCsgoFVURED
IgoqZlEEDCxGEBNBBQFRJGeQzDAgOYeZIQmS8d9U//ddxR3lRSZ0V1f3fd9znnM84zC3bldV173dXVU5
GIZxPomigjhHNBe3iPtEN/GqeFcME9+KyWKeWCw2iM1i3x/8R5g/0J/98ff0364X+rf0b+rf1tcYKvQ1
@@ -2220,7 +2220,7 @@
<data name="quitToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABHNCSVQICAgIfAhkiAAAAAFzUkdCAK7O
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA6/AAAOvwE4BVMkAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
HOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAGXRFWHRTb2Z0d2FyZQB3d3cu
aW5rc2NhcGUub3Jnm+48GgAASYVJREFUeF7t3XmcHWWd73HSnc7S2TeyB8hCFtZIIGyBECJCCFtCAgKB
BJJOIGYBQsKmgNtEEUWvVwFRBhHE4MKMgAxcR7kXx1HkXhFBHBXBGQVUBJRFCMlzq47nMNB+E7qfXz1P
VZ3z+b5e73+K0L9T51dVv6e7T1ftQAghhJBSpkti98TqxG2JnyReSjyXeDTxpcRxie4JQgghhJQ4YxNt
/trunk/Winify/NotificationForm.cs
@@ -1,8 +1,6 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Media;
using System.Threading.Tasks;
using System.Windows.Forms;
using Winify.Utilities;
/trunk/Winify/NotificationManager.cs
@@ -8,7 +8,6 @@
using System.Windows.Forms;
using Microsoft.Win32;
using Winify.Gotify;
using Winify.Properties;
 
namespace Winify
{
/trunk/Winify/Servers/Serialization/ServersSerialization.cs
@@ -6,6 +6,8 @@
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using Servers;
using Winify.Utilities;
 
namespace Winify.Servers.Serialization
{
@@ -87,7 +89,21 @@
XmlReaderSettingsValidationEventHandler;
}
 
return new ServersSerializationSuccess(servers, validationEventArgs);
// Decrypt password.
var deviceId = Miscellaneous.GetMachineGuid();
var protectedServers = new global::Servers.Servers
{
Server = new BindingListWithCollectionChanged<Server>()
};
foreach (var server in servers.Server)
{
var unarmored = Convert.FromBase64String(server.Password);
var decrypted = Encoding.UTF8.GetString(AES.Decrypt(unarmored, deviceId));
 
protectedServers.Server.Add(new Server(server.Name, server.Url, server.Username, decrypted));
}
 
return new ServersSerializationSuccess(protectedServers, validationEventArgs);
}
 
public static async Task<ServersSerializationState> Serialize(global::Servers.Servers servers, string file)
@@ -111,8 +127,22 @@
null,
"<!ATTLIST Servers xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>");
 
XmlSerializer.Serialize(xmlWriter, servers);
// Encrypt password for all servers.
var deviceId = Miscellaneous.GetMachineGuid();
var protectedServers = new global::Servers.Servers
{
Server = new BindingListWithCollectionChanged<Server>()
};
foreach (var server in servers.Server)
{
var encrypted = AES.Encrypt(Encoding.UTF8.GetBytes(server.Password), deviceId);
var armored = Convert.ToBase64String(encrypted);
 
protectedServers.Server.Add(new Server(server.Name, server.Url, server.Username, armored));
}
 
XmlSerializer.Serialize(xmlWriter, protectedServers);
 
using (var fileStream =
new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
@@ -153,8 +183,22 @@
null,
"<!ATTLIST Servers xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>");
 
XmlSerializer.Serialize(xmlWriter, servers);
// Encrypt password for all servers.
var deviceId = Miscellaneous.GetMachineGuid();
var protectedServers = new global::Servers.Servers
{
Server = new BindingListWithCollectionChanged<Server>()
};
foreach (var server in servers.Server)
{
var encrypted = AES.Encrypt(Encoding.UTF8.GetBytes(server.Password), deviceId);
var armored = Convert.ToBase64String(encrypted);
 
protectedServers.Server.Add(new Server(server.Name, server.Url, server.Username, armored));
}
 
XmlSerializer.Serialize(xmlWriter, protectedServers);
 
memoryStream.Position = 0L;
 
await memoryStream.CopyToAsync(outputStream);
/trunk/Winify/SettingsForm.Designer.cs
@@ -345,7 +345,7 @@
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(80, 23);
this.button1.TabIndex = 6;
this.button1.Text = "Add";
this.button1.Text = "Update";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.Button1_Click);
//
/trunk/Winify/SettingsForm.cs
@@ -60,12 +60,20 @@
 
var server = new Server(name, url, username, password);
 
if (_servers.Server.Any(servers => servers.Name == server.Name))
var update = _servers.Server.FirstOrDefault(select => select.Name == server.Name);
switch (update)
{
return;
default:
_servers.Server.Remove(update);
update.Url = server.Url;
update.Username = server.Username;
update.Password = server.Password;
_servers.Server.Add(update);
break;
case null:
_servers.Server.Add(server);
break;
}
 
_servers.Server.Add(server);
}
 
private void Button2_Click(object sender, EventArgs e)
/trunk/Winify/Utilities/AES.cs
@@ -0,0 +1,97 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System.IO;
using System.Linq;
using System.Security.Cryptography;
 
namespace Winify.Utilities
{
public static class AES
{
#region Static Fields and Constants
 
private const int AESKeySaltBytes = 16;
 
private static readonly RNGCryptoServiceProvider Rng = new RNGCryptoServiceProvider();
 
#endregion
 
#region Public Methods
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
public static byte[] Encrypt(byte[] plain, string password)
{
using (var rijndael = Rijndael.Create())
{
rijndael.BlockSize = 128;
rijndael.Mode = CipherMode.CBC;
rijndael.KeySize = 256;
rijndael.Padding = PaddingMode.PKCS7;
var salt = new byte[AESKeySaltBytes];
Rng.GetBytes(salt);
var pdb = new Rfc2898DeriveBytes(password, salt, 1000);
rijndael.Key = pdb.GetBytes(rijndael.KeySize / 8);
rijndael.IV = pdb.GetBytes(rijndael.BlockSize / 8);
 
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream =
new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(plain, 0, plain.Length);
cryptoStream.Close();
 
var ciphertext = memoryStream.ToArray();
 
return salt.Concat(ciphertext)
.ToArray();
}
}
}
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
public static byte[] Decrypt(byte[] cipher, string password)
{
using (var rijndael = Rijndael.Create())
{
rijndael.BlockSize = 128;
rijndael.Mode = CipherMode.CBC;
rijndael.KeySize = 256;
rijndael.Padding = PaddingMode.PKCS7;
 
var salt = cipher.Take(16)
.ToArray();
 
var ciphertext = cipher.Skip(16)
.ToArray();
 
var pdb = new Rfc2898DeriveBytes(password, salt, 1000);
rijndael.Key = pdb.GetBytes(rijndael.KeySize / 8);
rijndael.IV = pdb.GetBytes(rijndael.BlockSize / 8);
 
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream =
new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(ciphertext, 0, ciphertext.Length);
cryptoStream.Close();
 
return memoryStream.ToArray();
}
}
}
}
 
#endregion
}
}
/trunk/Winify/Utilities/Miscellaneous.cs
@@ -164,6 +164,39 @@
}
}
 
/// <summary>
/// Returns the machine GUID.
/// </summary>
/// <returns>the GUID of the machine</returns>
/// <remarks>https://stackoverflow.com/questions/2333149/how-to-fast-get-hardware-id-in-c</remarks>
public static string GetMachineGuid()
{
var location = @"SOFTWARE\Microsoft\Cryptography";
var name = "MachineGuid";
 
using (var localMachineX64View =
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var rk = localMachineX64View.OpenSubKey(location))
{
if (rk == null)
{
throw new KeyNotFoundException(
string.Format("Key Not Found: {0}", location));
}
 
var machineGuid = rk.GetValue(name);
if (machineGuid == null)
{
throw new IndexOutOfRangeException(
string.Format("Index Not Found: {0}", name));
}
 
return machineGuid.ToString();
}
}
}
 
#endregion
}
}
/trunk/Winify/Winify.csproj
@@ -8,10 +8,11 @@
<OutputType>WinExe</OutputType>
<RootNamespace>Winify</RootNamespace>
<AssemblyName>Winify</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -42,10 +43,9 @@
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\netstandard1.1\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
@@ -52,18 +52,12 @@
<Reference Include="System.Net.WebSockets.Client.Managed, Version=1.0.22.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.WebSockets.Client.Managed.1.0.22\lib\net45\System.Net.WebSockets.Client.Managed.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\portable-net45+win8+wp8+wpa81\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Windows" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
@@ -94,6 +88,7 @@
<Compile Include="Gotify\GotifyConnection.cs" />
<Compile Include="Gotify\GotifyNotification.cs" />
<Compile Include="Gotify\GotifyNotificationEventArgs.cs" />
<Compile Include="Utilities\AES.cs" />
<Compile Include="Utilities\Natives.cs" />
<Compile Include="NotificationForm.cs">
<SubType>Form</SubType>
/trunk/Winify/packages.config
@@ -3,7 +3,7 @@
<packages>
<package id="Autoupdater.NET.Official" version="1.7.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
<package id="System.Buffers" version="4.4.0" targetFramework="net472" />
<package id="System.Net.WebSockets.Client.Managed" version="1.0.22" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net452" />
<package id="System.Net.WebSockets.Client.Managed" version="1.0.22" targetFramework="net452" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net452" />
</packages>
/trunk/Winify.sln.DotSettings
@@ -1,5 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/NamespacesWithAnnotations/=Winify_002EAnnotations/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AES/@EntryIndexedValue">AES</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gotify/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Steamworks/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Winify/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>