3.3.6-rc1
[phpmyadmin/dkf.git] / libraries / ip_allow_deny.lib.php
blob6403528acf9fe8e5e28a7e04dd07dc7c62f67fa3
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * This library is used with the server IP allow/deny host authentication
5 * feature
7 * @version $Id$
8 * @package phpMyAdmin
9 */
12 /**
13 * Gets the "true" IP address of the current user
15 * @return string the ip of the user
17 * @access private
19 function PMA_getIp()
21 /* Get the address of user */
22 if (!empty($_SERVER['REMOTE_ADDR'])) {
23 $direct_ip = $_SERVER['REMOTE_ADDR'];
24 } else {
25 /* We do not know remote IP */
26 return false;
29 /* Do we trust this IP as a proxy? If yes we will use it's header. */
30 if (isset($GLOBALS['cfg']['TrustedProxies'][$direct_ip])) {
31 $trusted_header_value = PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
32 $matches = array();
33 // the $ checks that the header contains only one IP address, ?: makes sure the () don't capture
34 $is_ip = preg_match('|^(?:[0-9]{1,3}\.){3,3}[0-9]{1,3}$|', $trusted_header_value, $matches);
35 if ($is_ip && (count($matches) == 1)) {
36 // True IP behind a proxy
37 return $matches[0];
41 /* Return true IP */
42 return $direct_ip;
43 } // end of the 'PMA_getIp()' function
46 /**
47 * Based on IP Pattern Matcher
48 * Originally by J.Adams <jna@retina.net>
49 * Found on <http://www.php.net/manual/en/function.ip2long.php>
50 * Modified by Robbat2 <robbat2@users.sourceforge.net>
52 * Matches:
53 * xxx.xxx.xxx.xxx (exact)
54 * xxx.xxx.xxx.[yyy-zzz] (range)
55 * xxx.xxx.xxx.xxx/nn (CIDR)
57 * Does not match:
58 * xxx.xxx.xxx.xx[yyy-zzz] (range, partial octets not supported)
60 * @param string string of IP range to match
61 * @param string string of IP to test against range
63 * @return boolean always true
65 * @access public
67 function PMA_ipMaskTest($testRange, $ipToTest)
69 $result = true;
71 if (preg_match('|([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/([0-9]+)|', $testRange, $regs)) {
72 // performs a mask match
73 $ipl = ip2long($ipToTest);
74 $rangel = ip2long($regs[1] . '.' . $regs[2] . '.' . $regs[3] . '.' . $regs[4]);
76 $maskl = 0;
78 for ($i = 0; $i < 31; $i++) {
79 if ($i < $regs[5] - 1) {
80 $maskl = $maskl + PMA_pow(2, (30 - $i));
81 } // end if
82 } // end for
84 if (($maskl & $rangel) == ($maskl & $ipl)) {
85 return true;
86 } else {
87 return false;
89 } else {
90 // range based
91 $maskocts = explode('.', $testRange);
92 $ipocts = explode('.', $ipToTest);
94 // perform a range match
95 for ($i = 0; $i < 4; $i++) {
96 if (preg_match('|\[([0-9]+)\-([0-9]+)\]|', $maskocts[$i], $regs)) {
97 if (($ipocts[$i] > $regs[2])
98 || ($ipocts[$i] < $regs[1])) {
99 $result = false;
100 } // end if
101 } else {
102 if ($maskocts[$i] <> $ipocts[$i]) {
103 $result = false;
104 } // end if
105 } // end if/else
106 } //end for
107 } //end if/else
109 return $result;
110 } // end of the "PMA_IPMaskTest()" function
114 * Runs through IP Allow/Deny rules the use of it below for more information
116 * @param string 'allow' | 'deny' type of rule to match
118 * @return bool Matched a rule ?
120 * @access public
122 * @see PMA_getIp()
124 function PMA_allowDeny($type)
126 global $cfg;
128 // Grabs true IP of the user and returns if it can't be found
129 $remote_ip = PMA_getIp();
130 if (empty($remote_ip)) {
131 return false;
134 // copy username
135 $username = $cfg['Server']['user'];
137 // copy rule database
138 $rules = $cfg['Server']['AllowDeny']['rules'];
140 // lookup table for some name shortcuts
141 $shortcuts = array(
142 'all' => '0.0.0.0/0',
143 'localhost' => '127.0.0.1/8'
146 // Provide some useful shortcuts if server gives us address:
147 if (PMA_getenv('SERVER_ADDR')) {
148 $shortcuts['localnetA'] = PMA_getenv('SERVER_ADDR') . '/8';
149 $shortcuts['localnetB'] = PMA_getenv('SERVER_ADDR') . '/16';
150 $shortcuts['localnetC'] = PMA_getenv('SERVER_ADDR') . '/24';
153 foreach ($rules as $rule) {
154 // extract rule data
155 $rule_data = explode(' ', $rule);
157 // check for rule type
158 if ($rule_data[0] != $type) {
159 continue;
162 // check for username
163 if (($rule_data[1] != '%') //wildcarded first
164 && ($rule_data[1] != $username)) {
165 continue;
168 // check if the config file has the full string with an extra
169 // 'from' in it and if it does, just discard it
170 if ($rule_data[2] == 'from') {
171 $rule_data[2] = $rule_data[3];
174 // Handle shortcuts with above array
175 if (isset($shortcuts[$rule_data[2]])) {
176 $rule_data[2] = $shortcuts[$rule_data[2]];
179 // Add code for host lookups here
180 // Excluded for the moment
182 // Do the actual matching now
183 if (PMA_ipMaskTest($rule_data[2], $remote_ip)) {
184 return true;
186 } // end while
188 return false;
189 } // end of the "PMA_AllowDeny()" function