diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj index 5da91386c..6ec42a259 100644 --- a/BeWo/BeWo.csproj +++ b/BeWo/BeWo.csproj @@ -593,6 +593,7 @@ + diff --git a/BeWo/BeWoApp.xaml.cs b/BeWo/BeWoApp.xaml.cs index a734f542d..c3bb61386 100644 --- a/BeWo/BeWoApp.xaml.cs +++ b/BeWo/BeWoApp.xaml.cs @@ -67,6 +67,8 @@ namespace BeWo private static DocumentWatcher _DocumentWatcher; + internal static PasswortSecurityStrength PasswortStrength; + public static BeWoApp CurrentBeWo { get { return Current as BeWoApp; } diff --git a/BeWo/Core/BeWoUtils.cs b/BeWo/Core/BeWoUtils.cs index 19e5bcbd7..87b43b36a 100644 --- a/BeWo/Core/BeWoUtils.cs +++ b/BeWo/Core/BeWoUtils.cs @@ -1766,5 +1766,76 @@ namespace BeWo.Core BeWoApp.MainControl.EndWaiting(); } + + + public static PasswortSecurityStrength CheckPasswotrSecurity(string paswd) + { + string zahlen = "0123456789"; + string grossBuchstaben = "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ"; + string kleinBuchstaben = "abcdefghijklmnopqrstuvwxyzäöüß"; + + string sonderzeichenLevel1 = "\\\"\'µ@€!&/()=?+#*"; + string sonderzeichenLevel2 = ",.-;:_><|§$%'{[]}´`^°~²³"; + + int punkte = 0; + + if (paswd.Any(x => grossBuchstaben.Contains(x))) + { + punkte++; + } + if (paswd.Any(x => kleinBuchstaben.Contains(x))) + { + punkte++; + } + if (paswd.Any(x => zahlen.Contains(x))) + { + punkte++; + } + if (paswd.Any(x => sonderzeichenLevel1.Contains(x))) + { + punkte++; + } + if (paswd.Any(x => sonderzeichenLevel2.Contains(x))) + { + punkte++; + } + + //passwortlänge + if (paswd.Length >= 6 && paswd.Length < 9) + { + punkte += 1; + } + + if (paswd.Length >= 9 && paswd.Length < 12) + { + punkte += 2; + } + + if (paswd.Length >= 12 && paswd.Length < 18) + { + punkte += 3; + } + + if (paswd.Length >= 18) + { + punkte += 4; + } + + //return rückgabe schwach mittel stark + if (punkte > 7) + { + return PasswortSecurityStrength.Stark; + } + else if (punkte > 5 && punkte <= 7) + { + return PasswortSecurityStrength.Mittelmass; + } + else + { + return PasswortSecurityStrength.Schwach; + } + + } + } } diff --git a/BeWo/LoginControl.xaml.cs b/BeWo/LoginControl.xaml.cs index bd55bad30..c065069d0 100644 --- a/BeWo/LoginControl.xaml.cs +++ b/BeWo/LoginControl.xaml.cs @@ -757,6 +757,8 @@ namespace BeWo BeWoApp.UserName = lUserName; BeWoApp.UserPassword = lPassword; + + BeWoApp.PasswortStrength = BeWoUtils.CheckPasswotrSecurity(lPassword); ServiceFacade.DoUserServiceAsync(s2 => s2.LoadUserByLoginName(lUserName), r2 => diff --git a/BeWo/MainControl.xaml.cs b/BeWo/MainControl.xaml.cs index 892de68fa..c0601fb13 100644 --- a/BeWo/MainControl.xaml.cs +++ b/BeWo/MainControl.xaml.cs @@ -717,7 +717,6 @@ namespace BeWo NavigateTo(_HomeView); - // VarFieldListVM v = new VarFieldListVM(l); // NavigateTo(new VarFieldView(v)); diff --git a/BeWo/View/HomeDragPanelView.xaml b/BeWo/View/HomeDragPanelView.xaml index 290f2d661..a6eb4ca2b 100644 --- a/BeWo/View/HomeDragPanelView.xaml +++ b/BeWo/View/HomeDragPanelView.xaml @@ -200,7 +200,16 @@ - + + + + + + + + + + diff --git a/BeWo/View/HomeDragPanelView.xaml.cs b/BeWo/View/HomeDragPanelView.xaml.cs index 35c9fa1fc..4cad8d477 100644 --- a/BeWo/View/HomeDragPanelView.xaml.cs +++ b/BeWo/View/HomeDragPanelView.xaml.cs @@ -38,6 +38,7 @@ using System.Media; using System.Net; using System.Net.NetworkInformation; using System.Text; +using System.Text.RegularExpressions; using System.Windows.Forms; using BS.Shared.Core; using Newtonsoft.Json; @@ -91,17 +92,20 @@ namespace BeWo.View //################################################################ + //int staerke public HomeDragPanelView() { InitializeComponent(); - txtHeader.Text = String.Format("{0} {1}", BeWoApp.LoggedOnUser.Employee.FirstName, - BeWoApp.LoggedOnUser.Employee.LastName); + txtHeader.Text = String.Format("{0} {1}", BeWoApp.LoggedOnUser.Employee.FirstName,BeWoApp.LoggedOnUser.Employee.LastName); + txtVersion.Text = BeWoApp.Version; txtLoginTime.Text = string.Empty; txtLastLoginTime.Text = string.Empty; + PasswortSchloss.Text = string.Join("", (from Match m in Regex.Matches("D83DDD12", @"\S{4}") select (char)int.Parse(m.Value, NumberStyles.HexNumber)).ToArray()); + //PreparePanels(); InitPanels(null); @@ -146,6 +150,53 @@ namespace BeWo.View { BewoChat.Visibility = Visibility.Hidden; } + + + + PruefePasswortStaerke(); + } + + private void PruefePasswortStaerke() + { + if (BeWoApp.PasswortStrength == PasswortSecurityStrength.Schwach) + { + PasswortSchloss.Foreground = new SolidColorBrush(Colors.Red); + + this.Dispatcher.BeginInvoke( + DispatcherPriority.Normal, + (Action)delegate + { + if (BeWoApp.AppSettings.IsPasswordSecurityActiv) + { + MessageBox.Show("Ihr Passwort ist zu Schwach, bitte ändern sie es bei gelegenheit!", "Achtung", + MessageBoxButton.OK); + } + }); + + }else if (BeWoApp.PasswortStrength == PasswortSecurityStrength.Mittelmass) + { + PasswortSchloss.Foreground = new SolidColorBrush(Colors.Yellow); + + //this.Dispatcher.BeginInvoke( + //DispatcherPriority.Normal, + //(Action)delegate + //{ + // if (BeWoApp.AppSettings.IsPasswordSecurityActiv) + // { + // MessageBox.Show("Ihr Passwort ist zu Schwach, bitte ändern sie es bei gelegenheit!", "Achtung", + // MessageBoxButton.OK); + // } + //}); + + }else if (BeWoApp.PasswortStrength == PasswortSecurityStrength.Stark) + { + PasswortSchloss.Foreground = new SolidColorBrush(Colors.Green); + } + + + //wenn passwortsicherheit zusätzlich aktiviert dann gib messagebox aus (ihr passwort ist zu Schwach) + + } private void PreparePanels() diff --git a/BeWo/View/PasswortAenderungsView.xaml.cs b/BeWo/View/PasswortAenderungsView.xaml.cs index 3d2a2c232..8e98b3b6d 100644 --- a/BeWo/View/PasswortAenderungsView.xaml.cs +++ b/BeWo/View/PasswortAenderungsView.xaml.cs @@ -181,7 +181,6 @@ namespace BeWo.View } else { - //Passwort Längen Bonus Punkte if (NeuesPwBox.Password.Length >= 6 && NeuesPwBox.Password.Length < 9 ) { diff --git a/BeWo/ViewModel/PasswortVerlaufVM.cs b/BeWo/ViewModel/PasswortVerlaufVM.cs new file mode 100644 index 000000000..2ce530ac4 --- /dev/null +++ b/BeWo/ViewModel/PasswortVerlaufVM.cs @@ -0,0 +1,70 @@ +using BS.Shared; +using BS.Shared.DataContracts; +using System; + +namespace BeWo.ViewModel +{ + public class PasswortVerlaufVM : AbstractDCMapperVM + { + public static string PropertyName_ErstellDatum = "ErstellDatum"; + + //Nein zu Passwort und Salt + + private DateTime _ErstellDatum; + + private long? _ApplicationUserOid; + + public PasswortVerlaufVM(PasswortVerlaufDC pDC) + : base(pDC, true) + { + } + + public DateTime ErstellDatum + { + get { return this._ErstellDatum; } + + set + { + if (this.AreDifferent(this._ErstellDatum, value)) + { + this._ErstellDatum = value; + this.StoreDirtyInformation(this.AreDifferent(DataContract.ErstellDatum, value), PropertyName_ErstellDatum); + this.FirePropertyChanged(PropertyName_ErstellDatum); + } + } + } + + public virtual long? ApplicationUserOid + { + get + { + return this._ApplicationUserOid; + } + + set + { + if (this.AreDifferent(this._ApplicationUserOid, value)) + { + this._ApplicationUserOid = value; + } + } + } + + + protected override void InitByDataContract(PasswortVerlaufDC pDataContract) + { + _ApplicationUserOid = pDataContract.ApplicationUserOid; + _ErstellDatum = pDataContract.ErstellDatum; + + } + + protected override PasswortVerlaufDC MapToDataContract(PasswortVerlaufDC pDataContract, bool doCommit) + { + + pDataContract.ErstellDatum = _ErstellDatum; + pDataContract.ApplicationUserOid = _ApplicationUserOid; + + return pDataContract; + } + } +} \ No newline at end of file diff --git a/Data/Data.csproj b/Data/Data.csproj index 47701073e..177744ee2 100644 --- a/Data/Data.csproj +++ b/Data/Data.csproj @@ -158,6 +158,7 @@ + @@ -552,6 +553,9 @@ PreserveNewest + + Designer + Designer diff --git a/Data/Entities/PasswortVerlauf.cs b/Data/Entities/PasswortVerlauf.cs new file mode 100644 index 000000000..5beb50026 --- /dev/null +++ b/Data/Entities/PasswortVerlauf.cs @@ -0,0 +1,121 @@ +using BS.Shared; +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace BeWo.Data.Entities +{ + public class PasswortVerlauf : BeWoEntityBase + { + + public static string PropertyName_ApplicationUserOid = "ApplicationUserOid"; + + public static string PropertyName_ErstellDatum = "ErstellDatum"; + + public static string PropertyName_Passwort = "Passwort"; + + public static string PropertyName_Salt = "Salt"; + + private readonly byte[] _Rc2IV = { 35, 138, 177, 253, 227, 63, 2, 27 }; + + private readonly byte[] _Rc2Key = { 174, 130, 219, 185, 185, 221, 96, 50, 37, 212, 81, 121, 71, 206, 130, 153 }; + + private string _Passwort; + + private DateTime _ErstellDatum; + + private long? _ApplicationUserOid; + + private string _Salt; + + + public virtual string Passwort + { + get { return _Passwort; } + + set + { + if (AreDifferent(_Passwort, value)) + { + _Passwort = value; + } + } + } + + public virtual DateTime ErstellDatum + { + get + { + return this._ErstellDatum; + } + + set + { + if (this.AreDifferent(this._ErstellDatum, value)) + { + this._ErstellDatum = value; + } + } + } + + public virtual long? ApplicationUserOid + { + get + { + return this._ApplicationUserOid; + } + + set + { + if (this.AreDifferent(this._ApplicationUserOid, value)) + { + this._ApplicationUserOid = value; + } + } + } + + public virtual string Salt + { + get { return _Salt; } + + set + { + if (AreDifferent(_Salt, value)) + { + _Salt = value; + } + } + } + + + public virtual string RC2EncryptedHash + { + get + { + string lResult = string.Empty; + var lRc2CSP = new RC2CryptoServiceProvider(); + ICryptoTransform lEncryptor = lRc2CSP.CreateEncryptor(_Rc2Key, _Rc2IV); + + using (var msEncrypt = new MemoryStream()) + { + using (var csEncrypt = new CryptoStream(msEncrypt, lEncryptor, CryptoStreamMode.Write)) + { + byte[] toEncrypt = Encoding.UTF8.GetBytes(Passwort); + + csEncrypt.Write(toEncrypt, 0, toEncrypt.Length); + csEncrypt.FlushFinalBlock(); + + byte[] encrypted = msEncrypt.ToArray(); + lResult = BitConverter.ToString(encrypted); + } + } + if (!String.IsNullOrEmpty(lResult)) + lResult = lResult.Replace("-", "").ToLower(); + + return lResult; + } + } + + } +} \ No newline at end of file diff --git a/Data/Mappings/PasswortVerlauf.hbm.xml b/Data/Mappings/PasswortVerlauf.hbm.xml new file mode 100644 index 000000000..469a24a29 --- /dev/null +++ b/Data/Mappings/PasswortVerlauf.hbm.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Model/Changes_2016_12_21.txt b/Model/Changes_2016_12_21.txt new file mode 100644 index 000000000..d3e49ed3d --- /dev/null +++ b/Model/Changes_2016_12_21.txt @@ -0,0 +1,25 @@ +CREATE TABLE `1234567890`.`passwortverlauf` ( + `Oid` BIGINT(19) NOT NULL +AUTO_INCREMENT COMMENT '', + `ApplicationUserOid` BIGINT(19) NULL COMMENT '', + +`Tid` INT(10) NULL COMMENT '', + `Notice` VARCHAR(1024) NULL COMMENT '', + `InsTs` +DATETIME NULL COMMENT '', + `InsUser` VARCHAR(1024) NULL COMMENT '', + `Version` +BIGINT(19) NULL COMMENT '', + `UdpUser` VARCHAR(256) NULL COMMENT '', + `isActive` +TINYINT(4) NULL COMMENT '', + `SystemEntryID` INT(10) NULL COMMENT '', + `ErstellDatum` +DATETIME NULL COMMENT '', + `Passwort` VARCHAR(64) NULL COMMENT '', + + `Salt` VARCHAR(128) NULL COMMENT '', + + PRIMARY KEY (`Oid`) COMMENT '') +ENGINE = InnoDB +DEFAULT CHARACTER SET = latin1; diff --git a/Service/DCEntityMapper/MapperFactory.cs b/Service/DCEntityMapper/MapperFactory.cs index cb0b6da94..ed8e6fd4c 100644 --- a/Service/DCEntityMapper/MapperFactory.cs +++ b/Service/DCEntityMapper/MapperFactory.cs @@ -45,6 +45,8 @@ namespace BeWo.Service.DCEntityMapper private static CustomerAPPCodeDC_CustomerAPPCode _CustomerAPPCodeDC_CustomerAPPCode; + private static PasswortVerlaufDC_PasswortVerlauf _PasswortVerlaufDC_PasswortVerlauf; + private static ChatMessageDC_ChatMessage _ChatMessageDC_ChatMessage; private static ChatMediaMessageDC_ChatMediaMessage _ChatMediaMessageDC_ChatMediaMessage; @@ -521,6 +523,14 @@ namespace BeWo.Service.DCEntityMapper } } + public static PasswortVerlaufDC_PasswortVerlauf PasswortVerlaufDC_PasswortVerlauf + { + get + { + return _PasswortVerlaufDC_PasswortVerlauf ?? (_PasswortVerlaufDC_PasswortVerlauf = new PasswortVerlaufDC_PasswortVerlauf()); + } + } + public static ChatMessageDC_ChatMessage ChatMessagesDC_ChatMessages { get diff --git a/Service/DCEntityMapper/PasswortVerlaufDC_PasswortVerlauf.cs b/Service/DCEntityMapper/PasswortVerlaufDC_PasswortVerlauf.cs new file mode 100644 index 000000000..75097f10e --- /dev/null +++ b/Service/DCEntityMapper/PasswortVerlaufDC_PasswortVerlauf.cs @@ -0,0 +1,42 @@ +using System.IO; +using BeWo.Data.Entities; + +using BS.Shared.DataContracts; + +namespace BeWo.Service.DCEntityMapper +{ + public class PasswortVerlaufDC_PasswortVerlauf : AbstractIDCEntityMapper + { + public override PasswortVerlaufDC MergeWithDC(PasswortVerlauf pEntity, PasswortVerlaufDC pDataContract) + { + + pDataContract.ApplicationUserOid = pEntity.ApplicationUserOid; + pDataContract.ErstellDatum = pEntity.ErstellDatum; + pDataContract.Passwort = pEntity.Passwort; + pDataContract.Salt = pEntity.Salt; + + return pDataContract; + } + + public override PasswortVerlauf MergeWithEntity(PasswortVerlaufDC pDataContract, PasswortVerlauf pEntity) + { + pEntity.ApplicationUserOid = pDataContract.ApplicationUserOid; + pEntity.ErstellDatum = pDataContract.ErstellDatum; + pEntity.Passwort = pDataContract.Passwort; + pEntity.Salt = pDataContract.Salt; + + return pEntity; + } + + protected override bool AreDCAndEntityEqual(PasswortVerlaufDC pDC, PasswortVerlauf pEntity) + { + + if (pDC.PasswortVerlaufOid == null) + { + return false; + } + + return pDC.PasswortVerlaufOid == pEntity.Oid; + } + } +} \ No newline at end of file diff --git a/Service/Service.csproj b/Service/Service.csproj index 8b1fec752..306789343 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -213,6 +213,7 @@ + diff --git a/Service/ServiceImplementations/UserServiceImp.cs b/Service/ServiceImplementations/UserServiceImp.cs index 133c6e983..2d5d6dfb3 100644 --- a/Service/ServiceImplementations/UserServiceImp.cs +++ b/Service/ServiceImplementations/UserServiceImp.cs @@ -45,6 +45,17 @@ namespace BeWo.Service.ServiceImplementations } } + //speichere passwort in verlauf + var passwortvelauf = new PasswortVerlauf + { + ApplicationUserOid = lOriginal.Oid, + Passwort = lOriginal.HashedPassword, + Salt = lOriginal.Salt, + ErstellDatum = DateTime.Now + }; + + DAOFactory.GenericDAO.Insert(passwortvelauf); + DAOFactory.GenericDAO.Update(lOriginal); return lOriginal.Version.Value; } diff --git a/Shared/BeWoEntityEnums.cs b/Shared/BeWoEntityEnums.cs index 540c8d0cc..724f4e28d 100644 --- a/Shared/BeWoEntityEnums.cs +++ b/Shared/BeWoEntityEnums.cs @@ -877,4 +877,11 @@ namespace BS.Shared Unauthorized, Unknown } + + public enum PasswortSecurityStrength + { + Schwach, + Mittelmass, + Stark + } } \ No newline at end of file diff --git a/Shared/DataContracts/PasswortVerlaufDC.cs b/Shared/DataContracts/PasswortVerlaufDC.cs new file mode 100644 index 000000000..8ae8be163 --- /dev/null +++ b/Shared/DataContracts/PasswortVerlaufDC.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace BS.Shared.DataContracts +{ + [DataContract] + public class PasswortVerlaufDC : IDataContract + { + [DataMember] + public long? PasswortVerlaufOid { get; set; } + + [DataMember] + public long? ApplicationUserOid { get; set; } + + [DataMember] + public string Passwort { get; set; } + + [DataMember] + public DateTime ErstellDatum { get; set; } + + [DataMember] + public string Salt { get; set; } + + } +} \ No newline at end of file diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index e1b1115df..3f2f1b760 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -170,6 +170,7 @@ +