1 <?php
2 /*
3 * This code is part of GOsa (https://gosa.gonicus.de)
4 * Copyright (C) 2008 Cajus Pollmeier
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
21 /*! \brief Test functions
22 *
23 * This class provides various test functions. It enables to check
24 * if a given value is:
25 *
26 * - a phone numnber
27 * - a DNS name
28 * - an URL
29 * etc.
30 *
31 * The functions need to be handled with care, because they are not as strict
32 * as one might expect.
33 */
34 class tests {
36 /*! \brief Test if the given string is a phone number */
37 public static function is_phone_nr($nr)
38 {
39 if ($nr == ""){
40 return (TRUE);
41 }
43 // We require at least one numeric character in the number string.
44 return preg_match ("/^[\/0-9 ()+*-]*[0-9]{1}[\/0-9 ()+*-]*$/", $nr);
45 }
48 /*! \brief Test if the given string contains characters allowed in a DNS name */
49 public static function is_dns_name($str)
50 {
51 return(preg_match("/^[a-z0-9\.\-_]*$/i",$str));
52 }
55 /*! \brief Test if the given string is an URL */
56 public static function is_url($url)
57 {
58 if ($url == ""){
59 return (TRUE);
60 }
62 return preg_match ("/^(http|https):\/\/((?:[a-zA-Z0-9_-]+\.?)+):?(\d*)/", $url);
63 }
66 /*! \brief Test if the given string is a DN */
67 public static function is_dn($dn)
68 {
69 if ($dn == ""){
70 return (TRUE);
71 }
73 return preg_match ("/^[a-z0-9 _-]+$/i", $dn);
74 }
77 /*! \brief Test if the given string is an uid */
78 public static function is_uid($uid)
79 {
80 if ($uid == ""){
81 return (TRUE);
82 }
84 /* STRICT adds spaces and case insenstivity to the uid check.
85 This is dangerous and should not be used. */
86 if (strict_uid_mode()){
87 return preg_match ("/^[a-z0-9_-]+$/", $uid);
88 } else {
89 return preg_match ("/^[a-z0-9 _.-]+$/i", $uid);
90 }
91 }
94 /*! \brief Test if the given string is an IP */
95 public static function is_ip($ip)
96 {
97 if(function_exists('filter_var')) {
98 return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
99 } else {
100 return preg_match("/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/", $ip);
101 }
102 }
105 public static function is_ipv6($ip)
106 {
107 if(function_exists('filter_var')) {
108 return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
109 } else {
110 $ipv4 = '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)';
111 $g = '([0-9a-f]{1,4})'; //IPv6 group
112 return preg_match("/^$g:$g:$g:$g:$g:$g:$g:$g$/", $ip) ||
113 preg_match("/^$g:$g:$g:$g:$g:$g:$ipv4$/", $ip);
114 }
115 }
118 /*! \brief Test if the given string is a mac address */
119 public static function is_mac($mac)
120 {
121 return preg_match("/^[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$/i", $mac);
122 }
125 /*! \brief Checks if the given ip address dosen't match
126 "is_ip" because there is also a sub net mask given */
127 public static function is_ip_with_subnetmask($ip)
128 {
129 /* Generate list of valid submasks */
130 $res = array();
131 for($e = 0 ; $e <= 32; $e++){
132 $res[$e] = $e;
133 }
134 $i[0] =255;
135 $i[1] =255;
136 $i[2] =255;
137 $i[3] =255;
138 for($a= 3 ; $a >= 0 ; $a --){
139 $c = 1;
140 while($i[$a] > 0 ){
141 $str = $i[0].".".$i[1].".".$i[2].".".$i[3];
142 $res[$str] = $str;
143 $i[$a] -=$c;
144 $c = 2*$c;
145 }
146 }
147 $res["0.0.0.0"] = "0.0.0.0";
148 if(preg_match("/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.".
149 "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.".
150 "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.".
151 "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/", $ip)){
152 $mask = preg_replace("/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.".
153 "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.".
154 "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.".
155 "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/","",$ip);
157 $mask = preg_replace("/^\//","",$mask);
158 if((in_array("$mask",$res)) && preg_match("/^[0-9\.]/",$mask)){
159 return(TRUE);
160 }
161 }
162 return(FALSE);
163 }
166 /*! \brief Simple is domain check
167 *
168 * This checks if the given string looks like "string(...).string"
169 */
170 public static function is_domain($str)
171 {
172 return(preg_match("/^(([a-z0-9\-]{2,63})\.)*[a-z]{2,63}$/i",$str));
173 }
176 /*! \brief Check if the given argument is an id */
177 public static function is_id($id)
178 {
179 if ($id == ""){
180 return (FALSE);
181 }
183 return preg_match ("/^[0-9]+$/", $id);
184 }
187 /*! \brief Check if the given argument is a path */
188 public static function is_path($path)
189 {
190 if ($path == ""){
191 return (TRUE);
192 }
193 if (!preg_match('/^[a-z0-9%\/_.+-]+$/i', $path)){
194 return (FALSE);
195 }
197 return preg_match ("/\/.+$/", $path);
198 }
201 /*! \brief Check if the given argument is an email */
202 public static function is_email($address, $template= FALSE)
203 {
204 if ($address == ""){
205 return (TRUE);
206 }
207 if ($template){
208 return preg_match ("/^[._a-z0-9%-]+@[_a-z0-9-]+(\.[a-z0-9-]+)(\.[a-z0-9-]+)*$/i",
209 $address);
210 } else {
211 return preg_match ("/^[._a-z0-9-]+@[_a-z0-9-]+(\.[a-z0-9i-]+)(\.[a-z0-9-]+)*$/i",
212 $address);
213 }
214 }
217 /* \brief Check if the given department name is valid */
218 public static function is_department_name_reserved($name,$base)
219 {
220 $reservedName = array("systems","apps","incomming","internal","accounts","fax","addressbook",
221 preg_replace("/ou=(.*),/","\\1",get_people_ou()),
222 preg_replace("/ou=(.*),/","\\1",get_groups_ou()));
223 $follwedNames['/ou=fai,ou=configs,ou=systems,/'] = array("fai","hooks","templates","scripts","disk","packages","variables","profiles");
225 /* Check if name is one of the reserved names */
226 if(in_array_ics($name,$reservedName)) {
227 return(true);
228 }
230 /* Check all follow combinations if name is in array && parent base == array_key, return false*/
231 foreach($follwedNames as $key => $names){
232 if((in_array_ics($name,$names)) && (preg_match($key,$base))){
233 return(true);
234 }
235 }
236 return(false);
237 }
240 /* \brief Check if $ip1 and $ip2 represents a valid IP range
241 * \return TRUE in case of a valid range, FALSE in case of an error.
242 */
243 public static function is_ip_range($ip1,$ip2)
244 {
245 if(!tests::is_ip($ip1) || !tests::is_ip($ip2)){
246 return(FALSE);
247 }else{
248 $ar1 = explode(".",$ip1);
249 $var1 = $ar1[0] * (16777216) + $ar1[1] * (65536) + $ar1[2] * (256) + $ar1[3];
251 $ar2 = explode(".",$ip2);
252 $var2 = $ar2[0] * (16777216) + $ar2[1] * (65536) + $ar2[2] * (256) + $ar2[3];
253 return($var1 < $var2);
254 }
255 }
258 /* \brief Check if the specified IP address $address is inside the given network */
259 public static function is_in_network($network, $netmask, $address)
260 {
261 $nw= explode('.', $network);
262 $nm= explode('.', $netmask);
263 $ad= explode('.', $address);
265 /* Generate inverted netmask */
266 for ($i= 0; $i<4; $i++){
267 $ni[$i]= 255-$nm[$i];
268 $la[$i]= $nw[$i] | $ni[$i];
269 }
271 /* Transform to integer */
272 $first= $nw[0] * (16777216) + $nw[1] * (65536) + $nw[2] * (256) + $nw[3];
273 $curr= $ad[0] * (16777216) + $ad[1] * (65536) + $ad[2] * (256) + $ad[3];
274 $last= $la[0] * (16777216) + $la[1] * (65536) + $la[2] * (256) + $la[3];
276 return ($first < $curr&& $last > $curr);
277 }
279 /* Check if entry value is a valid date */
280 public static function is_date($date)
281 {
282 global $lang;
284 if ($date == ""){
285 return (TRUE);
286 }
288 #TODO: use $lang to check date format
289 if (!preg_match("/^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})$/", $date, $matches)) {
290 return false;
291 }
293 return checkdate($matches[2],$matches[1],$matches[3]);
294 }
295 /*
296 * Compares two dates
297 * @param $dataA as String in german dateformat
298 * @param $dataB as String in german dateformat
299 * @return float or false on error
300 *
301 * * <0 => a<b
302 * 0 => a=b
303 * >0 => a>b
304 */
305 public static function compareDate($dateA, $dateB){
306 /*
307 * TODO:
308 * use $lang to check date format
309 */
310 $tstampA = strtotime($dateA);
311 if($tstampA === false){
312 trigger_error("Given date can not be converted to timestamp(".$dataA.") in function tests::compareDate.");
313 return false;
314 }
315 $tstampB = strtotime($dateB);
316 if($tstampB === false){
317 trigger_error("Given date can not be converted to timestamp(".$dataB.") in function tests::compareDate.");
318 return false;
319 }
321 return $tstampA-$tstampB;
322 }
323 /* \brief Check if the specified IP address $address is inside the given network */
324 public static function is_in_ip_range($from, $to, $address)
325 {
326 $from = explode('.', $from);
327 $to = explode('.', $to);
328 $ad = explode('.', $address);
330 /* Transform to integer */
331 $from= $from[0] * (16777216) + $from[1] * (65536) + $from[2] * (256) + $from[3];
332 $to= $to[0] * (16777216) + $to[1] * (65536) + $to[2] * (256) + $to[3];
333 $ad= $ad[0] * (16777216) + $ad[1] * (65536) + $ad[2] * (256) + $ad[3];
335 return ($ad >= $from && $ad <= $to);
336 }
337 }
339 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
340 ?>