示例#1
0
        /// <summary>
        /// Create a log file scanner
        /// </summary>
        /// <param name="failedLogin">Interface for handling failed logins</param>
        /// <param name="dns">Interface for dns lookup</param>
        /// <param name="source">The source, i.e. SSH or SMTP, etc.</param>
        /// <param name="pathAndMask">File path and mask (i.e. /var/log/auth*.log)</param>
        /// <param name="recursive">Whether to parse all sub directories of path and mask recursively</param>
        /// <param name="regex">Regex to parse file lines to pull out ipaddress and username</param>
        /// <param name="maxFileSize">Max size of file before it is deleted or 0 for unlimited</param>
        /// <param name="pingIntervalMilliseconds"></param>
        public IPBanLogFileScanner(IFailedLogin failedLogin, IDnsLookup dns,
                                   string source, string pathAndMask, bool recursive, string regex, long maxFileSize = 0, int pingIntervalMilliseconds = 10000)
        {
            failedLogin.ThrowIfNull(nameof(failedLogin));
            dns.ThrowIfNull(nameof(dns));
            Source             = source;
            this.failedLogin   = failedLogin;
            this.dns           = dns;
            this.maxFileSize   = maxFileSize;
            PathAndMask        = pathAndMask;
            Regex              = IPBanConfig.ParseRegex(regex);
            directoryToWatch   = Path.GetDirectoryName(pathAndMask);
            fileMask           = Path.GetFileName(pathAndMask);
            pingTimer          = new System.Timers.Timer(pingIntervalMilliseconds);
            pingTimer.Elapsed += PingTimerElapsed;
            pingTimer.Start();

            // add initial files
            SearchOption option = (recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            string       dir    = Path.GetDirectoryName(pathAndMask);

            if (Directory.Exists(dir))
            {
                foreach (string existingFileName in Directory.GetFiles(dir, Path.GetFileName(pathAndMask), option))
                {
                    // start at end of existing files
                    AddPingFile(existingFileName, new FileInfo(existingFileName).Length);
                }
            }
        }
        public VotingController(IConferenceLoader conferenceLoader, IDataProvider dataProvider, IDnsLookup dnsLookup, IChartDataConverter chartDataConverter)
        {
            if (conferenceLoader == null)
            {
                throw new ArgumentNullException("conferenceLoader");
            }

            if (dataProvider == null)
            {
                throw new ArgumentNullException("dataProvider");
            }

            if (dnsLookup == null)
            {
                throw new ArgumentNullException("dnsLookup");
            }

            if (chartDataConverter == null)
            {
                throw new ArgumentNullException("chartDataConverter");
            }

            this.conferenceLoader = conferenceLoader;
            this.dataProvider = dataProvider;
            this.dnsLookup = dnsLookup;
            this.chartDataConverter = chartDataConverter;
        }
示例#3
0
        public VotingController(IConferenceLoader conferenceLoader, IDataProvider dataProvider, IDnsLookup dnsLookup, IChartDataConverter chartDataConverter)
        {
            if (conferenceLoader == null)
            {
                throw new ArgumentNullException("conferenceLoader");
            }

            if (dataProvider == null)
            {
                throw new ArgumentNullException("dataProvider");
            }

            if (dnsLookup == null)
            {
                throw new ArgumentNullException("dnsLookup");
            }

            if (chartDataConverter == null)
            {
                throw new ArgumentNullException("chartDataConverter");
            }

            this.conferenceLoader   = conferenceLoader;
            this.dataProvider       = dataProvider;
            this.dnsLookup          = dnsLookup;
            this.chartDataConverter = chartDataConverter;
        }
 public VotingControllerBuilder()
 {
     conferenceLoader   = Substitute.For <IConferenceLoader>();
     dataProvider       = Substitute.For <IDataProvider>();
     dnsLookup          = Substitute.For <IDnsLookup>();
     chartDataConverter = Substitute.For <IChartDataConverter>();
 }
 public VotingControllerBuilder()
 {
     conferenceLoader = Substitute.For<IConferenceLoader>();
     dataProvider = Substitute.For<IDataProvider>();
     dnsLookup = Substitute.For<IDnsLookup>();
     chartDataConverter = Substitute.For<IChartDataConverter>();
 }
示例#6
0
        /// <summary>
        /// Get the local ip address of the local machine
        /// </summary>
        /// <param name="dns">Dns lookup</param>
        /// <param name="addressFamily">Desired address family</param>
        /// <returns>Local ip address or null if unable to determine. If no address family match, falls back to an ipv6 attempt.</returns>
        public static async Task <System.Net.IPAddress> GetLocalIPAddress(this IDnsLookup dns, System.Net.Sockets.AddressFamily addressFamily = System.Net.Sockets.AddressFamily.InterNetwork)
        {
            try
            {
                // append ipv4 first, then the ipv6 then the remote ip
                System.Net.IPAddress[] ips = await dns.GetHostAddressesAsync(Dns.GetHostName());

                foreach (System.Net.IPAddress ip in ips)
                {
                    if (ip.AddressFamily == addressFamily)
                    {
                        return(ip);
                    }
                }
                foreach (System.Net.IPAddress ip in ips)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                    {
                        return(ip);
                    }
                }
            }
            catch
            {
            }
            return(null);
        }
示例#7
0
 public Register(IUnitOfWork repo, IDnsLookup dnsLookup, IHashProvider hashProvider, IPublishEndpoint publisher, ILogger <Register> logger)
 {
     _repo         = repo;
     _dnsLookup    = dnsLookup;
     _hashProvider = hashProvider;
     _logger       = logger;
     _publisher    = publisher;
 }
