/// <summary> /// Puts the values from the page into the configuration /// </summary> protected override bool ApplyChanges() { this.moduleConfiguration.Enabled = enabledCB.Checked; this.moduleConfiguration.VerifyAll = verifyAllCB.Checked; this.moduleConfiguration.DenyAction = (comboBoxDenyAction.SelectedItem as ComboboxItem).Value.ToString(); this.moduleConfiguration.AllowedMode = allowedRB.Checked; this.moduleConfiguration.GeoIpFilepath = geoIpFilepathTB.Text; this.moduleConfiguration.SelectedCountryCodes.Clear(); foreach (Country geoblockItem in selectedCountryCodesLB.CheckedItems) { this.moduleConfiguration.SelectedCountryCodes.Add(geoblockItem); } this.moduleConfiguration.ExceptionRules.Clear(); foreach (DataGridViewRow row in this.exceptionRulesDGV.Rows) { ExceptionRule item = (ExceptionRule)row.DataBoundItem; this.moduleConfiguration.ExceptionRules.Add(item); } UpdateConfiguration(); hasChanges = false; this.Update();//reloads tasks return(true); }
/// <summary> /// Fired when the user clicks the OK button. Checks if the user input is valid. If so, it sets the exception rule and closes the form /// </summary> /// <param name="sender">Not used</param> /// <param name="e">Not used</param> private void BOk_Click(object sender, EventArgs e) { if (RBSpecificIpAddress.Checked) { IPAddress ip; if (!IPAddress.TryParse(TBSpecificIpAddress.Text, out ip)) { MessageBox.Show(this, "'" + TBSpecificIpAddress.Text + "' is an invalid IP address.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } else { //We will check against existing exception rules if there is a conflict or overlap ExceptionRule newRule = new ExceptionRule(this.AllowMode, ip.ToString(), null); if (CheckNewRule(newRule)) { this.exceptionRule = newRule; this.DialogResult = DialogResult.OK; this.Close(); } } } else { IPAddress range; IPAddress mask; if (!IPAddress.TryParse(TBAddressRange.Text, out range)) { MessageBox.Show(this, "'" + TBAddressRange.Text + "' is an invalid IP address.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } if (!IPAddress.TryParse(TBMask.Text, out mask)) { MessageBox.Show(this, "'" + TBMask.Text + "' is an invalid subnet mask.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } try { var cidr = IPAddressRange.Parse(TBAddressRange.Text + "/" + TBMask.Text).ToCidrString(); } catch { MessageBox.Show(this, "'" + TBMask.Text + "' is an invalid subnet mask.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } //We will check against existing exception rules if there is a conflict or overlap ExceptionRule newRule = new ExceptionRule(this.AllowMode, range.ToString(), mask.ToString()); if (CheckNewRule(newRule)) { this.exceptionRule = newRule; this.DialogResult = DialogResult.OK; this.Close(); } } }
/// <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> /// Handles the begin request event. this is the place where the actual check is performed /// </summary> /// <param name="sender">The HttpApplication to extract the request from</param> /// <param name="e">Not used</param> void context_BeginRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; //Get module config GeoblockConfigurationSection moduleConfiguration = (GeoblockConfigurationSection)WebConfigurationManager.GetSection(context, GeoblockConfigurationSection.SectionName, typeof(GeoblockConfigurationSection)); if (!moduleConfiguration.Enabled) { return; } //Get the ip's of the request. All the IP's must be checked List <System.Net.IPAddress> ipAddressesToCheck = new List <System.Net.IPAddress>(); string ipNotificationString = string.Empty; try { string ip = context.Request.UserHostAddress; ipNotificationString += "Request IP: [" + ip + "]"; System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse(ip.Trim()); ipAddressesToCheck.Add(ipAddress); } catch { } //Could be behind proxy, so check forwarded IP's string forwardedIps = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (!String.IsNullOrEmpty(forwardedIps)) { ipNotificationString += " Forwarded IP's: [" + forwardedIps + "]"; //The HTTP_X_FORWARDED_FOR value can contain more then one entry (, seperated) string[] ips = forwardedIps.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string ip in ips) { try { System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse(ip.Trim()); ipAddressesToCheck.Add(ipAddress); } catch { } } } string[] selectedCountryCodes = new string[moduleConfiguration.SelectedCountryCodes.Count]; int i = 0; foreach (CountryConfigurationElement country in moduleConfiguration.SelectedCountryCodes) { selectedCountryCodes[i] = country.Code; i++; } ExceptionRule[] exceptionRules = new ExceptionRule[moduleConfiguration.ExceptionRules.Count]; i = 0; foreach (ExceptionRuleConfigurationElement exceptionRule in moduleConfiguration.ExceptionRules) { exceptionRules[i] = new ExceptionRule(exceptionRule.AllowedMode, exceptionRule.IpAddress, exceptionRule.Mask); i++; } //Perform the check string resultMessage; Geoblocker geoBlocker = new Geoblocker(moduleConfiguration.GeoIpFilepath, selectedCountryCodes, moduleConfiguration.AllowedMode, exceptionRules); if (!geoBlocker.Allowed(ipAddressesToCheck, out resultMessage)) { switch (moduleConfiguration.DenyAction) { case "Unauthorized": context.Response.StatusCode = 401; context.Response.SubStatusCode = 503; context.Response.StatusDescription = "IP is blocked by GeoIP2block Module. " + ipNotificationString + ". " + resultMessage; context.Response.SuppressContent = true; context.Response.End(); break; case "Forbidden": context.Response.StatusCode = 403; context.Response.SubStatusCode = 503; context.Response.StatusDescription = "IP is blocked by GeoIP2block Module. " + ipNotificationString + ". " + resultMessage; context.Response.SuppressContent = true; context.Response.End(); break; case "NotFound": context.Response.StatusCode = 404; context.Response.SubStatusCode = 503; context.Response.StatusDescription = "IP is blocked by GeoIP2block Module. " + ipNotificationString + ". " + resultMessage; context.Response.SuppressContent = true; context.Response.End(); break; case "Abort": context.Request.Abort(); break; } } }
/// <summary> /// Handles the begin request event. this is the place where the actual check is performed /// </summary> /// <param name="sender">The HttpApplication to extract the request from</param> /// <param name="e">Not used</param> void context_BeginRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; //Get module config GeoblockConfigurationSection moduleConfiguration = (GeoblockConfigurationSection)WebConfigurationManager.GetSection(context, GeoblockConfigurationSection.SectionName, typeof(GeoblockConfigurationSection)); if (!moduleConfiguration.Enabled) { return; } //Get the ip's of the request. All the IP's must be checked List <System.Net.IPAddress> ipAddressesToCheck = new List <System.Net.IPAddress>(); string ipNotificationString = string.Empty; try { string ip = context.Request.UserHostAddress; #if DEBUG this.DbgWrite(string.Format("REMOTE_ADDR: {0}", ip)); #endif ipNotificationString += "Request IP: [" + ip + "]"; System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse(ip.Trim()); ipAddressesToCheck.Add(ipAddress); } catch { } //Could be behind proxy, so check forwarded IP's string forwardedIps = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; #if DEBUG this.DbgWrite(string.Format("HTTP_X_FORWARDED_FOR: {0}", forwardedIps)); #endif if (!String.IsNullOrEmpty(forwardedIps)) { ipNotificationString += " Forwarded IP's: [" + forwardedIps + "]"; //The HTTP_X_FORWARDED_FOR value can contain more then one entry (, seperated) string[] ips = forwardedIps.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string ip in ips) { try { System.Net.IPAddress ipAddress; // Forwarded IP's in Application Request Routing might contain port if (ip.Contains(":")) { ipAddress = System.Net.IPAddress.Parse(ip.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[0].Trim()); } else { ipAddress = System.Net.IPAddress.Parse(ip.Trim()); } ipAddressesToCheck.Add(ipAddress); } catch { } } } // Make new unique list List <System.Net.IPAddress> ipAddressesToCheckUnique = ipAddressesToCheck.Distinct().ToList(); #if DEBUG ArrayList ipToCheck = new ArrayList(); foreach (IPAddress ipAddress in ipAddressesToCheckUnique) { ipToCheck.Add(ipAddress.ToString()); } this.DbgWrite(string.Format("Requestor IP address('s): {0}{1}", GeoblockHttpModule.ConvertStringArrayToStringJoin((string[])ipToCheck.ToArray(typeof(string))), Environment.NewLine)); #endif string[] selectedCountryCodes = new string[moduleConfiguration.SelectedCountryCodes.Count]; int i = 0; foreach (CountryConfigurationElement country in moduleConfiguration.SelectedCountryCodes) { selectedCountryCodes[i] = country.Code; i++; } #if DEBUG this.DbgWrite(string.Format("CountryCodes: {0} AllowedMode: {1}{2}", GeoblockHttpModule.ConvertStringArrayToStringJoin(selectedCountryCodes), moduleConfiguration.AllowedMode, Environment.NewLine)); #endif ExceptionRule[] exceptionRules = new ExceptionRule[moduleConfiguration.ExceptionRules.Count]; i = 0; foreach (ExceptionRuleConfigurationElement exceptionRule in moduleConfiguration.ExceptionRules) { exceptionRules[i] = new ExceptionRule(exceptionRule.AllowedMode, exceptionRule.IpAddress, exceptionRule.Mask); #if DEBUG if (!string.IsNullOrEmpty(exceptionRule.Mask)) { this.DbgWrite(string.Format("exceptionRule: AllowedMode: {0}, Requestor: {1} ({2}){3}", exceptionRule.AllowedMode, exceptionRule.IpAddress, exceptionRule.Mask, Environment.NewLine)); } else { this.DbgWrite(string.Format("exceptionRule: AllowedMode: {0}, Requestor: {1}{2}", exceptionRule.AllowedMode, exceptionRule.IpAddress, Environment.NewLine)); } #endif i++; } //Perform the check string resultMessage; Geoblocker geoBlocker = new Geoblocker(moduleConfiguration.GeoIpFilepath, selectedCountryCodes, moduleConfiguration.AllowedMode, exceptionRules, moduleConfiguration.VerifyAll); if (!geoBlocker.Allowed(ipAddressesToCheckUnique, out resultMessage)) { #if DEBUG this.DbgWrite(string.Concat("IP is blocked by GeoIP2block Module. ", ipNotificationString, ". ", resultMessage)); this.DbgWrite(string.Format("DenyAction: {0} ", moduleConfiguration.DenyAction)); #endif switch (moduleConfiguration.DenyAction) { case "Unauthorized": context.Response.StatusCode = 401; context.Response.SubStatusCode = 503; context.Response.StatusDescription = string.Concat("IP is blocked by GeoIP2block Module. ", ipNotificationString, ". ", resultMessage); context.Response.SuppressContent = true; context.Response.End(); break; case "Forbidden": context.Response.StatusCode = 403; context.Response.SubStatusCode = 503; context.Response.StatusDescription = string.Concat("IP is blocked by GeoIP2block Module. ", ipNotificationString, ". ", resultMessage); context.Response.SuppressContent = true; context.Response.End(); break; case "NotFound": context.Response.StatusCode = 404; context.Response.SubStatusCode = 503; context.Response.StatusDescription = string.Concat("IP is blocked by GeoIP2block Module. ", ipNotificationString, ". ", resultMessage); context.Response.SuppressContent = true; context.Response.End(); break; case "Abort": context.Request.Abort(); break; } } #if DEBUG else { this.DbgWrite(string.Format("DenyAction: {0} ", resultMessage)); } #endif }