* config.inc.php3, libraries/common.lib.php3: IP-based Allow/Deny code
      from feature #484158
    * Documentation.*: feature #484158 documented
This commit is contained in:
Robin Johnson
2002-05-18 06:05:48 +00:00
parent 42c38c009d
commit 6c5db8e09b
5 changed files with 941 additions and 971 deletions

View File

@@ -5,6 +5,11 @@ phpMyAdmin - Changelog
$Id$
$Source$
2002-05-17 Robin Johnson <robbat2@users.sourceforge.net>
* config.inc.php3, libraries/common.lib.php3: IP-based Allow/Deny code
from feature #484158
* Documentation.*: feature #484158 documented
2002-05-17 Marc Delisle <lem9@users.sourceforge.net>
* tbl_change.php3, bug 556296: field size for int
* tbl_qbe.php3, adjust drop-down width, thanks to Mike Beck

View File

@@ -343,10 +343,13 @@
<tt>$cfg['Servers'][$i]['user']</tt> and
<tt>$cfg['Servers'][$i]['password']</tt> fields.<br />
But you don't need to setup a &quot;controluser&quot; here:
using the <tt>$cfg['Servers'][$i]['only_db']</tt> might be enough.
<br />
In the ISP FAQ section, there is an entry explaining how to protect
using the <tt>$cfg['Servers'][$i]['only_db']</tt> might be enough.</li>
<li>In the ISP FAQ section, there is an entry explaining how to protect
your configuration file.<br /></li>
<li>For additional security in this mode, you may wish to consider the
Host authentication <tt>$cfg['Servers'][$i]['AllowDeny']['order']</tt>
and <tt>$cfg['Servers'][$i]['AllowDeny']['rules']</tt> configuration
directives.</li>
</ul>
@@ -438,9 +441,9 @@ $cfg['PmaAbsoluteUri'] = (!empty($HTTPS) ? 'https' : 'http') . '://'
<dt><b>$cfg['Servers'][$i]['connect_type']</b> string</dt>
<dd>
What type connection to use with the MySQL server. Your options are
'socket' &amp; 'tcp'. It defaults to 'tcp' as that is nearly guarenteed
to be available on all MySQL servers, while sockets are not supported
on some platforms.
<tt>'socket'</tt> &amp; <tt>'tcp'</tt>. It defaults to 'tcp' as that
is nearly guarenteed to be available on all MySQL servers, while
sockets are not supported on some platforms.
<br /><br />
</dd>
@@ -691,6 +694,56 @@ $cfg['PmaAbsoluteUri'] = (!empty($HTTPS) ? 'https' : 'http') . '://'
<br /><br />
</dd>
<dt><b>$cfg['Servers'][$i]['AllowDeny']['order']</b> string</dt>
<dd>
If your rule order is empty, then IP authentication is disabled.
<br /><br />
If your rule order is set to <tt>'deny,allow'</tt>. Then the system applies all deny rules followed by allow rules.
Access is allowed by default. Any client which does not match a Deny command or does match an Allow command will be
allowed access to the server.
<br /><br />
If your rule order is set to <tt>'allow,deny'</tt>. Then the system applies all allow rules followed by deny rules. Access
is denied by default. Any client which does not match an Allow directive or does match a Deny directive will be denied
access to the server.
<br /><br />
If your rule order is set to 'explicit', the authentication is performed in a similar fashion to rule order 'deny,allow',
with the added restriction that your host/username combination <b>must</b> be listed in the <i>allow</i> rules, and not
listed in the <i>deny</i> rules. This is the <b>most</b> secure means of using Allow/Deny rules, and was available in
Apache by specifying allow and deny rules without setting any order.
<br /><br />
</dd>
<dt><b>$cfg['Servers'][$i]['AllowDeny']['rules']</b> array of strings</dt>
<dd>
The general format for the rules is as such:<br />
<tt>&lt;'allow' | 'deny'&gt; &lt;username&gt; [from] &lt;ipmask&gt;</tt>
<br /><br />
If you wish to match all users, it is possible to use a <tt>'%'</tt> as a wildcard in the <i>username</i> field.<br />
There are a few shortcuts you can use in the <i>ipmask</i> field as well:
<tt><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'all' -&gt; 0.0.0.0/0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'localhost' -&gt; 127.0.0.1/8</tt>
<br /><br />
Having an empty rule list is equivilent to either using <tt>'allow % from all'</tt> if your rule order is set to
<tt>'deny,allow'</tt> or <tt>'deny % from all'</tt> if your rule order is set to <tt>'allow,deny'</tt> or
<tt>'explicit'</tt>.
<br /><br />
For the IP matching system, the following work:<br />
<tt>xxx.xxx.xxx.xxx</tt> (an exact IP address)<br />
<tt>xxx.xxx.xxx.[yyy-zzz]</tt> (an IP address range)<br />
<tt>xxx.xxx.xxx.xxx/nn</tt> (CIDR, Classless Inter-Domain Routing type IP addresses)<br />
But the following does not work:<br />
<tt>xxx.xxx.xxx.xx[yyy-zzz]</tt> (partial IP address range)
<br /><br />
</dd>
<dt><b>$cfg['ServerDefault']</b> integer</dt>
<dd>
If you have more than one server configured, you can set
@@ -1386,7 +1439,7 @@ $cfg['PmaAbsoluteUri'] = (!empty($HTTPS) ? 'https' : 'http') . '://'
your users. The development of this feature was kindly sponsored by
NetCologne GmbH.
This requires a properly setup MySQL user management and phpMyAdmin
http authentication. See the install section on
http or cookie authentication. See the install section on
&quot;Using http authentication&quot;.
</p>
@@ -1456,6 +1509,30 @@ $cfg['PmaAbsoluteUri'] = (!empty($HTTPS) ? 'https' : 'http') . '://'
would let a user create/manage his/her database(s).
</p>
<p>
<b>How can I use the Host-based authentication additions?</b>
<br />
If you have existing rules from an old .htaccess file, you can take them and
add a username between the <tt>'deny'</tt>/<tt>'allow'</tt> and <tt>'from'</tt>
strings. Using the username wildcard of <tt>'%'</tt> would be a major benefit
here if your installation is suited to using it. Then you can just add those
updated lines into the <tt>$cfg['Servers'][$i]['AllowDeny']['rules']</tt> array.
<br /><br />
If you want a pre-made sample, you can try this fragment. It stops the 'root'
user from logging in from any networks other than the private network IP blocks.
<br /><tt>
&nbsp;&nbsp;&nbsp;&nbsp;//block root from logging in except from the private networks<br />
&nbsp;&nbsp;&nbsp;&nbsp;$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';<br />
&nbsp;&nbsp;&nbsp;&nbsp;$cfg['Servers'][$i]['AllowDeny']['rules'] = array(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'deny root from all',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'allow root from localhost',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'allow root from 10.0.0.0/8',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'allow root from 192.168.0.0/16',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'allow root from 172.16.0.0/12',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);</tt>
</p>
<a name="faqbrowsers"></a>
<h3>[Browsers or client OS]</h3>
<p>
@@ -1556,7 +1633,7 @@ $cfg['PmaAbsoluteUri'] = (!empty($HTTPS) ? 'https' : 'http') . '://'
</p>
<ul>
<li>Using <tt>VARCHAR</tt> without a size argument</li>
<li>Using <tt>TEXT or</tt> BLOB with a size argument</li>
<li>Using <tt>TEXT</tt> or <tt>BLOB</tt> with a size argument</li>
</ul>
<p>
Also, look at the syntax chapter in the MySQL manual to confirm that your
@@ -1883,7 +1960,7 @@ CREDITS, in chronological order
* started SourceForge phpMyAdmin project in March 2001
* sync'ed different existing CVS trees with new features and bugfixes
* multi-language improvements, dynamic language selection
* current project maintainer, with Marc and Loic
* current project maintainer
[lc] - Lo<4C>c Chapeaux &lt;lolo_at_phpheaven.net&gt;
* rewrote and optimized javascript, DHTML and DOM stuff
@@ -1895,6 +1972,8 @@ CREDITS, in chronological order
[rj] - Robin Johnson &lt;robbat2_at_users.sourceforge.net&gt;
* database maintence controls
* table type code
* Host authentication IP Allow/Deny
* DB-based configuration
[af] - Armel Fauveau &lt;armel.fauveau_at_globalis-ms.com&gt;
* bookmarks feature
@@ -1927,7 +2006,7 @@ CREDITS, in chronological order
* German language file updates
Thanks to those guy who send us some major improvements to merge into the
Thanks to these guys who have sent us some major improvements to merge into the
code since version 2.1.0:
- Michal Cihar &lt;nijel at users.sourceforge.net&gt; who implemented the
enhanced index creation/display feature.
@@ -1947,6 +2026,7 @@ code since version 2.1.0:
- Maxime Delorme &lt;delorme.maxime at free.fr&gt; for the PDF schema output;
thanks also to Olivier Plathey for the fpdf library (www.fpdf.org).
And also to the following people who have contributed minor changes,
enhancements, bugfixes or support for a new language since version 2.1.0:
Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita,

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,11 @@ $cfg['Servers'][$i]['pdf_table_position']
// tables position for the
// PDF schema - leave blank
// for no PDF schema support
$cfg['Servers'][$i]['AllowDeny']['order']
= ''; // Host authentication order, leave blank to not use
$cfg['Servers'][$i]['AllowDeny']['rules']
= array( ); // Host authentication rules, leave blank for defaults
$i++;
$cfg['Servers'][$i]['host'] = '';