示例#8
0
 /// <summary>
 /// Load IPBan config from file
 /// </summary>
 /// <param name="configFilePath">Config file path</param>
 /// <param name="service">Service</param>
 /// <param name="dns">Dns lookup for resolving ip addresses</param>
 /// <returns>IPBanConfig</returns>
 public static IPBanConfig LoadFromFile(string configFilePath, IDnsLookup dns)
 {
     configFilePath = (File.Exists(configFilePath) ? configFilePath : ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath);
     if (!File.Exists(configFilePath))
     {
         throw new FileNotFoundException("Unable to find config file " + configFilePath);
     }
     return(LoadFromXml(File.ReadAllText(configFilePath), dns));
 }
示例#9
0
 /// <summary>
 /// Get the local ip addresses of the local machine
 /// </summary>
 /// <param name="dns">Dns lookup</param>
 /// <param name="addressFamily">Desired address family or null for all</param>
 /// <returns>Local ip address or empty array if unable to determine. If no address family match, falls back to an ipv6 attempt.</returns>
 public static async Task <System.Net.IPAddress[]> GetLocalIPAddressesAsync(this IDnsLookup dns, System.Net.Sockets.AddressFamily?addressFamily = System.Net.Sockets.AddressFamily.InterNetwork)
 {
     try
     {
         // append ipv4 first, then the ipv6 then the remote ip
         return((await dns.GetHostAddressesAsync(dns.GetHostName())).Union(localHostIP).Where(i => addressFamily is null || i.AddressFamily == addressFamily).ToArray());
     }
     catch
     {
     }
     return(new System.Net.IPAddress[0]);
 }
示例#10
0
        /// <summary>
        /// Create a log file scanner
        /// </summary>
        /// <param name="options">Options</param>
        public IPBanLogFileScanner(IPBanIPAddressLogFileScannerOptions options) : base(options.PathAndMask, options.MaxFileSizeBytes, options.PingIntervalMilliseconds)
        {
            options.ThrowIfNull(nameof(options));
            options.LoginHandler.ThrowIfNull(nameof(options.LoginHandler));
            options.Dns.ThrowIfNull(nameof(options.Dns));
            Source = options.Source;

            this.loginHandler = options.LoginHandler;
            this.dns          = options.Dns;

            this.regexFailure = IPBanConfig.ParseRegex(options.RegexFailure, true);
            this.regexFailureTimestampFormat = options.RegexFailureTimestampFormat;

            this.regexSuccess = IPBanConfig.ParseRegex(options.RegexSuccess, true);
            this.regexSuccessTimestampFormat = options.RegexSuccessTimestampFormat;
        }
        /// <summary>
        /// Create a log file scanner
        /// </summary>
        /// <param name="options">Options</param>
        public IPBanLogFileScanner(IPBanIPAddressLogFileScannerOptions options) : base(options.PathAndMask, options.MaxFileSizeBytes, options.PingIntervalMilliseconds)
        {
            options.ThrowIfNull(nameof(options));
            options.LoginHandler.ThrowIfNull(nameof(options.LoginHandler));
            options.Dns.ThrowIfNull(nameof(options.Dns));
            Source = options.Source;
            FailedLoginThreshold = options.FailedLoginThreshold;
            FailedLogLevel       = options.FailedLogLevel;
            SuccessfulLogLevel   = options.SuccessfulLogLevel;

            this.loginHandler = options.LoginHandler;
            this.dns          = options.Dns;

            this.regexFailure = options.RegexFailure;
            this.regexFailureTimestampFormat = options.RegexFailureTimestampFormat;

            this.regexSuccess = options.RegexSuccess;
            this.regexSuccessTimestampFormat = options.RegexSuccessTimestampFormat;
        }
示例#12
0
 /// <summary>
 /// Get the ip addresses of the local machine
 /// </summary>
 /// <param name="dns">Dns lookup</param>
 /// <param name="allowLocal">Whether to return localhost ip</param>
 /// <param name="addressFamily">Desired address family or null for all</param>
 /// <returns>Local ip address or empty array if unable to determine. If no address family match, falls back to an ipv6 attempt.</returns>
 public static async Task <System.Net.IPAddress[]> GetLocalIPAddressesAsync(this IDnsLookup dns, bool allowLocal = true, System.Net.Sockets.AddressFamily?addressFamily = System.Net.Sockets.AddressFamily.InterNetwork)
 {
     try
     {
         // append ipv4 first, then the ipv6 then the remote ip
         List <IPAddress> ips = new List <IPAddress>();
         ips.AddRange(await dns.GetHostAddressesAsync(dns.GetHostName()));
         if (allowLocal)
         {
             ips.AddRange(localHostIP);
         }
         return(ips.Where(ip => (allowLocal || ip.IsLocalHost()) ||
                          (addressFamily is null || ip.AddressFamily == addressFamily)).ToArray());
     }
     catch
     {
     }
     return(new System.Net.IPAddress[0]);
 }
