Browse Source

Add SSL Certificates function

Stuart Johnson 6 months ago
parent
commit
b94faf4cae

+ 24 - 37
.vs/TFA-Bot/xs/UserPrefs.xml

@@ -1,54 +1,38 @@
 <Properties StartupConfiguration="{25609AB4-A77A-4B47-AAB8-B2DB39464A3F}|Default">
   <MonoDevelop.Ide.ItemProperties.TFA-Bot PreferredExecutionTarget="MonoDevelop.Default" />
-  <MonoDevelop.Ide.Workbench ActiveDocument="TFA-Bot/DiscordBot/Commands/clsVersion.cs">
+  <MonoDevelop.Ide.Workbench ActiveDocument="TFA-Bot Status">
     <Files>
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsHelp.cs" Line="44" Column="1" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsNetworks.cs" Line="32" Column="45" />
-      <File FileName="TFA-Bot/DataClasses/clsNetwork.cs" Line="104" Column="38" />
-      <File FileName="TFA-Bot/clsExtenstions.cs" Line="88" Column="1" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsListNodes.cs" Line="21" Column="65" />
-      <File FileName="TFA-Bot/Program.cs" Line="73" Column="72" />
-      <File FileName="TFA-Bot/DataClasses/clsNodeGroup.cs" Line="57" Column="44" />
-      <File FileName="TFA-Bot/DataClasses/clsNode.cs" Line="177" Column="47" />
-      <File FileName="TFA-Bot/DiscordBot/clsBotClient.cs" Line="169" Column="84" />
-      <File FileName="TFA-Bot/clsEmail.cs" Line="96" Column="14" />
-      <File FileName="TFA-Bot/clsAlarm.cs" Line="82" Column="55" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsDiscord.cs" Line="31" Column="13" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsGoodnight.cs" Line="31" Column="1" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsEmail.cs" Line="30" Column="1" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsAlarm.cs" Line="38" Column="31" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/IBotCommand.cs" Line="21" Column="1" />
-      <File FileName="TFA-Bot/DiscordBot/clsCommands.cs" Line="18" Column="53" />
-      <File FileName="TFA-Bot/clsColumnDisplay.cs" Line="20" Column="50" />
-      <File FileName="TFA-Bot/Spreadsheet/clsSpreadsheet.cs" Line="75" Column="17" />
-      <File FileName="TFA-Bot/Spreadsheet/ASheetColumnHeader.cs" Line="1" Column="1" />
-      <File FileName="TFA-Bot/Spreadsheet/ISpreadsheet.cs" Line="1" Column="1" />
-      <File FileName="TFA-Bot/Utils/clsRollingAverage.cs" Line="48" Column="1" />
-      <File FileName="TFA-Bot/Spreadsheet/clsSpreadsheetReader.cs" Line="17" Column="40" />
-      <File FileName="entrypoint.sh" Line="7" Column="21" />
-      <File FileName="TFA-Bot/Dialler/clsDiallerTwilio.cs" Line="41" Column="51" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsBotControl.cs" Line="30" Column="84" />
-      <File FileName="TFA-Bot/Git/clsGitBranchInfo.cs" Line="1" Column="1" />
+      <File FileName="TFA-Bot/DataClasses/clsSSLCerts.cs" Line="14" Column="41" />
+      <File FileName="TFA-Bot/DataClasses/clsSetting.cs" Line="1" Column="1" />
+      <File FileName="TFA-Bot/DataClasses/clsNotificationPolicy.cs" Line="1" Column="1" />
+      <File FileName="TFA-Bot/Spreadsheet/clsSpreadsheet.cs" Line="31" Column="1" />
+      <File FileName="TFA-Bot/Spreadsheet/clsSpreadsheetReader.cs" Line="44" Column="1" />
+      <File FileName="TFA-Bot/DataClasses/clsNode.cs" Line="192" Column="1" />
+      <File FileName="TFA-Bot/DataClasses/clsUser.cs" Line="1" Column="1" />
+      <File FileName="TFA-Bot/Program.cs" Line="181" Column="52" />
+      <File FileName="TFA-Bot/clsAlarm.cs" Line="82" Column="65" />
+      <File FileName="TFA-Bot/clsSSLCertMonitor.cs" Line="95" Column="76" />
+      <File FileName="TFA-Bot/DiscordBot/Commands/clsSSL.cs" Line="50" Column="77" />
+      <File FileName="TFA-Bot/DiscordBot/clsBotClient.cs" Line="105" Column="1" />
+      <File FileName="TFA-Bot/clsEmail.cs" Line="42" Column="23" />
+      <File FileName="TFA-Bot/Spreadsheet/ASheetColumnHeader.cs" Line="23" Column="35" />
+      <File FileName="TFA-Bot/DiscordBot/Commands/clsHelp.cs" Line="24" Column="60" />
+      <File FileName="TFA-Bot/DiscordBot/clsCommands.cs" Line="115" Column="17" />
+      <File FileName="TFA-Bot/clsExtenstions.cs" Line="1" Column="1" />
       <File FileName="TFA-Bot/Git/clsGitHead.cs" Line="1" Column="1" />
