/** * Validate the contents of the textarea as either IP addresses, domain name or wildcard domain name (RFC 4592). * Used to validate a new line separated list of entries collected from a textarea control. * * This setting provides support for internationalised domain names (IDNs), however, such UTF-8 names will be converted to * their ascii-compatible encoding (punycode) on save, and converted back to their UTF-8 representation when fetched * via the get_setting() method, which has been overriden. * * @param string $data A list of FQDNs, DNS wildcard format domains, and IP addresses, separated by new lines. * @return mixed bool true for success or string:error on failure */ public function validate($data) { if (empty($data)) { return true; } $entries = explode("\n", $data); $badentries = []; foreach ($entries as $key => $entry) { $entry = trim($entry); if (empty($entry)) { return get_string('validateemptylineerror', 'admin'); } // Validate each string entry against the supported formats. if (\core\ip_utils::is_ip_address($entry) || \core\ip_utils::is_ipv6_range($entry) || \core\ip_utils::is_ipv4_range($entry) || \core\ip_utils::is_domain_name($entry) || \core\ip_utils::is_domain_matching_pattern($entry)) { continue; } // Otherwise, the entry is invalid. $badentries[] = $entry; } if ($badentries) { return get_string('validateerrorlist', 'admin', join(', ', $badentries)); } return true; }
/** * Test for \core\ip_utils::is_ip_address(). * * @param string $address the address to validate. * @param bool $expected the expected result. * @dataProvider ip_address_data_provider */ public function test_is_ip_address($address, $expected) { $this->assertEquals($expected, \core\ip_utils::is_ip_address($address)); }
/** * Checks whether the host portion of a url is blocked. * The host portion may be a FQDN, IPv4 address or a IPv6 address wrapped in square brackets, as per standard URL notation. * E.g. * images.example.com * 127.0.0.1 * [0.0.0.0.0.0.0.1] * The method logic is as follows: * 1. Check the host component against the list of IPv4/IPv6 addresses and ranges. * - This will perform a DNS forward lookup if required. * 2. Check the host component against the list of domain names and wildcard domain names. * - This will perform a DNS reverse lookup if required. * * @param string $host the host component of the URL to check against the blacklist. * @return bool true if the host is both valid and blocked, false otherwise. */ protected function host_is_blocked($host) { if (!$this->is_enabled() || empty($host) || !is_string($host)) { return false; } // Fix for square brackets in the 'host' portion of the URL (only occurs if an IPv6 address is specified). $host = str_replace(array('[', ']'), '', $host); // RFC3986, section 3.2.2. $blacklistedhosts = $this->get_blacklisted_hosts_by_category(); if (ip_utils::is_ip_address($host)) { if ($this->address_explicitly_blocked($host)) { return true; } // Only perform a reverse lookup if there is a point to it (i.e. we have rules to check against). if ($blacklistedhosts['domain'] || $blacklistedhosts['domainwildcard']) { $hostname = gethostbyaddr($host); // DNS reverse lookup - supports both IPv4 and IPv6 address formats. if ($hostname !== $host && $this->host_explicitly_blocked($hostname)) { return true; } } } else { if (ip_utils::is_domain_name($host)) { if ($this->host_explicitly_blocked($host)) { return true; } // Only perform a forward lookup if there are IP rules to check against. if ($blacklistedhosts['ipv4'] || $blacklistedhosts['ipv6']) { $hostip = gethostbyname($host); // DNS forward lookup - only returns IPv4 addresses! if ($hostip !== $host && $this->address_explicitly_blocked($hostip)) { return true; } } } } return false; }