示例#13
0
 /// <summary>
 /// Create a log file scanner
 /// </summary>
 /// <param name="failedLogin">Interface for handling failed logins</param>
 /// <param name="dns">Interface for dns lookup</param>
 /// <param name="source">The source, i.e. SSH or SMTP, etc.</param>
 /// <param name="pathAndMask">File path and mask (i.e. /var/log/auth*.log)</param>
 /// <param name="recursive">Whether to parse all sub directories of path and mask recursively</param>
 /// <param name="regex">Regex to parse file lines to pull out ipaddress and username</param>
 /// <param name="maxFileSizeBytes">Max size of file (in bytes) before it is deleted or 0 for unlimited</param>
 /// <param name="pingIntervalMilliseconds">Ping interval in milliseconds, less than 1 for manual ping required</param>
 public IPBanIPAddressLogFileScanner
 (
     IFailedLogin failedLogin,
     IDnsLookup dns,
     string source,
     string pathAndMask,
     bool recursive,
     string regex,
     long maxFileSizeBytes        = 0,
     int pingIntervalMilliseconds = 0
 ) : base(pathAndMask, recursive, maxFileSizeBytes, pingIntervalMilliseconds)
 {
     failedLogin.ThrowIfNull(nameof(failedLogin));
     dns.ThrowIfNull(nameof(dns));
     Source           = source;
     this.failedLogin = failedLogin;
     this.dns         = dns;
     this.regex       = IPBanConfig.ParseRegex(regex);
 }
 /// <summary>
 /// Create a log file scanner
 /// </summary>
 /// <param name="loginHandler">Interface for handling logins</param>
 /// <param name="dns">Interface for dns lookup</param>
 /// <param name="source">The source, i.e. SSH or SMTP, etc.</param>
 /// <param name="pathAndMask">File path and mask (i.e. /var/log/auth*.log)</param>
 /// <param name="recursive">Whether to parse all sub directories of path and mask recursively</param>
 /// <param name="regexFailure">Regex to parse file lines to pull out failed login ipaddress and username</param>
 /// <param name="regexSuccess">Regex to parse file lines to pull out successful login ipaddress and username</param>
 /// <param name="maxFileSizeBytes">Max size of file (in bytes) before it is deleted or 0 for unlimited</param>
 /// <param name="pingIntervalMilliseconds">Ping interval in milliseconds, less than 1 for manual ping required</param>
 public IPBanIPAddressLogFileScanner
 (
     IIPAddressEventHandler loginHandler,
     IDnsLookup dns,
     string source,
     string pathAndMask,
     bool recursive,
     string regexFailure,
     string regexSuccess,
     long maxFileSizeBytes        = 0,
     int pingIntervalMilliseconds = 0
 ) : base(pathAndMask, recursive, maxFileSizeBytes, pingIntervalMilliseconds)
 {
     loginHandler.ThrowIfNull(nameof(loginHandler));
     dns.ThrowIfNull(nameof(dns));
     Source            = source;
     this.loginHandler = loginHandler;
     this.dns          = dns;
     this.regexFailure = IPBanConfig.ParseRegex(regexFailure);
     this.regexSuccess = IPBanConfig.ParseRegex(regexSuccess);
 }
示例#15
0
        /// <summary>
        /// Get the ip addresses of the local machine
        /// </summary>
        /// <param name="dns">Dns lookup</param>
        /// <param name="allowLocal">Whether to return localhost ip</param>
        /// <param name="addressFamily">Desired address family or null for all</param>
        /// <returns>Local ip address or empty array if unable to determine. If no address family match, falls back to an ipv6 attempt.</returns>
        public static async Task <System.Net.IPAddress[]> GetLocalIPAddressesAsync(this IDnsLookup dns, bool allowLocal = true, System.Net.Sockets.AddressFamily?addressFamily = System.Net.Sockets.AddressFamily.InterNetwork)
        {
            try
            {
                // append ipv4 first, then the ipv6 then the remote ip
                List <IPAddress> ips      = new List <IPAddress>();
                string           hostName = await dns.GetHostNameAsync();

                IPAddress[] hostAddresses = await dns.GetHostAddressesAsync(hostName);

                ips.AddRange(hostAddresses);

                // sort ipv4 first
                ips.Sort((ip1, ip2) =>
                {
                    int compare = ip1.AddressFamily.CompareTo(ip2.AddressFamily);
                    if (compare == 0)
                    {
                        compare = ip1.CompareTo(ip2);
                    }
                    return(compare);
                });

                if (allowLocal)
                {
                    ips.AddRange(localHostIP);
                }

                return(ips.Where(ip => (allowLocal || !ip.IsLocalHost()) ||
                                 (addressFamily is null || ip.AddressFamily == addressFamily)).ToArray());
            }
            catch
            {
                // eat exception, delicious
            }
            return(new System.Net.IPAddress[0]);
        }
示例#16
0
 /// <summary>
 /// Load IPBan config from XML
 /// </summary>
 /// <param name="xml">XML string</param>
 /// <param name="dns">Dns lookup for resolving ip addresses, null for default</param>
 /// <param name="dnsList">Dns server list, null for none</param>
 /// <returns>IPBanConfig</returns>
 public static IPBanConfig LoadFromXml(string xml, IDnsLookup dns = null, IDnsServerList dnsList = null)
 {
     return(new IPBanConfig(xml, dns, dnsList));
 }
 public DnsLookupBuilder()
 {
     dnsLookup = Substitute.For<IDnsLookup>();
 }
