[feladat @ 244]
authorrejo
Fri, 11 Apr 2008 13:33:30 +0000
changeset 138 3e36ebbfe048
parent 137 79c33038ca14
child 139 98ce0ffae5b8
[feladat @ 244] Improved SOA record validation.
docs/i18n-template-php.pot
inc/config-me.inc.php
inc/dns.inc.php
inc/error.inc.php
inc/record.inc.php
inc/toolkit.inc.php
locale/nl_NL/LC_MESSAGES/messages.mo
locale/nl_NL/LC_MESSAGES/nl.po
--- a/docs/i18n-template-php.pot	Fri Apr 11 11:59:33 2008 +0000
+++ b/docs/i18n-template-php.pot	Fri Apr 11 13:33:30 2008 +0000
@@ -689,3 +689,12 @@
 msgid "No or unknown database type has been set in config.inc.php."
 msgstr ""
 
+msgid "You have an error in the MNAME field of the SOA record."
+msgstr ""
+
+msgid "Too many characters in the hostname."
+msgstr ""
+
+msgid "You are using an invalid top level domain."
+msgstr ""
+
--- a/inc/config-me.inc.php	Fri Apr 11 11:59:33 2008 +0000
+++ b/inc/config-me.inc.php	Fri Apr 11 13:33:30 2008 +0000
@@ -18,5 +18,6 @@
 $dns_ns2		= "";
 $dns_ttl		= "86400";
 $dns_fancy		= "false";
+$dns_strict_tld_check	= "1";
 
 ?>
--- a/inc/dns.inc.php	Fri Apr 11 11:59:33 2008 +0000
+++ b/inc/dns.inc.php	Fri Apr 11 13:33:30 2008 +0000
@@ -19,25 +19,10 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/*
- * Validates an IPv4 IP.
- * returns true if valid.
- */
-function validate_input($zoneid, $type, &$content, &$name, &$prio, &$ttl)
+function validate_input($zid, $type, &$content, &$name, &$prio, &$ttl)
 {
 	global $db;
-
-	// Has to validate content first then it can do the rest
-	// Since if content is invalid already it can aswell be just removed
-	// Check first if content is IPv4, IPv6 or Hostname
-	// We accomplish this by just running all tests over it
-	// We start with IPv6 since its not able to have these ip's in domains.
-	//
-	// <TODO>
-	// The nocheck has to move to the configuration file
-	// </TODO>
-	//
-	$domain = get_domain_name_from_id($zoneid);
+	$domain = get_domain_name_from_id($zid);
 	$nocheck = array('SOA', 'HINFO', 'NAPTR', 'URL', 'MBOXFW', 'TXT');
 	$hostname = false;
 	$ip4 = false;
@@ -122,14 +107,8 @@
 		}
 	}
 
-	if ($type == 'SOA') {
-		$status = is_valid_soa($content, $zoneid);
-		if($status == -1) {
-			error(ERR_DNS_SOA_UNIQUE);
-		} elseif($status == -2) {
-			error(ERR_DNS_SOA_NUMERIC);
-			return false;
-		}
+	if ($type == 'SOA' && !is_valid_rr_soa($content)) {
+		return false;
 	}
 
 	// HINFO and TXT require no validation.
@@ -183,18 +162,6 @@
 	return true;
 }
 