-      <File FileName="TFA-Bot/Git/clsGit.cs" Line="61" Column="17" />
-      <File FileName="TFA-Bot/Git/AssemblyGitCommit.cs" Line="13" Column="2" />
-      <File FileName="TFA-Bot/clsVersion.cs" Line="25" Column="47" />
       <File FileName="TFA-Bot Status" />
-      <File FileName="TFA-Bot/DiscordBot/Commands/clsVersion.cs" Line="1" Column="1" />
     </Files>
     <Pads>
       <Pad Id="ProjectPad">
         <State name="__root__">
-          <Node name="TFA-Bot" expanded="True">
+          <Node name="TFA-Bot" expanded="True" selected="True">
             <Node name="Solution Items" expanded="True" />
             <Node name="TFA-Bot" expanded="True">
               <Node name="Packages" expanded="True" />
               <Node name="DataClasses" expanded="True" />
               <Node name="Dialler" expanded="True" />
               <Node name="DiscordBot" expanded="True">
-                <Node name="Commands" expanded="True">
-                  <Node name="clsVersion.cs" selected="True" />
-                </Node>
+                <Node name="Commands" expanded="True" />
               </Node>
               <Node name="Git" expanded="True" />
               <Node name="Spreadsheet" expanded="True" />
@@ -65,7 +49,10 @@
   <MonoDevelop.Ide.DebuggingService.PinnedWatches />
   <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" />
   <MonoDevelop.Ide.DebuggingService.Breakpoints>
-    <BreakpointStore />
+    <BreakpointStore>
+      <Breakpoint file="/HOME/Projects/TFA-Bot/TFA-Bot/DiscordBot/Commands/clsSSL.cs" relfile="TFA-Bot/DiscordBot/Commands/clsSSL.cs" line="71" column="33" />
+      <Breakpoint file="/HOME/Projects/TFA-Bot/TFA-Bot/clsSSLCertMonitor.cs" relfile="TFA-Bot/clsSSLCertMonitor.cs" line="89" column="70" />
+    </BreakpointStore>
   </MonoDevelop.Ide.DebuggingService.Breakpoints>
   <MultiItemStartupConfigurations />
 </Properties>

+ 33 - 0
TFA-Bot/DataClasses/clsSSLCerts.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.ObjectModel;
+
+namespace TFABot
+{
+    public class clsSSLCerts : ISpreadsheet<clsSSLCerts>
+    {
+        public clsSSLCerts()
+        {
+        }
+
+        [ASheetColumnHeader(true,"url")]
+        public String URL {get;set;}
+        [ASheetColumnHeader("contacts")]
+        public String Contacts {get;set;}
+        
+        public DateTime CertExpiry {get;set;}
+        
+        
+        public void Update(clsSSLCerts user)
+        {
+            if (URL != user.URL) throw new Exception("index name does not match");
+            
+            Contacts = user.Contacts;
+        }
+        
+        public String PostPopulate()
+        {            
+            return null;
+        }
+
+    }
+}

+ 81 - 0
TFA-Bot/DiscordBot/Commands/clsSSL.cs