示例#18
0
        /// <summary>
        /// Get an ip address and user name out of text using regex. Regex may contain groups named source_[sourcename] to override the source.
        /// </summary>
        /// <param name="regex">Regex</param>
        /// <param name="text">Text</param>
        /// <param name="ipAddress">Found ip address or null if none</param>
        /// <param name="userName">Found user name or null if none</param>
        /// <param name="timestampFormat">Timestamp format</param>
        /// <param name="eventType">Event type</param>
        /// <param name="dns">Dns lookup to resolve ip addresses</param>
        /// <returns>Set of matches from text</returns>
        public static IEnumerable <IPAddressLogEvent> GetIPAddressEventsFromRegex(Regex regex, string text,
                                                                                  string timestampFormat = null, IPAddressEventType eventType = IPAddressEventType.FailedLogin, IDnsLookup dns = null)
        {
            const string customSourcePrefix = "source_";

            // if no regex or no text, we are done
            if (regex is null || string.IsNullOrWhiteSpace(text))
            {
                yield break;
            }

            // remove control chars
            text = new string(text.Where(c => c == '\n' || c == '\t' || !char.IsControl(c)).ToArray()).Trim();

            // go through all the matches and pull out event info
            foreach (Match match in regex.Matches(text))
            {
                string   userName  = null;
                string   ipAddress = null;
                string   source    = null;
                DateTime timestamp = default;

                // check for a user name
                Group userNameGroup = match.Groups["username"];
                if (userNameGroup != null && userNameGroup.Success)
                {
                    userName = (userName ?? userNameGroup.Value.Trim(regexTrimChars));
                }

                // check for source
                Group sourceGroup = match.Groups["source"];
                if (sourceGroup != null && sourceGroup.Success)
                {
                    source = (source ?? sourceGroup.Value.Trim(regexTrimChars));
                }

                // check for groups with a custom source name
                foreach (Group group in match.Groups)
                {
                    if (group.Success && group.Name != null &&
                        string.IsNullOrWhiteSpace(source) && group.Name.StartsWith(customSourcePrefix))
                    {
                        source = group.Name.Substring(customSourcePrefix.Length);
                    }
                }

                // check for timestamp group
                Group timestampGroup = match.Groups["timestamp"];
                if (timestampGroup != null && timestampGroup.Success)
                {
                    string toParse = timestampGroup.Value.Trim(regexTrimChars);
                    if (string.IsNullOrWhiteSpace(timestampFormat) ||
                        !DateTime.TryParseExact(toParse, timestampFormat.Trim(), CultureInfo.InvariantCulture,
                                                DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal, out timestamp))
                    {
                        DateTime.TryParse(toParse, CultureInfo.InvariantCulture,
                                          DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal, out timestamp);
                    }
                }

                // check if the regex had an ipadddress group
                Group ipAddressGroup = match.Groups["ipaddress"];
                if (ipAddressGroup is null)
                {
                    ipAddressGroup = match.Groups["ipaddress_exact"];
                }
                if (ipAddressGroup != null && ipAddressGroup.Success && !string.IsNullOrWhiteSpace(ipAddressGroup.Value))
                {
                    string tempIPAddress = ipAddressGroup.Value.Trim();

                    // in case of IP:PORT format, try a second time, stripping off the :PORT, saves having to do this in all
                    //  the different ip regex.
                    int  lastColon        = tempIPAddress.LastIndexOf(':');
                    bool isValidIPAddress = IPAddress.TryParse(tempIPAddress, out IPAddress tmp);
                    if (isValidIPAddress || (lastColon >= 0 && IPAddress.TryParse(tempIPAddress.Substring(0, lastColon), out tmp)))
                    {
                        ipAddress = tmp.ToString();
                    }

                    // if we are parsing anything as ip address (including dns names)
                    if (ipAddress is null && dns != null && ipAddressGroup.Name == "ipaddress" &&
                        tempIPAddress != Environment.MachineName && tempIPAddress != "-")
                    {
                        // Check Host by name
                        Logger.Info("Parsing as IP failed, checking dns '{0}'", tempIPAddress);
                        try
                        {
                            IPHostEntry entry = dns.GetHostEntryAsync(tempIPAddress).Sync();
                            if (entry != null && entry.AddressList != null && entry.AddressList.Length > 0)
                            {
                                ipAddress = entry.AddressList.FirstOrDefault().ToString();
                                Logger.Info("Dns result '{0}' = '{1}'", tempIPAddress, ipAddress);
                                break;
                            }
                        }
                        catch
                        {
                            Logger.Info("Parsing as dns failed '{0}'", tempIPAddress);
                        }
                    }
                }

                // see if there is a repeat indicator in the message
                int repeatCount = ExtractRepeatCount(match, text);

                // return an event for this match
                yield return(new IPAddressLogEvent(ipAddress, userName, source, repeatCount, eventType, timestamp));
            }
        }
示例#19
0
        private IPBanConfig(string xml, IDnsLookup dns)
        {
            this.dns = dns;

            // deserialize with XmlDocument, the .net core Configuration class is quite buggy
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xml);
            foreach (XmlNode node in doc.SelectNodes("//appSettings/add"))
            {
                appSettings[node.Attributes["key"].Value] = node.Attributes["value"].Value;
            }

            GetConfig <int>("FailedLoginAttemptsBeforeBan", ref failedLoginAttemptsBeforeBan);
            GetConfig <TimeSpan>("BanTime", ref banTime);
            GetConfig <bool>("ClearBannedIPAddressesOnRestart", ref clearBannedIPAddressesOnRestart);
            GetConfig <TimeSpan>("ExpireTime", ref expireTime);
            GetConfig <TimeSpan>("CycleTime", ref cycleTime);
            GetConfig <TimeSpan>("MinimumTimeBetweenFailedLoginAttempts", ref minimumTimeBetweenFailedLoginAttempts);
            GetConfig <string>("FirewallRulePrefix", ref firewallRulePrefix);
            GetConfig <bool>("CreateWhitelistFirewallRule", ref createWhitelistFirewallRule);

            string whiteListString      = GetConfig <string>("Whitelist", string.Empty);
            string whiteListRegexString = GetConfig <string>("WhitelistRegex", string.Empty);
            string blacklistString      = GetConfig <string>("Blacklist", string.Empty);
            string blacklistRegexString = GetConfig <string>("BlacklistRegex", string.Empty);

            PopulateList(whiteList, ref whiteListRegex, whiteListString, whiteListRegexString);
            PopulateList(blackList, ref blackListRegex, blacklistString, blacklistRegexString);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                expressions = new XmlSerializer(typeof(ExpressionsToBlock)).Deserialize(new XmlNodeReader(doc.SelectSingleNode("//ExpressionsToBlock"))) as ExpressionsToBlock;
                if (expressions != null)
                {
                    foreach (ExpressionsToBlockGroup group in expressions.Groups)
                    {
                        foreach (ExpressionToBlock expression in group.Expressions)
                        {
                            expression.Regex = (expression.Regex ?? string.Empty).Trim();
                        }
                    }
                }
            }
            else
            {
                expressions = new ExpressionsToBlock {
                    Groups = new ExpressionsToBlockGroup[0]
                };
            }
            try
            {
                LogFilesToParse logFilesToParse = new XmlSerializer(typeof(LogFilesToParse)).Deserialize(new XmlNodeReader(doc.SelectSingleNode("//LogFilesToParse"))) as LogFilesToParse;
                logFiles = (logFilesToParse == null ? new LogFileToParse[0] : logFilesToParse.LogFiles);
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
                logFiles = new LogFileToParse[0];
            }
            GetConfig <string>("ProcessToRunOnBan", ref processToRunOnBan);

            // retrieve firewall configuration
            string[] firewallTypes = GetConfig <string>("FirewallType", string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries);
            foreach (string firewallOSAndType in firewallTypes)
            {
                string[] pieces = firewallOSAndType.Split(':');
                if (pieces.Length == 2)
                {
                    osAndFirewallType[pieces[0]] = pieces[1];
                }
            }

            string userNameWhiteListString = GetConfig <string>("UserNameWhiteList", string.Empty);

            foreach (string userName in userNameWhiteListString.Split(','))
            {
                string userNameTrimmed = userName.Normalize().Trim();
                if (userNameTrimmed.Length > 0)
                {
                    userNameWhitelist.Add(userNameTrimmed);
                }
            }
            GetConfig <int>("UserNameWhiteListMinimumEditDistance", ref userNameWhitelistMaximumEditDistance);
            GetConfig <int>("FailedLoginAttemptsBeforeBanUserNameWhitelist", ref failedLoginAttemptsBeforeBanUserNameWhitelist);
            GetConfig <string>("GetUrlUpdate", ref getUrlUpdate);
            GetConfig <string>("GetUrlStart", ref getUrlStart);
            GetConfig <string>("GetUrlStop", ref getUrlStop);
            GetConfig <string>("GetUrlConfig", ref getUrlConfig);
            GetConfig <string>("ExternalIPAddressUrl", ref externalIPAddressUrl);
        }
