summaryrefslogtreecommitdiff
path: root/lib/Kolab/FreeBusy/Utils.php
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2013-01-17 13:48:06 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2013-01-17 13:48:06 (GMT)
commit2b0104f82c9c11789ad81b6f8d1db1e086c13392 (patch)
treea524898fa902c72153216ebbe62cddb39c15f7d3 /lib/Kolab/FreeBusy/Utils.php
parent91d925b304affc82f444535a52d68c78724928b3 (diff)
downloadkolab-freebusy-2b0104f82c9c11789ad81b6f8d1db1e086c13392.tar.gz
Implement HTTP authentication and trusted network check
Diffstat (limited to 'lib/Kolab/FreeBusy/Utils.php')
-rw-r--r--lib/Kolab/FreeBusy/Utils.php118
1 files changed, 118 insertions, 0 deletions
diff --git a/lib/Kolab/FreeBusy/Utils.php b/lib/Kolab/FreeBusy/Utils.php
new file mode 100644
index 0000000..ba1e736
--- /dev/null
+++ b/lib/Kolab/FreeBusy/Utils.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Kolab\FreeBusy;
+
+/**
+ * Static calss providing utility functions for the Free/Busy service
+ */
+class Utils
+{
+ /**
+ * Resolve the given directory to a real path ending with $append
+ *
+ * @param string Arbitrary directory directory path
+ * @param string Make path end with this string/character
+ * @return string Absolute file system path
+ */
+ public static function abspath($dirname, $append = '')
+ {
+ if ($dirname[0] != '/')
+ $dirname = realpath(KOLAB_FREEBUSY_ROOT . '/' . $dirname);
+
+ return rtrim($dirname, '/') . $append;
+ }
+
+ /**
+ * Returns remote IP address and forwarded addresses if found
+ *
+ * @return string Remote IP address(es)
+ */
+ public static function remoteIP()
+ {
+ $address = $_SERVER['REMOTE_ADDR'];
+
+ // use the NGINX X-Real-IP header, if set
+ if (!empty($_SERVER['HTTP_X_REAL_IP'])) {
+ $address = $_SERVER['HTTP_X_REAL_IP'];
+ }
+ // use the X-Forwarded-For header, if set
+ if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+ $address = $_SERVER['HTTP_X_FORWARDED_FOR'];
+ }
+
+ return $address;
+ }
+
+
+ /**
+ * Checks if the given IP address is in one of the provided ranges
+ *
+ * @param string IP address
+ * @param array List of IP ranges/subnets to check against
+ * @return boolean True if in range, False if not
+ */
+ public static function checkIPRange($ip, $ranges)
+ {
+ $ipv6 = strpos($ip, ':') !== false;
+ $ipbin = $ipv6 ? self::ip6net2bits($ip) : ip2long($ip);
+
+ foreach ((array)$ranges as $range) {
+ // don't compare IPv4 and IPv6 addresses/ranges
+ $rangev6 = strpos($range, ':') !== false;
+ if ($ipv6 != $rangev6) {
+ continue;
+ }
+
+ // quick substring check (e.g. 192.168.0.)
+ if (( $ipv6 && strpos($ipbin, self::ip6net2bits($range)) === 0) ||
+ (!$ipv6 && strpos($ip, rtrim($range, '*')) === 0)) {
+ return true;
+ }
+
+ // range from-to specified (IPv4 only)
+ list($lower, $upper) = explode('-', $range);
+ if (strlen($upper) && !$ipv6) {
+ if ($ipbin >= ip2long(trim($lower)) && $ipbin <= ip2long(trim($upper))) {
+ return true;
+ }
+ }
+
+ // subnet/length is given
+ list($subnet, $bits) = explode('/', $range);
+
+ // IPv6 subnet
+ if (strlen($bits) && $ipv6) {
+ $subnetbin = self::ip6net2bits($subnet);
+ if (substr($ipbin, 0, $bits) === substr($subnetbin, 0, $bits)) {
+ return true;
+ }
+ }
+ // IPv4 subnet
+ else if (strlen($bits)) {
+ $subnet = ip2long($subnet);
+ $mask = -1 << $bits;
+ $subnet &= $mask; // just in case the supplied subnet wasn't correctly aligned
+ if (($ipbin & $mask) == $subnet) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert the given IPv6 address to a binary string representation.
+ * (from http://stackoverflow.com/questions/7951061/matching-ipv6-address-to-a-cidr-subnet)
+ */
+ public static function ip6net2bits($inet)
+ {
+ $binaryip = '';
+ $unpacked = @unpack('A16', inet_pton($inet));
+ foreach (str_split($unpacked[1]) as $char) {
+ $binaryip .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
+ }
+ return $binaryip;
+ }
+
+} \ No newline at end of file