Added new level of security to web services (only registration.soap.php so far) to allow filtering by IPs or IP ranges. The file added in this commit is optional, which is why I'm allowing myself to send it although we are already in Beta stage (BT#4158)

skala
Yannick Warnier 13 years ago
parent f4c1fe77ac
commit bf2e4ee9fd
  1. 21
      main/inc/lib/main_api.lib.php
  2. 34
      main/webservices/registration.soap.php
  3. 21
      main/webservices/webservice-auth-ip.conf.php

@ -5979,4 +5979,25 @@ function api_get_real_ip(){
if (!empty($debug)) error_log('Real IP: '.$ip);
return $ip;
}
/**
* Checks whether an IP is included inside an IP range
* @author claudiu at cnixs dot com on http://www.php.net/manual/fr/ref.network.php#55230
* @param string IP address
* @param string IP range
* @return bool True if IP is in the range, false otherwise
*/
function api_check_ip_in_range($ip,$range) {
if (empty($ip) or empty($range)) {
return false;
}
list ($net, $mask) = split ("/", $range);
$ip_net = ip2long ($net);
$ip_mask = ~((1 << (32 - $mask)) - 1);
$ip_ip = ip2long ($ip);
$ip_ip_net = $ip_ip & $ip_mask;
return ($ip_ip_net == $ip_net);
}

@ -33,7 +33,8 @@ function WSHelperVerifyKey($params) {
$secret_key = $params;
}
//error_log(print_r($params,1));
$check_ip = false;
$ip_matches = false;
$ip = trim($_SERVER['REMOTE_ADDR']);
// if we are behind a reverse proxy, assume it will send the
// HTTP_X_FORWARDED_FOR header and use this IP instead
@ -41,10 +42,33 @@ function WSHelperVerifyKey($params) {
list($ip1, $ip2) = split(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
$ip = trim($ip1);
}
$security_key = $ip.$_configuration['security_key'];
//error_log($secret_key.'-'.$security_key);
// Check if a file that limits access from webservices exists and contains
// the restraining check
if (is_file('webservice-auth-ip.conf.php')) {
include 'webservice-auth-ip.conf.php';
if (!empty($ws_auth_ip)) {
$check_ip = true;
if (strpos($ws_auth_ip,'/')!==false) {
$ip_matches = api_check_ip_in_range($ip,$ws_auth_ip);
} elseif (strpos(',',$ws_auth_ip)!==false) {
$list = split(',',$ws_auth_ip);
foreach ($list as $ipc) {
if (strcmp($ip,trim($ipc))===0) {
$ip_matches = true;
break;
}
}
} else {
$ip_matches = (strcmp($ip,$ws_auth_ip)===0);
}
}
}
if ($check_ip) {
$security_key = $_configuration['security_key'];
} else {
$security_key = $ip.$_configuration['security_key'];
}
$result = api_is_valid_secret_key($secret_key, $security_key);
//error_log($result);
if ($debug) error_log('WSHelperVerifyKey result '.intval($result));
return $result;
}
@ -5021,4 +5045,4 @@ function WSUpdateUserApiKey($params) {
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
$server->service($HTTP_RAW_POST_DATA);

@ -0,0 +1,21 @@
<?php
/**
* This file allows a Chamilo portal admin to authorize access from specific
* IPs or ranges of IPs
*/
/**
* Define here the IPs or ranges that will be authorized to access the
* webservice. When this is in place, the security key check will be made on
* the string given here in $ws_auth_ip, and not anymore on
* $_SERVER['REMOTE_ADDR'], but $_SERVER['REMOTE_ADDR'] will still be checked
* against the IP or range provided. It doesn't support IPv6 yet.
* If $ws_auth_ip is not defined, this file will be ignored. If $ws_auth_ip *is*
* defined, then the only security key expected from the client is the
* $_configuration['security_key'] encrypted through SHA1
* @example
* <pre>
* $ws_auth_ip = '192.168.1.1/22';
* $ws_auth_ip = '192.168.1.5';
* $ws_auth_ip = '192.168.1.5,192.168.1.9';
* </pre>
*/
Loading…
Cancel
Save