示例#20
0
 public DnsLookupBuilder()
 {
     dnsLookup = Substitute.For <IDnsLookup>();
 }
示例#21
0
 internal VelvetService(IDnsLookup dnsLookup)
 {
     this.dnsLookup = dnsLookup;
     this.dnsServer = new DnsServer(IPAddress.Any, 10, 10, dnsLookup.ProcessQuery);
 }
 public VotingControllerBuilder WithDnsLookup(IDnsLookup dnsLookup)
 {
     this.dnsLookup = dnsLookup;
     return(this);
 }
示例#23
0
        /// <summary>
        /// Get an ip address and user name out of text using regex. Regex may contain groups named source_[sourcename] to override the source.
        /// </summary>
        /// <param name="regex">Regex</param>
        /// <param name="text">Text</param>
        /// <param name="ipAddress">Found ip address or null if none</param>
        /// <param name="userName">Found user name or null if none</param>
        /// <param name="timestampFormat">Timestamp format</param>
        /// <param name="eventType">Event type</param>
        /// <param name="dns">Dns lookup to resolve ip addresses</param>
        /// <returns>Set of matches from text</returns>
        public static IEnumerable <IPAddressLogEvent> GetIPAddressEventsFromRegex(Regex regex, string text,
                                                                                  string timestampFormat = null, IPAddressEventType eventType = IPAddressEventType.FailedLogin, IDnsLookup dns = null)
        {
            const string customSourcePrefix = "source_";

            // if no regex or no text, we are done
            if (regex is null || string.IsNullOrWhiteSpace(text))
            {
                yield break;
            }

            // remove control chars
            text = new string(text.Where(c => c == '\n' || c == '\t' || !char.IsControl(c)).ToArray());

            // go through all the matches and pull out event info
            MatchCollection matches = regex.Matches(text);

            foreach (Match match in matches)
            {
                string   userName  = null;
                string   ipAddress = null;
                string   source    = null;
                DateTime timestamp = default;

                // check for a user name
                Group userNameGroup = match.Groups["username"];
                if (userNameGroup != null && userNameGroup.Success)
                {
                    userName ??= userNameGroup.Value.Trim(regexTrimChars);
                }

                // check for source
                Group sourceGroup = match.Groups["source"];
                if (sourceGroup != null && sourceGroup.Success)
                {
                    source ??= sourceGroup.Value.Trim(regexTrimChars);
                }

                // check for groups with a custom source name
                foreach (Group group in match.Groups)
                {
                    if (group.Success && group.Name != null &&
                        string.IsNullOrWhiteSpace(source) && group.Name.StartsWith(customSourcePrefix))
                    {
                        source = group.Name[customSourcePrefix.Length..];
示例#24
0
 /// <summary>
 /// Load IPBan config from XML
 /// </summary>
 /// <param name="xml">XML string</param>
 /// <param name="service">Service</param>
 /// <param name="dns">Dns lookup for resolving ip addresses</param>
 /// <returns>IPBanConfig</returns>
 public static IPBanConfig LoadFromXml(string xml, IDnsLookup dns)
 {
     return(new IPBanConfig(xml, dns));
 }
 public VotingControllerBuilder WithDnsLookup(IDnsLookup dnsLookup)
 {
     this.dnsLookup = dnsLookup;
     return this;
 }
示例#26
0
        /// <summary>
        /// Get an ip address and user name out of text using regex. Regex may contain groups named source_[sourcename] to override the source.
        /// </summary>
        /// <param name="dns">Dns lookup to resolve ip addresses</param>
        /// <param name="regex">Regex</param>
        /// <param name="text">Text</param>
        /// <param name="ipAddress">Found ip address or null if none</param>
        /// <param name="userName">Found user name or null if none</param>
        /// <returns>True if a regex match was found, false otherwise</returns>
        public static IPAddressLogEvent GetIPAddressInfoFromRegex(IDnsLookup dns, Regex regex, string text)
        {
            const string customSourcePrefix = "source_";
            bool         foundMatch         = false;
            string       userName           = null;
            string       ipAddress          = null;
            string       source             = null;
            int          repeatCount        = 1;

            Match repeater = Regex.Match(text, "message repeated (?<count>[0-9]+) times", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);

            if (repeater.Success)
            {
                repeatCount = int.Parse(repeater.Groups["count"].Value, CultureInfo.InvariantCulture);
            }

            foreach (Match m in regex.Matches(text))
            {
                if (!m.Success)
                {
                    continue;
                }

                // check for a user name
                Group userNameGroup = m.Groups["username"];
                if (userNameGroup != null && userNameGroup.Success)
                {
                    userName = (userName ?? userNameGroup.Value.Trim('\'', '\"', '(', ')', '[', ']', '{', '}', ' ', '\r', '\n'));
                }
                Group sourceGroup = m.Groups["source"];
                if (sourceGroup != null && sourceGroup.Success)
                {
                    source = (source ?? sourceGroup.Value.Trim('\'', '\"', '(', ')', '[', ']', '{', '}', ' ', '\r', '\n'));
                }
                if (string.IsNullOrWhiteSpace(source))
                {
                    foreach (Group group in m.Groups)
                    {
                        if (group.Success && group.Name != null && group.Name.StartsWith(customSourcePrefix))
                        {
                            source = group.Name.Substring(customSourcePrefix.Length);
                        }
                    }
                }

                // check if the regex had an ipadddress group
                Group ipAddressGroup = m.Groups["ipaddress"];
                if (ipAddressGroup is null)
                {
                    ipAddressGroup = m.Groups["ipaddress_exact"];
                }
                if (ipAddressGroup != null && ipAddressGroup.Success && !string.IsNullOrWhiteSpace(ipAddressGroup.Value))
                {
                    string tempIPAddress = ipAddressGroup.Value.Trim();

                    // in case of IP:PORT format, try a second time, stripping off the :PORT, saves having to do this in all
                    //  the different ip regex.
                    int  lastColon        = tempIPAddress.LastIndexOf(':');
                    bool isValidIPAddress = IPAddress.TryParse(tempIPAddress, out IPAddress tmp);
                    if (isValidIPAddress || (lastColon >= 0 && IPAddress.TryParse(tempIPAddress.Substring(0, lastColon), out tmp)))
                    {
                        ipAddress  = tmp.ToString();
                        foundMatch = true;
                        break;
                    }

                    // if we are parsing anything as ip address (including dns names)
                    if (ipAddressGroup.Name == "ipaddress" && tempIPAddress != Environment.MachineName && tempIPAddress != "-")
                    {
                        // Check Host by name
                        Logger.Info("Parsing as IP failed, checking dns '{0}'", tempIPAddress);
                        try
                        {
                            IPHostEntry entry = dns.GetHostEntryAsync(tempIPAddress).Sync();
                            if (entry != null && entry.AddressList != null && entry.AddressList.Length > 0)
                            {
                                ipAddress = entry.AddressList.FirstOrDefault().ToString();
                                Logger.Info("Dns result '{0}' = '{1}'", tempIPAddress, ipAddress);
                                foundMatch = true;
                                break;
                            }
                        }
                        catch
                        {
                            Logger.Info("Parsing as dns failed '{0}'", tempIPAddress);
                        }
                    }
                }
                else
                {
                    // found a match but no ip address, that is OK.
                    foundMatch = true;
                }
            }

            return(new IPAddressLogEvent(ipAddress, userName, source, repeatCount, IPAddressEventType.FailedLogin)
            {
                FoundMatch = foundMatch
            });
        }
示例#27
0
        private IPBanConfig(string xml, IDnsLookup dns = null, IDnsServerList dnsList = null, IHttpRequestMaker httpRequestMaker = null)
        {
            this.dns              = dns ?? DefaultDnsLookup.Instance;
            this.dnsList          = dnsList;
            this.httpRequestMaker = httpRequestMaker;

            // deserialize with XmlDocument, the .net core Configuration class is quite buggy
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xml);
            Xml = xml;
            foreach (XmlNode node in doc.SelectNodes("/configuration/appSettings/add"))
            {
                appSettings[node.Attributes["key"].Value] = node.Attributes["value"].Value;
            }

            GetConfig <int>("FailedLoginAttemptsBeforeBan", ref failedLoginAttemptsBeforeBan, 1, 50);
            GetConfig <bool>("ResetFailedLoginCountForUnbannedIPAddresses", ref resetFailedLoginCountForUnbannedIPAddresses);
            GetConfigArray <TimeSpan>("BanTime", ref banTimes, emptyTimeSpanArray);
            for (int i = 0; i < banTimes.Length; i++)
            {
                // according to documentation, a ban time of 0 should become max ban time
                if (banTimes[i].Ticks <= 0)
                {
                    banTimes[i] = maxBanTimeSpan;
                }
                else
                {
                    banTimes[i] = banTimes[i].Clamp(TimeSpan.FromMinutes(1.0), maxBanTimeSpan);
                }
            }
            GetConfig <bool>("ClearBannedIPAddressesOnRestart", ref clearBannedIPAddressesOnRestart);
            GetConfig <bool>("ClearFailedLoginsOnSuccessfulLogin", ref clearFailedLoginsOnSuccessfulLogin);
            GetConfig <TimeSpan>("ExpireTime", ref expireTime, TimeSpan.Zero, maxBanTimeSpan);
            if (expireTime.TotalMinutes < 1.0)
            {
                expireTime = maxBanTimeSpan;
            }
            GetConfig <TimeSpan>("CycleTime", ref cycleTime, TimeSpan.FromSeconds(5.0), TimeSpan.FromMinutes(1.0), false);
            GetConfig <TimeSpan>("MinimumTimeBetweenFailedLoginAttempts", ref minimumTimeBetweenFailedLoginAttempts, TimeSpan.Zero, TimeSpan.FromSeconds(15.0), false);
            GetConfig <string>("FirewallRulePrefix", ref firewallRulePrefix);

            string whitelistString      = GetConfig <string>("Whitelist", string.Empty);
            string whitelistRegexString = GetConfig <string>("WhitelistRegex", string.Empty);
            string blacklistString      = GetConfig <string>("Blacklist", string.Empty);
            string blacklistRegexString = GetConfig <string>("BlacklistRegex", string.Empty);

            PopulateList(whitelist, whitelistRanges, whitelistOther, ref whitelistRegex, whitelistString, whitelistRegexString);
            PopulateList(blackList, blackListRanges, blackListOther, ref blackListRegex, blacklistString, blacklistRegexString);
            XmlNode node2 = doc.SelectSingleNode("/configuration/ExpressionsToBlock");

            if (node2 != null)
            {
                try
                {
                    expressionsFailure = new XmlSerializer(typeof(EventViewerExpressionsToBlock)).Deserialize(new XmlNodeReader(node2)) as EventViewerExpressionsToBlock;
                }
                catch (Exception ex)
                {
                    expressionsFailure = new EventViewerExpressionsToBlock {
                        Groups = new List <EventViewerExpressionGroup>()
                    };
                    Logger.Error("Failed to load expressions to block", ex);
                }
                if (expressionsFailure != null)
                {
                    foreach (EventViewerExpressionGroup group in expressionsFailure.Groups)
                    {
                        foreach (EventViewerExpression expression in group.Expressions)
                        {
                            expression.Regex = (expression.Regex?.ToString() ?? string.Empty).Trim();
                        }
                    }
                }
            }
            node2 = doc.SelectSingleNode("/configuration/ExpressionsToNotify");
            if (node2 != null)
            {
                try
                {
                    expressionsSuccess = new XmlSerializer(typeof(EventViewerExpressionsToNotify)).Deserialize(new XmlNodeReader(node2)) as EventViewerExpressionsToNotify;
                }
                catch (Exception ex)
                {
                    expressionsSuccess = new EventViewerExpressionsToNotify {
                        Groups = new List <EventViewerExpressionGroup>()
                    };
                    Logger.Error("Failed to load expressions to notify: {0}", ex);
                }
                if (expressionsSuccess != null)
                {
                    foreach (EventViewerExpressionGroup group in expressionsSuccess.Groups)
                    {
                        group.NotifyOnly = true;
                        foreach (EventViewerExpression expression in group.Expressions)
                        {
                            expression.Regex = (expression.Regex?.ToString() ?? string.Empty).Trim();
                        }
                    }
                }
            }
            try
            {
                XmlNode logFilesToParseNode = doc.SelectSingleNode("/configuration/LogFilesToParse");
                if (logFilesToParseNode != null && new XmlSerializer(typeof(IPBanLogFilesToParse)).Deserialize(new XmlNodeReader(logFilesToParseNode)) is IPBanLogFilesToParse logFilesToParse)
                {
                    logFiles = logFilesToParse.LogFiles;
                }
                else
                {
                    logFiles = emptyLogFilesToParseArray;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Failed to load log files to parse", ex);
                logFiles = emptyLogFilesToParseArray;
            }
            GetConfig <string>("ProcessToRunOnBan", ref processToRunOnBan);
            GetConfig <bool>("UseDefaultBannedIPAddressHandler", ref useDefaultBannedIPAddressHandler);

            string userNameWhitelistString = GetConfig <string>("UserNameWhitelist", string.Empty);

            if (!string.IsNullOrEmpty(userNameWhitelistString))
            {
                foreach (string userName in userNameWhitelistString.Split(','))
                {
                    string userNameTrimmed = userName.Normalize().ToUpperInvariant().Trim();
                    userNameWhitelist.Add(userNameTrimmed);
                }
            }
            string userNameWhitelistRegexString = GetConfig <string>("UserNameWhitelistRegex", string.Empty);

            if (!string.IsNullOrWhiteSpace(userNameWhitelistRegexString))
            {
                userNameWhitelistRegex = new Regex(userNameWhitelistRegexString, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Singleline);
            }
            GetConfig <int>("UserNameWhitelistMinimumEditDistance", ref userNameWhitelistMaximumEditDistance);
            GetConfig <int>("FailedLoginAttemptsBeforeBanUserNameWhitelist", ref failedLoginAttemptsBeforeBanUserNameWhitelist);
            GetConfig <string>("GetUrlUpdate", ref getUrlUpdate);
            GetConfig <string>("GetUrlStart", ref getUrlStart);
            GetConfig <string>("GetUrlStop", ref getUrlStop);
            GetConfig <string>("GetUrlConfig", ref getUrlConfig);
            GetConfig <string>("ExternalIPAddressUrl", ref externalIPAddressUrl);
            GetConfig <string>("FirewallUriRules", ref firewallUriRules);
            if (string.IsNullOrWhiteSpace(firewallUriRules))
            {
                // legacy
                GetConfig <string>("FirewallUriSources", ref firewallUriRules);
            }
            firewallUriRules = (firewallUriRules ?? string.Empty).Trim();

            // parse firewall block rules, one per line
            ParseFirewallBlockRules();
        }
示例#28
0
        private IPBanConfig(string xml, IDnsLookup dns)
        {
            this.dns = dns;

            // deserialize with XmlDocument, the .net core Configuration class is quite buggy
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xml);
            foreach (XmlNode node in doc.SelectNodes("//appSettings/add"))
            {
                appSettings[node.Attributes["key"].Value] = node.Attributes["value"].Value;
            }

            GetConfig <int>("FailedLoginAttemptsBeforeBan", ref failedLoginAttemptsBeforeBan, 1, 50);
            GetConfig <bool>("ResetFailedLoginCountForUnbannedIPAddresses", ref resetFailedLoginCountForUnbannedIPAddresses);
            GetConfigArray <TimeSpan>("BanTime", ref banTimes, emptyTimeSpanArray);
            for (int i = 0; i < banTimes.Length; i++)
            {
                banTimes[i] = banTimes[i].Clamp(TimeSpan.FromMinutes(1.0), maxBanTimeSpan);
            }
            GetConfig <bool>("ClearBannedIPAddressesOnRestart", ref clearBannedIPAddressesOnRestart);
            GetConfig <TimeSpan>("ExpireTime", ref expireTime, TimeSpan.FromMinutes(1.0), maxBanTimeSpan);
            GetConfig <TimeSpan>("CycleTime", ref cycleTime, TimeSpan.FromSeconds(5.0), TimeSpan.FromMinutes(1.0), false);
            GetConfig <TimeSpan>("MinimumTimeBetweenFailedLoginAttempts", ref minimumTimeBetweenFailedLoginAttempts, TimeSpan.Zero, TimeSpan.FromSeconds(15.0), false);
            GetConfig <string>("FirewallRulePrefix", ref firewallRulePrefix);

            string whiteListString      = GetConfig <string>("Whitelist", string.Empty);
            string whiteListRegexString = GetConfig <string>("WhitelistRegex", string.Empty);
            string blacklistString      = GetConfig <string>("Blacklist", string.Empty);
            string blacklistRegexString = GetConfig <string>("BlacklistRegex", string.Empty);

            PopulateList(whiteList, whiteListRanges, whiteListOther, ref whiteListRegex, whiteListString, whiteListRegexString);
            PopulateList(blackList, blackListRanges, blackListOther, ref blackListRegex, blacklistString, blacklistRegexString);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                XmlNode node = doc.SelectSingleNode("//ExpressionsToBlock");
                if (node != null)
                {
                    expressionsFailure = new XmlSerializer(typeof(EventViewerExpressionsToBlock)).Deserialize(new XmlNodeReader(node)) as EventViewerExpressionsToBlock;
                    if (expressionsFailure != null)
                    {
                        foreach (EventViewerExpressionGroup group in expressionsFailure.Groups)
                        {
                            foreach (EventViewerExpression expression in group.Expressions)
                            {
                                expression.Regex = (expression.Regex?.ToString() ?? string.Empty).Trim();
                            }
                        }
                    }
                }
                node = doc.SelectSingleNode("//ExpressionsToNotify");
                if (node != null)
                {
                    expressionsSuccess = new XmlSerializer(typeof(EventViewerExpressionsToNotify)).Deserialize(new XmlNodeReader(node)) as EventViewerExpressionsToNotify;
                    if (expressionsSuccess != null)
                    {
                        foreach (EventViewerExpressionGroup group in expressionsSuccess.Groups)
                        {
                            group.NotifyOnly = true;
                            foreach (EventViewerExpression expression in group.Expressions)
                            {
                                expression.Regex = (expression.Regex?.ToString() ?? string.Empty).Trim();
                            }
                        }
                    }
                }
            }
            else
            {
                expressionsFailure = new EventViewerExpressionsToBlock();
                expressionsSuccess = new EventViewerExpressionsToNotify();
            }
            try
            {
                if (new XmlSerializer(typeof(IPBanLogFilesToParse)).Deserialize(new XmlNodeReader(doc.SelectSingleNode("//LogFilesToParse"))) is IPBanLogFilesToParse logFilesToParse)
                {
                    logFiles = logFilesToParse.LogFiles;
                }
                else
                {
                    logFiles = emptyLogFilesToParseArray;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                logFiles = new IPBanLogFileToParse[0];
            }
            GetConfig <string>("ProcessToRunOnBan", ref processToRunOnBan);
            GetConfig <bool>("UseDefaultBannedIPAddressHandler", ref useDefaultBannedIPAddressHandler);

            // retrieve firewall configuration
            string[] firewallTypes = GetConfig <string>("FirewallType", string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries);
            foreach (string firewallOSAndType in firewallTypes)
            {
                string[] pieces = firewallOSAndType.Split(':');
                if (pieces.Length == 2)
                {
                    osAndFirewallType[pieces[0]] = pieces[1];
                }
            }

            string userNameWhiteListString = GetConfig <string>("UserNameWhiteList", string.Empty);

            foreach (string userName in userNameWhiteListString.Split(','))
            {
                string userNameTrimmed = userName.Normalize().ToUpperInvariant().Trim();
                if (userNameTrimmed.Length > 0)
                {
                    userNameWhitelist.Add(userNameTrimmed);
                }
            }
            string userNameWhiteListRegexString = GetConfig <string>("UserNameWhiteListRegex", string.Empty);

            if (!string.IsNullOrWhiteSpace(userNameWhiteListRegexString))
            {
                userNameWhitelistRegex = new Regex(userNameWhiteListRegexString, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Singleline);
            }
            GetConfig <int>("UserNameWhiteListMinimumEditDistance", ref userNameWhitelistMaximumEditDistance);
            GetConfig <int>("FailedLoginAttemptsBeforeBanUserNameWhitelist", ref failedLoginAttemptsBeforeBanUserNameWhitelist);
            GetConfig <string>("GetUrlUpdate", ref getUrlUpdate);
            GetConfig <string>("GetUrlStart", ref getUrlStart);
            GetConfig <string>("GetUrlStop", ref getUrlStop);
            GetConfig <string>("GetUrlConfig", ref getUrlConfig);
            GetConfig <string>("ExternalIPAddressUrl", ref externalIPAddressUrl);
            GetConfig <string>("FirewallUriRules", ref firewallUriRules);
            if (string.IsNullOrWhiteSpace(firewallUriRules))
            {
                // legacy
                GetConfig <string>("FirewallUriSources", ref firewallUriRules);
            }
            firewallUriRules = (firewallUriRules ?? string.Empty).Trim();

            // parse firewall block rules, one per line
            ParseFirewallBlockRules();
        }
示例#29
0
 internal VelvetService(IDnsLookup dnsLookup)
 {
     this.dnsLookup = dnsLookup;
     this.dnsServer = new DnsServer(IPAddress.Any, 10, 10, dnsLookup.ProcessQuery);
 }