View File

@@ -311,6 +311,144 @@ if (!defined('PMA_COMMON_LIB_INCLUDED')){
return true;
} // end of the 'PMA_setFontSizes()' function
/**
* Based on IP Pattern Matcher
* Originally by J.Adams <jna@retina.net>
* Found on <http://www.php.net/manual/en/function.ip2long.php>
* Modified by Robbat2 <robbat2@users.sourceforge.net>
*
* Matches:
* xxx.xxx.xxx.xxx (exact)
* xxx.xxx.xxx.[yyy-zzz] (range)
* xxx.xxx.xxx.xxx/nn (CIDR)
*
* Does not match:
* xxx.xxx.xxx.xx[yyy-zzz] (range, partial octets not supported)
*
* @param string string of IP range to match
* @param string string of IP to test against range
*
* @return boolean always true
*
* @access public
*/
function PMA_IPMaskTest($TestRange,$IPtoTest)
{
$result = TRUE;
if (ereg( "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/([0-9]+)", $TestRange, $regs) ) {
//perform a mask match
$ipl = ip2long($IPtoTest);
$rangel = ip2long($regs[1].'.'.$regs[2].'.'.$regs[3].'.'.$regs[4]);
$maskl = 0;
for ($i = 0; $i< 31; $i++) {
if ($i < $regs[5]-1) {
$maskl = $maskl + pow(2,(30-$i));
} // end if
} // end for
if (($maskl & $rangel) == ($maskl & $ipl)) {
return TRUE;
} else {
return FALSE;
}
} else {
// range based
$maskocts = split("\.",$TestRange);
$ipocts = split("\.",$IPtoTest);
// perform a range match
for ($i=0; $i<4; $i++) {
if (ereg("\[([0-9]+)\-([0-9]+)\]",$maskocts[$i],$regs)) {
if ( ($ipocts[$i] > $regs[2])
|| ($ipocts[$i] < $regs[1])) {
$result = FALSE;
} // end if
} else {
if ($maskocts[$i] <> $ipocts[$i]) {
$result = FALSE;
} // end if
} // end if/else
} //end for
} //end if/else
return $result;
}
/**
* Runs through IP Allow/Deny rules the use of it below for more information
*
* @param string 'allow' | 'deny' type of rule to match
*
* @return bool Matched a rule ?
*
* @access public
*/
function PMA_AllowDeny($type)
{
global $cfg;
// grab IP of user
if (getenv("HTTP_X_FORWARDED_FOR")) {
// try to behave properly with proxies, as per
// http://www.php.net/manual/en/function.getenv.php
$remoteip = getenv("HTTP_X_FORWARDED_FOR");
} else {
// possibly does not work in ISAPI?
$remoteip = getenv("REMOTE_ADDR");
}
// copy username
$username = $cfg['Server']['user'];
// copy rule database
$rules = $cfg['Server']['AllowDeny']['rules'];
// lookup table for some name shortcuts
$shortcuts = array(
"all" => "0.0.0.0/0",
"localhost" => "127.0.0.1/8"
);
reset ($rules); // used instead of a foreach look for PHP3 support
while ( list(, $rule) = each ($rules) ) {
// extract rule data
$rule_data = explode(' ',$rule);
// check for rule type
if( $rule_data[0] != $type )
continue;
// check for username
if( ($rule_data[1] != '%' ) //wildcarded first
&& ($rule_data[1] != $username) )
continue;
// check if the config file has the full string with an extra 'from' in it
// if it does, just discard it
if( $rule_data[2] == 'from' )
$rule_data[2] = $rule_data[3];
// Handle shortcuts with above array
// DON'T use "array_key_exists" as it's only PHP 4.1 and newer.
if( isset($shortcuts[$rule_data[2]]) )
$rule_data[2] = $shortcuts[$rule_data[2]];
// Add code for host lookups here
// Excluded for the moment
// Do the actual matching now
if(PMA_IPMaskTest($rule_data[2],$remoteip))
return TRUE;
}
return FALSE;
}
/**
* $cfg['PmaAbsoluteUri'] is a required directive else cookies won't be
@@ -405,6 +543,42 @@ if (!defined('PMA_COMMON_LIB_INCLUDED')){
PMA_auth_set_user();
}
// Check IP-based Allow/Deny rules as soon as possible to reject the user
// Based on mod_access in Apache
// http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup
// Look at: "static int check_dir_access(request_rec *r)"
// Robbat2 - May 10, 2002
$AllowDeny_forbidden = FALSE; //default
if ( $cfg['Server']['AllowDeny']['order'] == 'allow,deny' ) {
$AllowDeny_forbidden = TRUE;
if( PMA_AllowDeny('allow') ) {
$AllowDeny_forbidden = FALSE;
}
if( PMA_AllowDeny('deny') ) {
$AllowDeny_forbidden = TRUE;
}
} else if ( $cfg['Server']['AllowDeny']['order'] == 'deny,allow' ) {
if( PMA_AllowDeny('deny') ) {
$AllowDeny_forbidden = TRUE;
}
if( PMA_AllowDeny('allow') ) {
$AllowDeny_forbidden = FALSE;
}
} else if ( $cfg['Server']['AllowDeny']['order'] == 'explicit' ) {
if( PMA_AllowDeny('allow')
&& !PMA_AllowDeny('deny') ) {
$AllowDeny_forbidden = FALSE;
} else {
$AllowDeny_forbidden = TRUE;
}
}
if($AllowDeny_forbidden) {
// eject the user if they are bad
PMA_auth_fails();
}
unset($AllowDeny_forbidden); //Clean up after you!
// The user can work with only some databases
if (isset($cfg['Server']['only_db']) && $cfg['Server']['only_db'] != '') {
if (is_array($cfg['Server']['only_db'])) {
@@ -447,6 +621,9 @@ if (!defined('PMA_COMMON_LIB_INCLUDED')){
} // end if
} // end if
// Pass #1 of DB-Config to read in master level DB-Config will go here
// Robbat2 - May 11, 2002
// Connects to the server (validates user's login)
$userlink = @$connect_func(
$cfg['Server']['host'] . $server_port . $server_socket,
@@ -457,6 +634,9 @@ if (!defined('PMA_COMMON_LIB_INCLUDED')){
PMA_auth_fails();
} // end if
// Pass #2 of DB-Config to read in user level DB-Config will go here
// Robbat2 - May 11, 2002
if (PMA_PHP_INT_VERSION >= 40000) {
@ini_set('track_errors', $bkp_track_err);
}