/// <summary> /// Checks whether an IP address matches to an exception rule /// </summary> /// <param name="ipAddress">The IP address to check</param> /// <param name="exceptionRule">The exception rule to match it against</param> /// <returns>True if the IP address matches to the exception rule. False otherwise</returns> private bool IpAddressMatchesExceptionRule(IPAddress ipAddress, ExceptionRule exceptionRule) { if (String.IsNullOrEmpty(exceptionRule.Mask) && IPAddress.Parse(exceptionRule.IpAddress).Equals(ipAddress)) { return(true); } if (!String.IsNullOrEmpty(exceptionRule.Mask) && IPUtilities.IsInSameSubnet(ipAddress, exceptionRule.IpAddress, exceptionRule.Mask)) { return(true); } return(false); }
/// <summary> /// Checks for conflicts between the new rule and the existing exception rules /// </summary> /// <param name="newRule">The new rule to check</param> /// <returns>True if there is no conflict. False otherwise</returns> private bool CheckNewRule(ExceptionRule newRule) { foreach (ExceptionRule existingRule in this.existingRules) { if (String.IsNullOrEmpty(newRule.Mask)) { if (String.IsNullOrEmpty(existingRule.Mask)) { if (newRule.IpAddress.Equals(existingRule.IpAddress)) { if (newRule.AllowedMode == existingRule.AllowedMode) { MessageBox.Show(this, "This exception rule allready exists", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return(false); } else { MessageBox.Show(this, "This exception rule conflicts with rule: " + existingRule.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return(false); } } } else { if (IPUtilities.IsInSameSubnet(newRule.IpAddress, existingRule.IpAddress, existingRule.Mask)) { if (newRule.AllowedMode == existingRule.AllowedMode) { DialogResult result = MessageBox.Show(this, "This exception rule overlaps with rule: " + existingRule.ToString() + ". Add it anyway?", this.Text, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) { return(true); } else { return(false); } } else { MessageBox.Show(this, "This exception rule conflicts with rule: " + existingRule.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return(false); } } } } else { if (String.IsNullOrEmpty(existingRule.Mask)) { if (IPUtilities.IsInSameSubnet(existingRule.IpAddress, newRule.IpAddress, newRule.Mask)) { if (newRule.AllowedMode == existingRule.AllowedMode) { DialogResult result = MessageBox.Show(this, "This exception rule overlaps with rule: " + existingRule.ToString() + ". Add it anyway?", this.Text, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) { return(true); } else { return(false); } } else { MessageBox.Show(this, "This exception rule conflicts with rule: " + existingRule.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return(false); } } } else { if (IPUtilities.IsInSameSubnet(newRule.IpAddress, existingRule.IpAddress, existingRule.Mask) || IPUtilities.IsInSameSubnet(existingRule.IpAddress, newRule.IpAddress, newRule.Mask)) { if (newRule.AllowedMode == existingRule.AllowedMode) { DialogResult result = MessageBox.Show(this, "This exception rule overlaps with rule: " + existingRule.ToString() + ". Add it anyway?", this.Text, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) { return(true); } else { return(false); } } else { MessageBox.Show(this, "This exception rule conflicts with rule: " + existingRule.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return(false); } } } } } return(true); }
/// <summary> /// Checks the country to which the ip's belong to and determines whether or not access is denied or allowed /// </summary> /// <param name="ipAddressesToCheck">The ip addresses to check</param> /// <param name="resultMessage">An explanation of the result</param> /// <returns>True if access is allowed. False otherwise</returns> /// <remarks>All IP addresses must be allowed for the request to be allowed</remarks> public bool Allowed(List <System.Net.IPAddress> ipAddressesToCheck, out string resultMessage) { if (ipAddressesToCheck == null || ipAddressesToCheck.Count == 0) { resultMessage = "No valid IP found in request"; return(false); } using (var reader = new MaxMind.GeoIP2.DatabaseReader(geoIpFilepath, MaxMind.Db.FileAccessMode.MemoryMapped)) { //sanity check if (reader == null) { resultMessage = "IP check failed"; return(true); } foreach (System.Net.IPAddress ipAddress in ipAddressesToCheck) { //first check if the IP is a private ip. It turns out that proxy servers put private ip addresses in the X_FORWARDED_FOR header. //we won't base our geoblocking on private ip addresses if (IPUtilities.IsPrivateIpAddress(ipAddress)) { continue; } //next check the exception rules bool matchedOnExceptionRule = false; bool allowedByExceptionRule = false; foreach (ExceptionRule exceptionRule in exceptionRules) { if (IpAddressMatchesExceptionRule(ipAddress, exceptionRule)) { matchedOnExceptionRule = true; if (exceptionRule.AllowedMode) { allowedByExceptionRule = true; } else { allowedByExceptionRule = false; //one IP denied = deny access alltogether break; } } } if (matchedOnExceptionRule) { if (allowedByExceptionRule) { //IP found that matches an allow exception rule, don't check the country //We continue if verifyAll is specified, because another IP could be denied if (verifyAll) { continue; } else { break; } } else { //IP found that matches a deny exception rule, deny access immediately resultMessage = "Blocked IP: [" + ipAddress.ToString() + "]"; return(false); } } if (reader.Metadata.DatabaseType.ToLower().IndexOf("country") == -1) { throw new System.InvalidOperationException("This is not a GeoLite2-Country or GeoIP2-Country database"); } string countryCode = string.Empty; //not found in exception rule, so base access rights on the country try { MaxMind.GeoIP2.Responses.CountryResponse countryResponse = reader.Country(ipAddress); countryCode = !string.IsNullOrEmpty(countryResponse.Country.IsoCode) ? countryResponse.Country.IsoCode : !string.IsNullOrEmpty(countryResponse.RegisteredCountry.IsoCode) ? countryResponse.RegisteredCountry.IsoCode : string.Empty; } catch (MaxMind.GeoIP2.Exceptions.AddressNotFoundException) { } catch (MaxMind.GeoIP2.Exceptions.PermissionRequiredException) { } catch (MaxMind.GeoIP2.Exceptions.GeoIP2Exception) { } finally { if (string.IsNullOrEmpty(countryCode)) { countryCode = "--"; } } bool selected = CountryCodeSelected(countryCode); bool allowed = (selected == allowedMode); /* * allowedmode selected allowed * 1 1 1 * 1 0 0 * 0 1 0 * 0 0 1 */ if (!allowed) { resultMessage = "Blocked IP: [" + ipAddress.ToString() + "] from [" + countryCode + "]"; return(false); } else { // If a proxy in HTTP_X_FORWARDED_FOR should be ignored if previous checked ip matches previous found country or exceptionRule if (!verifyAll) { break; } } } } resultMessage = "None"; return(true); }