From 8f7b102af38fd4980b9aebd9874ea50f05f178d0 Mon Sep 17 00:00:00 2001 From: Yannick Warnier Date: Thu, 19 Jul 2012 11:08:36 -0500 Subject: [PATCH] Improved IP address validation in web service from registration.soap.php --- main/inc/lib/main_api.lib.php | 42 ++++++++++++++++++++------ main/webservices/registration.soap.php | 14 +-------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/main/inc/lib/main_api.lib.php b/main/inc/lib/main_api.lib.php index d993f27b45..2c62448d49 100644 --- a/main/inc/lib/main_api.lib.php +++ b/main/inc/lib/main_api.lib.php @@ -5958,29 +5958,51 @@ function api_get_real_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 + * @author claudiu at cnixs dot com on http://www.php.net/manual/fr/ref.network.php#55230 + * @author Yannick Warnier for improvements and managment of multiple ranges + * @todo check for IPv6 support */ 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); + $ranges = array(); + // divide range param into array of elements + if (strpos($range,',')!==false) { + $ranges = explode(',',$range); + } else { + $ranges = array($range); + } + foreach ($ranges as $range) { + $range = trim($range); + if (empty($range)) { continue; } + if (strpos($range,'/')===false) { + if (strcmp($ip,$range)===0) { + return true; // there is a direct IP match, return OK + } + continue; //otherwise, get to the next range + } + // the range contains a "/", so analyse completely + list ($net, $mask) = explode("/", $range); + + $ip_net = ip2long ($net); + // mask binary magic + $ip_mask = ~((1 << (32 - $mask)) - 1); - $ip_ip_net = $ip_ip & $ip_mask; - - return ($ip_ip_net == $ip_net); + $ip_ip_net = $ip_ip & $ip_mask; + if ($ip_ip_net == $ip_net) { + return true; + } + } + return false; } function api_check_user_access_to_legal($course_visibility) { $course_visibility_list = array(COURSE_VISIBILITY_OPEN_WORLD, COURSE_VISIBILITY_OPEN_PLATFORM); return in_array($course_visibility, $course_visibility_list) || api_is_drh(); -} \ No newline at end of file +} diff --git a/main/webservices/registration.soap.php b/main/webservices/registration.soap.php index aaf5d1b7d2..d0fd293a38 100644 --- a/main/webservices/registration.soap.php +++ b/main/webservices/registration.soap.php @@ -48,19 +48,7 @@ function WSHelperVerifyKey($params) { 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); - } + $ip_matches = api_check_ip_in_range($ip,$ws_auth_ip); } } if ($check_ip) {