diff --git a/SuperLauncher/CredentialExpirationService.cs b/SuperLauncher/CredentialExpirationService.cs
index a2a905f..f2b1b16 100644
--- a/SuperLauncher/CredentialExpirationService.cs
+++ b/SuperLauncher/CredentialExpirationService.cs
@@ -8,14 +8,18 @@ namespace SuperLauncher
{
public static class CredentialExpirationService
{
- private static Timer Timer = new();
+ private static Timer CheckTimer = new();
+ private static Timer NotifyTimer = new();
public static DateTime PasswordLastSet = DateTime.MaxValue;
- public static TimeSpan MaxPasswordAge = TimeSpan.MaxValue;
+ public static TimeSpan MaxPasswordAge = TimeSpan.Zero;
+ private static ExpStat Status = ExpStat.Unknown;
public static string PasswordExpirationMessage
{
get
{
- return
+ if (Status == ExpStat.NeverExpires) return "Password never expires.";
+ if (Status == ExpStat.DCNotResponding) return "Could not determine password expiration date, Active Directory is offline.";
+ if (Status == ExpStat.Expires) return
"Password expires in " +
ExpirationTimeSpan.Days +
" day(s), " +
@@ -23,6 +27,7 @@ public static string PasswordExpirationMessage
" hour(s) and " +
ExpirationTimeSpan.Seconds +
" second(s).";
+ return "An un-known error occured when determining your password expiration date.";
}
}
public static DateTime PasswordExpirationDate
@@ -41,45 +46,68 @@ public static TimeSpan ExpirationTimeSpan
}
public static void Initialize()
{
- Timer.Elapsed += CheckExpiration;
- Timer.Enabled = true;
- Timer.Interval = 10800000; //3 hours
- Timer.Start();
- CheckExpiration();
+ Task.Run(() => {
+ CheckTimer.Elapsed += CheckTimer_Elapsed;
+ CheckTimer.Enabled = true;
+ CheckTimer.Interval = TimeSpan.FromMinutes(5).TotalMilliseconds;
+ CheckTimer.Start();
+ CheckTimer_Elapsed(null, null);
+ if (Settings.Default.CredentialExpirationWarningIntervalMinutes <= 0) return;
+ NotifyTimer.Elapsed += NotifyTimer_Elapsed;
+ NotifyTimer.Enabled = true;
+ NotifyTimer.Interval = TimeSpan.FromMinutes(Settings.Default.CredentialExpirationWarningIntervalMinutes).TotalMilliseconds;
+ NotifyTimer.Start();
+ NotifyTimer_Elapsed(null, null);
+ });
}
- public static void CheckExpiration(object s = null, object e = null)
+ private static void NotifyTimer_Elapsed(object sender, ElapsedEventArgs e)
{
- Task.Run(() => {
- try
- {
- DirectorySearcher ds = new();
- ds.SearchScope = SearchScope.Base;
- ds.PropertiesToLoad.Clear();
- ds.PropertiesToLoad.Add("maxPwdAge");
- ds.Filter = "";
- SearchResult root = ds.FindOne();
- ds.SearchScope = SearchScope.Subtree;
- ds.PropertiesToLoad.Clear();
- ds.PropertiesToLoad.Add("userAccountControl");
- ds.PropertiesToLoad.Add("pwdLastSet");
- ds.Filter = "(objectSid=" + WindowsIdentity.GetCurrent().User.Value + ")";
- SearchResult user = ds.FindOne();
- bool pwdNeverExpires = (((int)user.Properties["userAccountControl"][0]) & 0x00010000) == 0x00010000; //https://learn.microsoft.com/en-us/windows/win32/api/iads/ne-iads-ads_user_flag_enum
- PasswordLastSet = DateTime.FromFileTime((long)user.Properties["pwdLastSet"][0]);
- MaxPasswordAge = TimeSpan.FromMicroseconds((long)root.Properties["maxPwdAge"][0] / 10 * -1);
- ModernLauncherNotifyIcon.Icon.BalloonTipTitle = RunAsHelper.GetCurrentDomainWithUserName();
- ModernLauncherNotifyIcon.Icon.BalloonTipText = PasswordExpirationMessage;
- ModernLauncherNotifyIcon.Icon.ShowBalloonTip(0);
- }
- catch
+ if (PasswordExpirationDate.CompareTo(DateTime.Now.AddDays(Settings.Default.CredentialExpirationWarningDays)) <= 0)
+ {
+ ModernLauncherNotifyIcon.Icon.BalloonTipTitle = RunAsHelper.GetCurrentDomainWithUserName();
+ ModernLauncherNotifyIcon.Icon.BalloonTipText = PasswordExpirationMessage;
+ ModernLauncherNotifyIcon.Icon.ShowBalloonTip(0);
+ }
+ }
+ private static void CheckTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ try
+ {
+ DirectorySearcher ds = new();
+ ds.SearchScope = SearchScope.Base;
+ ds.PropertiesToLoad.Clear();
+ ds.PropertiesToLoad.Add("maxPwdAge");
+ ds.Filter = "";
+ SearchResult root = ds.FindOne();
+ MaxPasswordAge = TimeSpan.FromMicroseconds((long)root.Properties["maxPwdAge"][0] / 10 * -1);
+ if (MaxPasswordAge == TimeSpan.Zero) { Status = ExpStat.NeverExpires; return; }
+ ds.SearchScope = SearchScope.Subtree;
+ ds.PropertiesToLoad.Clear();
+ ds.PropertiesToLoad.Add("userAccountControl");
+ ds.PropertiesToLoad.Add("pwdLastSet");
+ ds.Filter = "(objectSid=" + WindowsIdentity.GetCurrent().User.Value + ")";
+ SearchResult user = ds.FindOne();
+ PasswordLastSet = DateTime.FromFileTime((long)user.Properties["pwdLastSet"][0]);
+ bool pwdNeverExpires = (((int)user.Properties["userAccountControl"][0]) & 0x00010000) == 0x00010000; //https://learn.microsoft.com/en-us/windows/win32/api/iads/ne-iads-ads_user_flag_enum
+ if (pwdNeverExpires == true) { Status = ExpStat.NeverExpires; return; }
+ Status = ExpStat.Expires;
+ }
+ catch (Exception ex)
+ {
+ if (ex.Source == "System.DirectoryServices")
{
- //Just give up
+ Status = ExpStat.DCNotResponding;
+ return;
}
- });
+ Status = ExpStat.Unknown;
+ }
+ }
+ private enum ExpStat
+ {
+ Expires = 0,
+ NeverExpires = 1,
+ DCNotResponding = 2,
+ Unknown = -1
}
- //private static datetime convertfromadtime()
- //{
-
- //}
}
-}
+}
\ No newline at end of file
diff --git a/SuperLauncher/Settings.cs b/SuperLauncher/Settings.cs
index df0d5c6..e7098ae 100644
--- a/SuperLauncher/Settings.cs
+++ b/SuperLauncher/Settings.cs
@@ -28,6 +28,7 @@ class SettingsDefault
" 390" +
" 230" +
" 7" +
+ " 60" +
"";
public bool AutoElevate
{
@@ -117,6 +118,17 @@ public int CredentialExpirationWarningDays
Write("CredentialExpirationWarningDays", value);
}
}
+ public int CredentialExpirationWarningIntervalMinutes
+ {
+ get
+ {
+ return ReadInt("CredentialExpirationWarningIntervalMinutes");
+ }
+ set
+ {
+ Write("CredentialExpirationWarningIntervalMinutes", value);
+ }
+ }
public string Read(string NodeName)
{
XmlNode node = XDoc.SelectSingleNode("/SuperLauncher/" + NodeName);