@@ -0,0 +1,81 @@
+using System;
+using System.Net;
+using System.Security.Cryptography.X509Certificates;
+using System.Text.RegularExpressions;
+using DSharpPlus.EventArgs;
+
+namespace TFABot.DiscordBot.Commands
+{
+    public class clsSSL : IBotCommand
+    {
+    
+        public String[] MatchCommand {get; private set;}
+        public String[] MatchSubstring {get; private set;}
+        public Regex[] MatchRegex {get; private set;}
+        
+        public clsSSL()
+        {
+            MatchCommand = new []{"ssl"};
+        }
+
+        void IBotCommand.Run(MessageCreateEventArgs e)
+        {
+
+            try
+            {
+
+                if (e.Message.Content == "ssl")
+                {
+                    var cd = new clsColumnDisplay();
+                    cd.ColumnChar=' ';
+                    cd.Append("```");
+                    cd.AppendLine($"SSL Certificates checked {clsSSLCertMonitor.LastTest.Value:yyyy-MM-dd HH:mm}");
+                    cd.AppendCol("URL");
+                    cd.AppendCol("Days");                     
+                    cd.AppendCharLine('-');
+
+                    foreach (var ssl in Program.SSLCertsList.Values)
+                    {
+                        cd.AppendCol(ssl.URL);                        
+                        cd.AppendCol((ssl.CertExpiry - DateTime.UtcNow).Days.ToString());
+                        cd.NewLine();
+                    }
+                    cd.Append("```");
+                    e.Channel.SendMessageAsync(cd.ToString());
+                    
+                }
+                else if (e.Message.Content.Length>4)
+                {
+                    var url = e.Message.Content.Substring(4).Trim();
+                    if (!url.StartsWith("https://")) url = $"https://{url}";
+
+                    HttpWebRequest request;
+                    request = (HttpWebRequest)WebRequest.Create(url);
+                    try
+                    {
+                        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
+                        response.Close();
+                    }
+                    catch { }
+                    
+                    
+                    var cert = request.ServicePoint.Certificate;
+                    var cert2 = new X509Certificate2(cert);
+                    var days = (DateTime.Parse(cert2.GetExpirationDateString()) - DateTime.UtcNow).Days;
+                    e.Channel.SendMessageAsync($"{days} days");
+                    
+                }
+            }
+            catch (Exception ex)
+            {
+                e.Channel.SendMessageAsync(ex.Message);
+            }
+
+        }
+
+        public void HelpString (ref clsColumnDisplay columnDisplay)
+        {
+            columnDisplay.AppendCol("ssl","<https url>");
+        }
+    }
+}

+ 1 - 1
TFA-Bot/Git/clsGitHead.cs

@@ -59,7 +59,7 @@ namespace TFABot.Git
             }
             catch (Exception ex)
             {
-                return $"Git unavailabe {ex.Message}";
+                return $"Git unavailabe";
             }
         }
         

+ 3 - 0
TFA-Bot/Program.cs

@@ -35,6 +35,7 @@ namespace TFABot
         static public Dictionary<string,clsNode> NodesList = new Dictionary<string, clsNode>();
         static public Dictionary<string,clsNodeGroup> NodeGroupList = new Dictionary<string, clsNodeGroup>();
         static public Dictionary<string,clsNotificationPolicy> NotificationPolicyList = new Dictionary<string, clsNotificationPolicy>();
+        static public Dictionary<string,clsSSLCerts> SSLCertsList = new Dictionary<string, clsSSLCerts>();
         
         static public DateTime AppStarted = DateTime.UtcNow;
         static public clsAlarmManager AlarmManager = new clsAlarmManager();
@@ -176,6 +177,8 @@ namespace TFABot
                         {
                             BotErrorCounter = 0;
                         }
+
+                        clsSSLCertMonitor.HeartbeatCheck();
                           
                        ApplicationHold.WaitOne(loopWait);
                     }

+ 4 - 2
TFA-Bot/Spreadsheet/clsSpreadsheet.cs

@@ -25,9 +25,11 @@ namespace TFABot
                 ReadSheet<clsNotificationPolicy>("NotificationPolicy",Program.NotificationPolicyList,sb);
                 ReadSheet<clsNetwork>("Networks",Program.NetworkList,sb);
                 ReadSheet<clsUser>("Users",Program.UserList,sb);
