diff options
Diffstat (limited to 'radicale_infcloud/web/auth')
-rw-r--r-- | radicale_infcloud/web/auth/.htaccess | 24 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/common.inc | 41 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/config.inc | 58 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/cross_domain.inc | 14 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/doc/example_config_response.xml | 88 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/doc/readme.txt | 7 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/index.php | 33 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/plugins/generic.inc | 58 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/plugins/generic_conf.inc | 12 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/plugins/ldap.inc | 37 | ||||
-rw-r--r-- | radicale_infcloud/web/auth/plugins/ldap_conf.inc | 12 |
11 files changed, 384 insertions, 0 deletions
diff --git a/radicale_infcloud/web/auth/.htaccess b/radicale_infcloud/web/auth/.htaccess new file mode 100644 index 0000000..fb4203d --- /dev/null +++ b/radicale_infcloud/web/auth/.htaccess @@ -0,0 +1,24 @@ +##################################################################################################### +# Apache configuration (REQUIRED to prevent access for .inc files /especially config files/) +# You NEED to add the following lines into your Apache vhost configuration (without the # character): +# <Directory /client/installation/directory/auth/> +# AllowOverride Limit +# <IfVersion >= 2.3> +# Require all granted +# </IfVersion> +# <IfVersion < 2.3> +# Order allow,deny +# Allow from all +# </IfVersion> +# </Directory> +##################################################################################################### + +<Files ~ "\.inc$"> + <IfVersion >= 2.3> + Require all granted + </IfVersion> + <IfVersion < 2.3> + Order allow,deny + Deny from all + </IfVersion> +</Files> diff --git a/radicale_infcloud/web/auth/common.inc b/radicale_infcloud/web/auth/common.inc new file mode 100644 index 0000000..419cefb --- /dev/null +++ b/radicale_infcloud/web/auth/common.inc @@ -0,0 +1,41 @@ +<?php + function array_to_xml($array, $skip_top_closing=false, $level=0) + { + static $result="<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"; + + foreach($array as $k => $v) + { + if(is_numeric($k)) + array_to_xml($v, $skip_top_closing, $level); + else + { + for($j=0; $j<$level; $j++) + $result.=" "; + + $result.="<".htmlspecialchars($k); + if($k=='resources') + $result.=" xmlns=\"urn:com.inf-it:configuration\""; + if($v=='') + $result.=" />\n"; + else + { + $result.=">"; + + if(is_array($v)) + { + $result.="\n"; + array_to_xml($v, $skip_top_closing, $level+1); + for($j=0; $j<$level; $j++) + $result.=" "; + } + else + $result.=htmlspecialchars($v); + + if($level!==0 || $skip_top_closing===false) + $result.="</".htmlspecialchars($k).">\n"; + } + } + } + return $result; + } +?>
\ No newline at end of file diff --git a/radicale_infcloud/web/auth/config.inc b/radicale_infcloud/web/auth/config.inc new file mode 100644 index 0000000..534e524 --- /dev/null +++ b/radicale_infcloud/web/auth/config.inc @@ -0,0 +1,58 @@ +<?php + // auth method: generic (auth/plugins/generic_conf.inc) or ldap (auth/plugins/ldap_conf.inc) + $config['auth_method']='generic'; + + // set to true for debugging XML response, otherwise set to false to avoid browser + // to show http authentication window after unsuccessful authentication + $config['auth_send_authenticate_header']=false; + + // successfull authentication XML specification (change the "http://www.server.com:80" to your protocol/server/port) + $config['accounts']=array('resources'=>array()); + + // note: if you want to use regex values, then use one of the following formats (the second example is with regex modifier): 're:.*someregex.*[0-9]$' or 're|i:.*someregex.*[0-9]$' + // note: 'crossdomain' and 'withcredentials' are still available but there is NO REASON to use them (crossDomain is detected automatically, and I've never seen anyone who understand when to use withCredentials /there is NO REASON to set it to true!/) + // note: 'syncinterval' was removed - use globalSyncResourcesInterval in config.js instead + $config['accounts']['resources'][]=array( + 'resource'=>array( + 'type'=>array('addressbook'=>'', 'calendar'=>''), + 'href'=>(empty($_SERVER['HTTPS']) ? 'http' : 'https').'://www.server.com:80/caldav.php/'.$_SERVER['PHP_AUTH_USER'].'/', + 'hreflabel'=>'null', // if undefined or empty href value is used (see above) + 'forcereadonly'=>'null', // see auth/doc/example_config_response.xml for proper use, for example: 'forcereadonly'=>array(array('collection'=>'/caldav.php/user/collection/'), array('collection'=>'re:^/caldav.php/user/collection[0-9]/$')), + 'settingsaccount'=>'true', // client properties are saved here (note: set it to true only for ONE account) + 'checkcontenttype'=>'true', // check content-type in the server response (if you cannot see data in the interface /buggy server response/ you may try to disable it) + 'delegation'=>'true', // see auth/doc/example_config_response.xml for proper use, for example: 'delegation'=>array(array('resource'=>'/caldav.php/user%40domain.com/'), array('resource'=>'re|i:^/caldav.php/a[b-x].+/$')), + 'ignorealarms'=>'false', // see auth/doc/example_config_response.xml for proper use, for example: 'ignorealarms'=>array(array('collection'=>'/caldav.php/user/collection/'), array('collection'=>'re:^/caldav.php/user/collection[0-9]/$')), + 'backgroundcalendars'=>'', // see auth/doc/example_config_response.xml for proper use, for example: 'backgroundcalendars'=>array(array('collection'=>'/caldav.php/user/collection/'), array('collection'=>'re|i:^/caldav.php/user/collection[0-9]/$')), + 'userauth'=>array( + 'username'=>$_SERVER['PHP_AUTH_USER'], + 'password'=>$_SERVER['PHP_AUTH_PW'] + ), + 'timeout'=>90000, + 'locktimeout'=>10000 + ) + ); + +/* + // additional accounts + $config['accounts']['resources'][]=array( + 'resource'=>array( + 'type'=>array('addressbook'=>'', 'calendar'=>''), + 'href'=>'http://www.server.com:80/caldav.php/resource/', + 'hreflabel'=>'null', // if undefined or empty href value is used (see above) + 'forcereadonly'=>'null', // see auth/doc/example_config_response.xml for proper use, for example: 'forcereadonly'=>array(array('collection'=>'/caldav.php/user/collection/'), array('collection'=>'re:^/caldav.php/user/collection[0-9]/$')), + 'settingsaccount'=>'false', // client properties are saved here (note: set it to true only for ONE account) + 'checkcontenttype'=>'true', // check content-type in the server response (if you cannot see data in the interface /buggy server response/ you may try to disable it) + 'delegation'=>'true', // see auth/doc/example_config_response.xml for proper use, for example: 'delegation'=>array(array('resource'=>'/caldav.php/user%40domain.com/'), array('resource'=>'re|i:^/caldav.php/a[b-x].+/$')), + 'ignorealarms'=>'false', // see auth/doc/example_config_response.xml for proper use, for example: 'ignorealarms'=>array(array('collection'=>'/caldav.php/user/collection/'), array('collection'=>'re:^/caldav.php/user/collection[0-9]/$')), + 'backgroundcalendars'=>'', // see auth/doc/example_config_response.xml for proper use, for example: 'backgroundcalendars'=>array(array('collection'=>'/caldav.php/user/collection/'), array('collection'=>'re|i:^/caldav.php/user/collection[0-9]/$')), + 'userauth'=>array( + 'username'=>$_SERVER['PHP_AUTH_USER'], + 'password'=>$_SERVER['PHP_AUTH_PW'] + ), + 'timeout'=>90000, + 'locktimeout'=>10000 + ) + ); +*/ + +?>
\ No newline at end of file diff --git a/radicale_infcloud/web/auth/cross_domain.inc b/radicale_infcloud/web/auth/cross_domain.inc new file mode 100644 index 0000000..a6a10e0 --- /dev/null +++ b/radicale_infcloud/web/auth/cross_domain.inc @@ -0,0 +1,14 @@ +<?php + header_remove('Access-Control-Allow-Origin'); + header_remove('Access-Control-Allow-Methods'); + header_remove('Access-Control-Allow-Headers'); + header_remove('Access-Control-Allow-Credentials'); + + header('Access-Control-Allow-Origin: *'); + header('Access-Control-Allow-Methods: GET'); + header('Access-Control-Allow-Headers: User-Agent,Authorization,Content-type,X-client'); + header('Access-Control-Allow-Credentials: true'); + + if($_SERVER['REQUEST_METHOD']=='OPTIONS') // Preflighted request + exit(0); +?>
\ No newline at end of file diff --git a/radicale_infcloud/web/auth/doc/example_config_response.xml b/radicale_infcloud/web/auth/doc/example_config_response.xml new file mode 100644 index 0000000..9568049 --- /dev/null +++ b/radicale_infcloud/web/auth/doc/example_config_response.xml @@ -0,0 +1,88 @@ +<resources xmlns="urn:com.inf-it:configuration"> + <resource> + <type> + <addressbook /> + <calendar /> + </type> + <href>http://www.server.com:8080/principals/users/user/</href> + <hreflabel></hreflabel> + <crossdomain>null</crossdomain> + <forcereadonly>null</forcereadonly> + <withcredentials>false</withcredentials> + <settingsaccount>true</settingsaccount> + <checkcontenttype>true</checkcontenttype> + <delegation>true</delegation> + <ignorealarms>false</ignorealarms> + <backgroundcalendars /> + <userauth> + <username>user</username> + <password>password</password> + </userauth> + <timeout>90000</timeout> + <locktimeout>10000</locktimeout> + </resource> + <resource> + <type> + <addressbook /> + <calendar /> + </type> + <href>http://www.server2.com:80/caldav.php/user/</href> + <hreflabel></hreflabel> + <crossdomain>null</crossdomain> + <forcereadonly>true</forcereadonly> + <withcredentials>false</withcredentials> + <settingsaccount>false</settingsaccount> + <checkcontenttype>true</checkcontenttype> + <delegation> + <resource>/caldav.php/user/</resource> + <resource>/principals/users/user%40domain.com/</resource> + <resource>re:^/caldav.php/a[b-x].+/$</resource> + <resource>re|i:^/caldav.php/a[b-x].+/$</resource> + </delegation> + <ignorealarms> + <collection>/caldav.php/user/collection/</collection> + <collection>/caldav.php/user%40domain.com/collection/</collection> + <collection>re:^/caldav.php/user/collection[0-9]/$</collection> + <collection>re|i:^/caldav.php/user/collection[0-9]/$</collection> + </ignorealarms> + <backgroundcalendars> + <collection>/caldav.php/user/collection/</collection> + <collection>/caldav.php/user%40domain.com/collection/</collection> + <collection>re:^/caldav.php/user/collection[0-9]/$</collection> + <collection>re|i:^/caldav.php/user/collection[0-9]/$</collection> + </backgroundcalendars> + <userauth> + <username>user</username> + <password>password</password> + </userauth> + <timeout>90000</timeout> + <locktimeout>10000</locktimeout> + </resource> + <resource> + <type> + <addressbook /> + <calendar /> + </type> + <href>https://www.server3.com:8443/caldav.php/user/</href> + <hreflabel></hreflabel> + <crossdomain>null</crossdomain> + <forcereadonly> + <collection>/caldav.php/user/collection/</collection> + <collection>/caldav.php/user%40domain.com/collection/</collection> + <collection>re:^/caldav.php/user/collection[0-9]/$</collection> + <collection>re|i:^/caldav.php/user/collection[0-9]/$</collection> + </forcereadonly> + <withcredentials>false</withcredentials> + <settingsaccount>false</settingsaccount> + <checkcontenttype>true</checkcontenttype> + <delegation>false</delegation> + <ignorealarms>false</ignorealarms> + <backgroundcalendars /> + <userauth> + <username>user</username> + <password>password</password> + </userauth> + <timeout>90000</timeout> + <locktimeout>10000</locktimeout> + </resource> +</resources> diff --git a/radicale_infcloud/web/auth/doc/readme.txt b/radicale_infcloud/web/auth/doc/readme.txt new file mode 100644 index 0000000..860d29c --- /dev/null +++ b/radicale_infcloud/web/auth/doc/readme.txt @@ -0,0 +1,7 @@ +1.) configure your auth method (see the plugins directory) and the response XML in auth/config.inc and set $config['auth_send_authenticate_header']=true +2.) configure the selected auth module in plugins/PLUGIN_conf.inc +3.) check the correct response by visiting http://your-server.com/client_dir/auth/ and entering username and password +4.) set $config['auth_send_authenticate_header']=false in auth/config.inc + +By default the generic plugin is used for basic HTTP authentication ($config['auth_method']='generic'; in config.inc). + diff --git a/radicale_infcloud/web/auth/index.php b/radicale_infcloud/web/auth/index.php new file mode 100644 index 0000000..e92f005 --- /dev/null +++ b/radicale_infcloud/web/auth/index.php @@ -0,0 +1,33 @@ +<?php + require_once('config.inc'); + require_once('common.inc'); + require_once('cross_domain.inc'); + require_once('plugins/'.$config['auth_method'].'.inc'); // configured module - it defines the 'MODULE_authenticate()' function + + if(call_user_func($config['auth_method'].'_authenticate')!==1) + { + // HTTP authentication (exit if unsuccessfull) + if($config['auth_send_authenticate_header']) + header('WWW-Authenticate: Basic realm="Inf-IT Auth Module"'); + header('HTTP/1.0 401 Unauthorized'); +echo <<<HTML +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> +<html> + <head> + <title>401 Authorization Required</title> + </head> + <body> + <h1>Authorization Required</h1> + <p>This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.</p> + </body> +</html> +HTML; + exit(0); + } + else + { + header('Content-type: text/xml; charset="utf-8"'); + header('Cache-Control: max-age=0, must-revalidate, no-cache, no-store, no-transform, private'); + echo array_to_xml($config['accounts']); + } +?>
\ No newline at end of file diff --git a/radicale_infcloud/web/auth/plugins/generic.inc b/radicale_infcloud/web/auth/plugins/generic.inc new file mode 100644 index 0000000..8e6b14b --- /dev/null +++ b/radicale_infcloud/web/auth/plugins/generic.inc @@ -0,0 +1,58 @@ +<?php + require_once(dirname(__FILE__).'/generic_conf.inc'); + + function generic_authenticate() + { + global $pluginconfig; + if($_SERVER['PHP_AUTH_USER']!='' && $_SERVER['PHP_AUTH_PW']!='') + { + preg_match('#(https?)://([^/:]+)((?::[0-9]+)?)#i', $pluginconfig['base_url'], $matches); + $hostname_clean=$matches[2]; + if($matches[1]=='https') + $hostname='ssl://'.$matches[2]; + else + $hostname=$matches[2]; + + if($matches[3]=='') + { + if($matches[1]=='http') + $port=80; + else if($matches[1]=='https') + $port=443; + } + else + $port=substr($matches[3],1); + + $fp=fsockopen($hostname, $port, $errno, $errstr, $pluginconfig['timeout']); + if(!$fp) + { + echo "$errstr ($errno)<br />\n"; + return -2; + } + else + { + $request="<?xml version=\"1.0\" encoding=\"utf-8\"?><A:propfind xmlns:A=\"DAV:\"><A:prop><A:current-user-principal/></A:prop></A:propfind>"; + + $out="PROPFIND ".$pluginconfig['request']." HTTP/1.1\r\n"; + $out.="Host: $hostname_clean\r\n"; + $out.="Authorization: Basic ".base64_encode($_SERVER['PHP_AUTH_USER'].':'.$_SERVER['PHP_AUTH_PW'])."\r\n"; + $out.="Depth: 0\r\n"; + $out.="Content-Type: text/xml; charset=\"utf-8\"\r\n"; + $out.="Content-Length:". strlen($request)."\r\n\r\n"; + $out.=$request; + fwrite($fp, $out); + + $result=''; + if(!feof($fp)) + $result.=fgets($fp); + fclose($fp); + + if(strpos($result, 'HTTP/1.1 207')===0) + return 1; // auth successful + else + return -1; // auth unsuccessful + } + } + return 0; // empty username or password + } +?>
\ No newline at end of file diff --git a/radicale_infcloud/web/auth/plugins/generic_conf.inc b/radicale_infcloud/web/auth/plugins/generic_conf.inc new file mode 100644 index 0000000..01c2b32 --- /dev/null +++ b/radicale_infcloud/web/auth/plugins/generic_conf.inc @@ -0,0 +1,12 @@ +<?php + // Server base URL + $pluginconfig['base_url']=(empty($_SERVER['HTTPS']) ? 'http' : 'https').'://my.server.com:8080'; + + // Default values are usually OK + // for Davical: + $pluginconfig['request']='/caldav.php'; // change only if your Davical is not installed into server root directory + // for Lion server: + //$pluginconfig['request']='/principals/users'; + + $pluginconfig['timeout']=30; +?>
\ No newline at end of file diff --git a/radicale_infcloud/web/auth/plugins/ldap.inc b/radicale_infcloud/web/auth/plugins/ldap.inc new file mode 100644 index 0000000..f7012e5 --- /dev/null +++ b/radicale_infcloud/web/auth/plugins/ldap.inc @@ -0,0 +1,37 @@ +<?php + require_once(dirname(__FILE__).'/ldap_conf.inc'); + + function ldap_authenticate() + { + global $pluginconfig; + if($_SERVER['PHP_AUTH_USER']!="" && $_SERVER['PHP_AUTH_PW']!="") + { + $ds=ldap_connect($pluginconfig['host']); + + // if binding is required for LDAP search + if(isset($pluginconfig['bind_dn']) && isset($pluginconfig['bind_passwd'])) + { + @ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + if(!($r=@ldap_bind($ds, $pluginconfig['bind_dn'], $pluginconfig['bind_passwd']))) + return -2; // auth unsuccessful (bind error) + } + + // perform the search + if(($r=ldap_search($ds, $pluginconfig['basedn'], '(&('.$pluginconfig['user_attr'].'='.$_SERVER['PHP_AUTH_USER'].')'.(isset($pluginconfig['filter']) && $pluginconfig['filter']!='' ? '('.$pluginconfig['filter'].')' : '' ).')'))!==false) + { + $result=@ldap_get_entries($ds, $r); + if($result[0]) + { + @ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + if(@ldap_bind($ds, $result[0]['dn'], $_SERVER['PHP_AUTH_PW'])) + { + @ldap_unbind($bi); + return 1; // auth successful + } + } + } + return -1; // auth unsuccessful + } + return 0; // empty username or password + } +?>
\ No newline at end of file diff --git a/radicale_infcloud/web/auth/plugins/ldap_conf.inc b/radicale_infcloud/web/auth/plugins/ldap_conf.inc new file mode 100644 index 0000000..c9242c7 --- /dev/null +++ b/radicale_infcloud/web/auth/plugins/ldap_conf.inc @@ -0,0 +1,12 @@ +<?php + // LDAP configuration parameters + $pluginconfig['host']='ldaps://ldap.server.com/'; + $pluginconfig['basedn']='ou=People,dc=server,dc=com'; + $pluginconfig['user_attr']='uid'; + // if the server requires binding (if set to null then binding is not performed) + //$pluginconfig['bind_dn']=null; + //$pluginconfig['bind_passwd']=null; + + // optional + $pluginconfig['filter']='accountStatus=active'; +?>
\ No newline at end of file |