-
-
-		/****************************************
-		 *					*
-		 * RECORD VALIDATING PART.		*
-		 * CHANGES HERE SHOULD BE CONSIDERED	*
-		 * THEY REQUIRE KNOWLEDGE ABOUT THE 	*
-		 * DNS SPECIFICATIONS			*
-		 *					*
-		 ***************************************/
-
-
 /*
  * Validatis a CNAME record by the name it will have and its destination
  *
@@ -411,55 +378,113 @@
 }
 
 
-/*
- * Function to check the validity of SOA records.
- * return values: true if succesful
- */
-function is_valid_soa(&$content, $zoneid)
-{
+function is_valid_hostname_label($hostname_label) {
+
+        // See <https://www.poweradmin.org/trac/wiki/Documentation/DNS-hostnames>.
+        if (!preg_match('/^[a-z\d]([a-z\d-]*[a-z\d])*$/i',$hostname_label)) {
+		return false;
+        } elseif (preg_match('/^[\d]+$/i',$hostname_label)) {
+                return false;
+        } elseif ((strlen($hostname_label) < 2) || (strlen($hostname_label) > 63)) {
+                return false;
+        }
+        return true;
+}
+
+function is_valid_hostname_fqdn($hostname) {
 
-	/*
-	 * The stored format is: primary hostmaster serial refresh retry expire default_ttl
-	 */
+        // See <https://www.poweradmin.org/trac/wiki/Documentation/DNS-hostnames>.
+	global $dns_strict_tld_check;
+	global $valid_tlds;
+
+	$hostname = ereg_replace("\.$","",$hostname);
 
-	$return = get_records_by_type_from_domid("SOA", $zoneid);
-	if($return->numRows() > 1) {
-		return -1;
+	if (strlen($hostname) > 255) {
+		error(ERR_DNS_HN_TOO_LONG);
+		return false;
+	}
+
+        $hostname_labels = explode ('.', $hostname);
+        $label_count = count($hostname_labels);
+
+	if ($dns_strict_tld_check == "1" && !in_array($hostname_labels[$label_count-1], $valid_tlds)) {
+		error(ERR_DNS_INV_TLD);
+		return false;
 	}
 
-	$soacontent = preg_split("/\s+/", $content);
-	
-	if(is_valid_hostname($soacontent[0])) {
+	if ($hostname_labels[$label_count-1] == "arpa") {
+		// FIXME
+	} else {
+		foreach ($hostname_labels as $hostname_label) {
+			if (!is_valid_hostname_label($hostname_label)) {
+				error(ERR_DNS_HOSTNAME);
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
+function is_valid_rr_soa(&$content) {
 
-		$totalsoa = $soacontent[0];
-		// It doesnt matter what field 2 contains, but lets check if its there
-		// We assume the 2nd field wont have numbers, otherwise its a TTL field
+	// TODO move to appropiate location
+//	$return = get_records_by_type_from_domid("SOA", $zid);
+//	if($return->numRows() > 1) {
+//		return false;
+//	}
+
+	$fields = preg_split("/\s+/", trim($content));
+        $field_count = count($fields);
+
+	if ($field_count == 0 || $field_count > 7) {
+		return false;
+	} else {
+		if (!is_valid_hostname_fqdn($fields[0]) || preg_match('/\.arpa\.?$/',$fields[0])) {
+			return false;
+		}
+		$final_soa = $fields[0];
 
-		if(count($soacontent) > 1) {
-			if(is_numeric($soacontent[1])) {
-				// its a TTL field, or at least not hostmaster or alike
-				// Set final string to the default hostmaster addy
-				global $dns_hostmaster;
-				$totalsoa .= " ". $dns_hostmaster;
-			} else {
-				$totalsoa .= " ".$soacontent[1];
+		if (isset($fields[1])) {
+			$addr_input = $fields[1];
+		} else {
+			global $dns_hostmaster;
+			$addr_input = $dns_hostmaster;
+		}
+		if (!preg_match("/@/", $addr_input)) {
+			$addr_input = preg_split('/(?<!\\\)\./', $addr_input, 2);
+			$addr_to_check = str_replace("\\", "", $addr_input[0]) . "@" . $addr_input[1];
+		} else {
+			$addr_to_check = $addr_input;
+		}
+		
+		if (!is_valid_email($addr_to_check)) {
+			return false;
+		} else {
+			$addr_final = explode('@', $addr_to_check, 2);
+			$final_soa .= " " . str_replace(".", "\\.", $addr_final[0]) . "." . $addr_final[1];
+		}
+
+		if (isset($fields[2])) {
+			if (!is_numeric($fields[2])) {
+				return false;
 			}
-			// For loop to iterate over the numbers
-			$imax = count($soacontent);
-			for($i = 2; ($i < $imax) && ($i < 7); $i++) {
-				if(!is_numeric($soacontent[$i])) {
-					return -2;
+			$final_soa .= " " . $fields[2];
+		} else {
+			$final_soa .= " 0";
+		}
+		
+		if ($field_count == 7) {
+			for ($i = 3; ($i < 7); $i++) {
+				if (!is_numeric($fields[$i])) {
+					return false;
 				} else {
-					$totalsoa .= " ".$soacontent[$i];
+					$final_soa .= " " . $fields[$i];
 				}
 			}
-			// if($i > 7) --> SOA contained too many fields, should we provide error?
 		}
-	} else {
-		error(ERR_DNS_SOA_HOSTNAME);
 	}
-	$content = $totalsoa;
-	return 1;
+	$content = $final_soa;
+	return true;
 }
 
 
--- a/inc/error.inc.php	Fri Apr 11 11:59:33 2008 +0000
+++ b/inc/error.inc.php	Fri Apr 11 13:33:30 2008 +0000
@@ -78,9 +78,9 @@
 define("ERR_DNS_NS_HNAME", _('NS records must be a hostnames.'));
 define("ERR_DNS_MX_CNAME", _('You can not point a MX record to a CNAME record. Remove or rename the CNAME record first or take another name.'));
 define("ERR_DNS_MX_PRIO", _('A prio field should be numeric.'));
-define("ERR_DNS_SOA_NUMERIC", _('At least one of the five last SOA data fields is not numeric.'));
-define("ERR_DNS_SOA_NUMERIC_FIELDS", _('You can only have five numeric fields in the SOA record.'));
-define("ERR_DNS_SOA_HOSTNAME", _('The first part of your SOA record does not contain a valid hostname for a DNS server.'));
+define("ERR_DNS_SOA_MNAME", _('You have an error in the MNAME field of the SOA record.'));
+define("ERR_DNS_HN_TOO_LONG", _('The hostname is too long.'));
+define("ERR_DNS_INV_TLD", _('You are using an invalid top level domain.'));
 
 /* GOOD! */
 define("SUC_ZONE_ADD", _('Zone has been added successfully.')); 
--- a/inc/record.inc.php	Fri Apr 11 11:59:33 2008 +0000
+++ b/inc/record.inc.php	Fri Apr 11 13:33:30 2008 +0000
@@ -116,7 +116,7 @@
 				$query = "UPDATE records 
 					SET name=".$db->quote($record['name']).", 
 					type=".$db->quote($record['type']).", 
-					content=".$db->quote($record['content']).", 
+					content='" . $record['content'] . "', 
 					ttl=".$db->quote($record['ttl']).", 
 					prio=".$db->quote($record['prio']).", 
 					change_date=".$db->quote(time())." 
--- a/inc/toolkit.inc.php	Fri Apr 11 11:59:33 2008 +0000
+++ b/inc/toolkit.inc.php	Fri Apr 11 13:33:30 2008 +0000
@@ -47,6 +47,33 @@
    define('LETTERSTART', "a");
 }
 
+$valid_tlds = array(
+  "ac", "ad", "ae", "aero", "af", "ag", "ai", "al", "am", "an", "ao", "aq", "ar",
+  "arpa", "as", "asia", "at", "au", "aw", "ax", "az", "ba", "bb", "bd", "be",
+  "bf", "bg", "bh", "bi", "biz", "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv",
+  "bw", "by", "bz", "ca", "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl",
+  "cm", "cn", "co", "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj",
+  "dk", "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi",
+  "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh", "gi",
+  "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk",
+  "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in", "info", "int", "io",
+  "iq", "ir", "is", "it", "je", "jm", "jo", "jobs", "jp", "ke", "kg", "kh", "ki",
+  "km", "kn", "kp", "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "lr",
+  "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", "me", "mg", "mh", "mil", "mk",
+  "ml", "mm", "mn", "mo", "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum",
+  "mv", "mw", "mx", "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni",
+  "nl", "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph",
+  "pk", "pl", "pm", "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re", "ro",
+  "rs", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si", "sj", "sk",
+  "sl", "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz", "tc", "td", "tel",
+  "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to", "tp", "tr", "travel",
+  "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um", "us", "uy", "uz", "va", "vc",
+  "ve", "vg", "vi", "vn", "vu", "wf", "ws", "xn--0zwm56d", "xn--11b5bs3a9aj6g",
+  "xn--80akhbyknj4f", "xn--9t4b11yi5a", "xn--deba0ad", "xn--g6w251d",
+  "xn--hgbk6aj7f53bba", "xn--hlcj6aya9esc7a", "xn--jxalpdlp", "xn--kgbechtv",
+  "xn--zckzah", "ye", "yt", "yu", "za", "zm", "zw");
+
+
 /* Database connection */
 
 require_once("database.inc.php");
@@ -331,8 +358,7 @@
  */
 function is_valid_email($email)
 {
-	if(!eregi("^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.([a-z]{2,6}$)", $email))
-	{
+	if(!eregi("^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.([a-z]{2,6}$)", $email)) {
 		return false;
 	}
 	return true;
Binary file locale/nl_NL/LC_MESSAGES/messages.mo has changed
--- a/locale/nl_NL/LC_MESSAGES/nl.po	Fri Apr 11 11:59:33 2008 +0000
+++ b/locale/nl_NL/LC_MESSAGES/nl.po	Fri Apr 11 13:33:30 2008 +0000
@@ -665,6 +665,15 @@
 msgid "Password has been changed, please login."
 msgstr "Het wachtwoord is gewijzigd. Log opnieuw in."
 
+msgid "You have an error in the MNAME field of the SOA record."
+msgstr "Het MNAME veld van het SOA record is ongeldig."
+
+msgid "Too many characters in the hostname."
+msgstr "De hostnaam bestaat uit teveel tekens."
+
+msgid "You are using an invalid top level domain."
+msgstr "De hostnaam heeft een niet-officiele TLD."
+
 # The following is a list of strings that are not hard-code in the PHP 
 # files, but which are listed in the poweradmin database. Because of 
 # this, tools like xgettext will not notice these strings.
@@ -749,3 +758,5 @@
 
 msgid "No or unknown database type has been set in config.inc.php."
 msgstr "Er is geen of een onbekend database type opgegeven in config.inc.php."
+
+