-                ReadSheet<clsNodeGroup>("NodeGroups",Program.NodeGroupList,sb);
-                
+                ReadSheet<clsNodeGroup>("NodeGroups",Program.NodeGroupList,sb);                
                 ReadSheet<clsNode>("Nodes",Program.NodesList,sb);
+                
+                ReadSheet<clsSSLCerts>("SSLCerts",Program.SSLCertsList,sb);
+                
             }
             catch (Exception ex)
             {

+ 3 - 0
TFA-Bot/TFA-Bot.csproj

@@ -142,6 +142,9 @@
     <Compile Include="clsEmail.cs" />
     <Compile Include="DiscordBot\Commands\clsEmail.cs" />
     <Compile Include="DiscordBot\Commands\clsDiscord.cs" />
+    <Compile Include="DiscordBot\Commands\clsSSL.cs" />
+    <Compile Include="DataClasses\clsSSLCerts.cs" />
+    <Compile Include="clsSSLCertMonitor.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />

+ 1 - 1
TFA-Bot/clsEmail.cs

@@ -39,7 +39,7 @@ namespace TFABot
         }
         
         
-        static Task SendEmail(String To, String Subject, String Message,DSharpPlus.Entities.DiscordChannel ChBotAlert = null)
+        static public Task SendEmail(String To, String Subject, String Message,DSharpPlus.Entities.DiscordChannel ChBotAlert = null)
         {
            Task task = null; 
            

+ 100 - 0
TFA-Bot/clsSSLCertMonitor.cs

@@ -0,0 +1,100 @@
+using System;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+using DiscordBot;
+
+
+namespace TFABot
+{
+    public class clsSSLCertMonitor
+    {
+        static public DateTime? LastTest = null;
+        
+        public clsSSLCertMonitor()
+        {
+            
+        }
+
+        internal static void HeartbeatCheck()
+        {
+            if (!LastTest.HasValue || (DateTime.UtcNow - LastTest.Value).Hours >= 24)
+            {
+                Console.WriteLine("clsSSLCertMonitor: HeartbeatCheck");
+                LastTest = DateTime.UtcNow;
+
+                Task.Run(() =>
+                {
+                    foreach (var ssl in Program.SSLCertsList.Values)
+                    {
+                        CheckSSL(ssl);
+                    }
+                });
+            }
+        }
+
+        private static async void CheckSSL(clsSSLCerts ssl)
+        {       
+            try
+            {
+                var url = ssl.URL.Trim();
+                if (!url.StartsWith("https://")) url = $"https://{url}";
+
+                var uri = new Uri(url);
+
+                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
+
+                HttpWebResponse response;
+                try
+                {
+                    response = (HttpWebResponse)request.GetResponse();
+                    response.Close();
+                }
+                catch { }
+                
+                
+                var cert = request.ServicePoint.Certificate;
+                var cert2 = new X509Certificate2(cert);
+                
+                ssl.CertExpiry = DateTime.Parse(cert2.GetExpirationDateString());
+                var days = (ssl.CertExpiry - DateTime.UtcNow).Days;
+
+                if (days <= 7) SendMessage(ssl, $"{ssl.URL} certificate expires in {days} days");
+                
+            }
+            catch (Exception ex)
+            {
+                SendMessage(ssl, $"{ssl.URL} certificate read error");
+            }
+        }
+
+        private static void SendMessage(clsSSLCerts ssl, string messageText)
+        {
+            foreach (var user in ssl.Contacts.Split(';'))
+            {
+                if (user.StartsWith("@"))
+                {
+                    var hashsplit = user.Split('#');
+                    if (hashsplit.Length == 2)
+                    {
+                        try
+                        {
+                            var discordUser = clsBotClient.Instance.Our_BotAlert.Guild.Members.FirstOrDefault(x => x.Discriminator == hashsplit[1]);
+                            discordUser.SendMessageAsync(messageText);
+                        }
+                        catch (Exception ex)
+                        {
+                            Console.WriteLine($"Error {ex.Message}");
+                        }
+                    }                    
+                }
+                else if (user.Contains("@"))
+                {
+                    clsEmail.SendEmail(user,"SSL Certificate",messageText);
+                }
+            }
+        }
+    }
+}