PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/auth/cas/auth.php

https://github.com/ctham/moodle
PHP | 408 lines | 265 code | 44 blank | 99 comment | 67 complexity | bfbfc9992fc734cb9da4b4c5467781dc MD5 | raw file
  1. <?php
  2. /**
  3. * @author Martin Dougiamas
  4. * @author Jerome GUTIERREZ
  5. * @author I�aki Arenaza
  6. * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  7. * @package moodle multiauth
  8. *
  9. * Authentication Plugin: CAS Authentication
  10. *
  11. * Authentication using CAS (Central Authentication Server).
  12. *
  13. * 2006-08-28 File created.
  14. */
  15. if (!defined('MOODLE_INTERNAL')) {
  16. die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
  17. }
  18. require_once($CFG->dirroot.'/auth/ldap/auth.php');
  19. require_once($CFG->dirroot.'/auth/cas/CAS/CAS.php');
  20. /**
  21. * CAS authentication plugin.
  22. */
  23. class auth_plugin_cas extends auth_plugin_ldap {
  24. /**
  25. * Constructor.
  26. */
  27. function auth_plugin_cas() {
  28. $this->authtype = 'cas';
  29. $this->roleauth = 'auth_cas';
  30. $this->errorlogtag = '[AUTH CAS] ';
  31. $this->init_plugin($this->authtype);
  32. }
  33. function prevent_local_passwords() {
  34. return true;
  35. }
  36. /**
  37. * Authenticates user against CAS
  38. * Returns true if the username and password work and false if they are
  39. * wrong or don't exist.
  40. *
  41. * @param string $username The username (with system magic quotes)
  42. * @param string $password The password (with system magic quotes)
  43. * @return bool Authentication success or failure.
  44. */
  45. function user_login ($username, $password) {
  46. $this->connectCAS();
  47. return phpCAS::isAuthenticated() && (trim(moodle_strtolower(phpCAS::getUser())) == $username);
  48. }
  49. /**
  50. * Returns true if this authentication plugin is 'internal'.
  51. *
  52. * @return bool
  53. */
  54. function is_internal() {
  55. return false;
  56. }
  57. /**
  58. * Returns true if this authentication plugin can change the user's
  59. * password.
  60. *
  61. * @return bool
  62. */
  63. function can_change_password() {
  64. return false;
  65. }
  66. /**
  67. * Authentication choice (CAS or other)
  68. * Redirection to the CAS form or to login/index.php
  69. * for other authentication
  70. */
  71. function loginpage_hook() {
  72. global $frm;
  73. global $CFG;
  74. global $SESSION, $OUTPUT, $PAGE;
  75. $site = get_site();
  76. $CASform = get_string('CASform', 'auth_cas');
  77. $username = optional_param('username', '', PARAM_RAW);
  78. if (!empty($username)) {
  79. if (isset($SESSION->wantsurl) && (strstr($SESSION->wantsurl, 'ticket') ||
  80. strstr($SESSION->wantsurl, 'NOCAS'))) {
  81. unset($SESSION->wantsurl);
  82. }
  83. return;
  84. }
  85. // Return if CAS enabled and settings not specified yet
  86. if (empty($this->config->hostname)) {
  87. return;
  88. }
  89. // Connection to CAS server
  90. $this->connectCAS();
  91. if (phpCAS::checkAuthentication()) {
  92. $frm->username = phpCAS::getUser();
  93. $frm->password = 'passwdCas';
  94. return;
  95. }
  96. if (isset($_GET['loginguest']) && ($_GET['loginguest'] == true)) {
  97. $frm->username = 'guest';
  98. $frm->password = 'guest';
  99. return;
  100. }
  101. if ($this->config->multiauth) {
  102. $authCAS = optional_param('authCAS', '', PARAM_RAW);
  103. if ($authCAS == 'NOCAS') {
  104. return;
  105. }
  106. // Show authentication form for multi-authentication
  107. // test pgtIou parameter for proxy mode (https connection
  108. // in background from CAS server to the php server)
  109. if ($authCAS != 'CAS' && !isset($_GET['pgtIou'])) {
  110. $PAGE->set_url('/auth/cas/auth.php');
  111. $PAGE->navbar->add($CASform);
  112. $PAGE->set_title("$site->fullname: $CASform");
  113. $PAGE->set_heading($site->fullname);
  114. echo $OUTPUT->header();
  115. include($CFG->dirroot.'/auth/cas/cas_form.html');
  116. echo $OUTPUT->footer();
  117. exit();
  118. }
  119. }
  120. // Force CAS authentication (if needed).
  121. if (!phpCAS::isAuthenticated()) {
  122. phpCAS::setLang($this->config->language);
  123. phpCAS::forceAuthentication();
  124. }
  125. }
  126. /**
  127. * Logout from the CAS
  128. *
  129. */
  130. function prelogout_hook() {
  131. global $CFG;
  132. if ($this->config->logoutcas) {
  133. $backurl = $CFG->wwwroot;
  134. $this->connectCAS();
  135. phpCAS::logoutWithURL($backurl);
  136. }
  137. }
  138. /**
  139. * Connect to the CAS (clientcas connection or proxycas connection)
  140. *
  141. */
  142. function connectCAS() {
  143. global $PHPCAS_CLIENT;
  144. if (!is_object($PHPCAS_CLIENT)) {
  145. // Make sure phpCAS doesn't try to start a new PHP session when connecting to the CAS server.
  146. if ($this->config->proxycas) {
  147. phpCAS::proxy($this->config->casversion, $this->config->hostname, (int) $this->config->port, $this->config->baseuri, false);
  148. } else {
  149. phpCAS::client($this->config->casversion, $this->config->hostname, (int) $this->config->port, $this->config->baseuri, false);
  150. }
  151. }
  152. if($this->config->certificate_check && $this->config->certificate_path){
  153. phpCAS::setCasServerCACert($this->config->certificate_path);
  154. }else{
  155. // Don't try to validate the server SSL credentials
  156. phpCAS::setNoCasServerValidation();
  157. }
  158. }
  159. /**
  160. * Prints a form for configuring this authentication plugin.
  161. *
  162. * This function is called from admin/auth.php, and outputs a full page with
  163. * a form for configuring this plugin.
  164. *
  165. * @param array $page An object containing all the data for this page.
  166. */
  167. function config_form($config, $err, $user_fields) {
  168. global $CFG, $OUTPUT;
  169. if (!function_exists('ldap_connect')) { // Is php-ldap really there?
  170. echo $OUTPUT->notification(get_string('auth_ldap_noextension', 'auth_ldap'));
  171. // Don't return here, like we do in auth/ldap. We cas use CAS without LDAP.
  172. // So just warn the user (done above) and define the LDAP constants we use
  173. // in config.html, to silence the warnings.
  174. if (!defined('LDAP_DEREF_NEVER')) {
  175. define ('LDAP_DEREF_NEVER', 0);
  176. }
  177. if (!defined('LDAP_DEREF_ALWAYS')) {
  178. define ('LDAP_DEREF_ALWAYS', 3);
  179. }
  180. }
  181. include($CFG->dirroot.'/auth/cas/config.html');
  182. }
  183. /**
  184. * A chance to validate form data, and last chance to
  185. * do stuff before it is inserted in config_plugin
  186. * @param object object with submitted configuration settings (without system magic quotes)
  187. * @param array $err array of error messages
  188. */
  189. function validate_form(&$form, &$err) {
  190. $certificate_path = trim($form->certificate_path);
  191. if ($form->certificate_check && empty($certificate_path)) {
  192. $err['certificate_path'] = get_string('auth_cas_certificate_path_empty', 'auth_cas');
  193. }
  194. }
  195. /**
  196. * Returns the URL for changing the user's pw, or empty if the default can
  197. * be used.
  198. *
  199. * @return moodle_url
  200. */
  201. function change_password_url() {
  202. return null;
  203. }
  204. /**
  205. * Processes and stores configuration data for this authentication plugin.
  206. */
  207. function process_config($config) {
  208. // CAS settings
  209. if (!isset($config->hostname)) {
  210. $config->hostname = '';
  211. }
  212. if (!isset($config->port)) {
  213. $config->port = '';
  214. }
  215. if (!isset($config->casversion)) {
  216. $config->casversion = '';
  217. }
  218. if (!isset($config->baseuri)) {
  219. $config->baseuri = '';
  220. }
  221. if (!isset($config->language)) {
  222. $config->language = '';
  223. }
  224. if (!isset($config->proxycas)) {
  225. $config->proxycas = '';
  226. }
  227. if (!isset($config->logoutcas)) {
  228. $config->logoutcas = '';
  229. }
  230. if (!isset($config->multiauth)) {
  231. $config->multiauth = '';
  232. }
  233. if (!isset($config->certificate_check)) {
  234. $config->certificate_check = '';
  235. }
  236. if (!isset($config->certificate_path)) {
  237. $config->certificate_path = '';
  238. }
  239. // LDAP settings
  240. if (!isset($config->host_url)) {
  241. $config->host_url = '';
  242. }
  243. if (empty($config->ldapencoding)) {
  244. $config->ldapencoding = 'utf-8';
  245. }
  246. if (!isset($config->contexts)) {
  247. $config->contexts = '';
  248. }
  249. if (!isset($config->user_type)) {
  250. $config->user_type = 'default';
  251. }
  252. if (!isset($config->user_attribute)) {
  253. $config->user_attribute = '';
  254. }
  255. if (!isset($config->search_sub)) {
  256. $config->search_sub = '';
  257. }
  258. if (!isset($config->opt_deref)) {
  259. $config->opt_deref = LDAP_DEREF_NEVER;
  260. }
  261. if (!isset($config->bind_dn)) {
  262. $config->bind_dn = '';
  263. }
  264. if (!isset($config->bind_pw)) {
  265. $config->bind_pw = '';
  266. }
  267. if (!isset($config->ldap_version)) {
  268. $config->ldap_version = '3';
  269. }
  270. if (!isset($config->objectclass)) {
  271. $config->objectclass = '';
  272. }
  273. if (!isset($config->memberattribute)) {
  274. $config->memberattribute = '';
  275. }
  276. if (!isset($config->memberattribute_isdn)) {
  277. $config->memberattribute_isdn = '';
  278. }
  279. if (!isset($config->attrcreators)) {
  280. $config->attrcreators = '';
  281. }
  282. if (!isset($config->groupecreators)) {
  283. $config->groupecreators = '';
  284. }
  285. if (!isset($config->removeuser)) {
  286. $config->removeuser = AUTH_REMOVEUSER_KEEP;
  287. }
  288. // save CAS settings
  289. set_config('hostname', trim($config->hostname), $this->pluginconfig);
  290. set_config('port', trim($config->port), $this->pluginconfig);
  291. set_config('casversion', $config->casversion, $this->pluginconfig);
  292. set_config('baseuri', trim($config->baseuri), $this->pluginconfig);
  293. set_config('language', $config->language, $this->pluginconfig);
  294. set_config('proxycas', $config->proxycas, $this->pluginconfig);
  295. set_config('logoutcas', $config->logoutcas, $this->pluginconfig);
  296. set_config('multiauth', $config->multiauth, $this->pluginconfig);
  297. set_config('certificate_check', $config->certificate_check, $this->pluginconfig);
  298. set_config('certificate_path', $config->certificate_path, $this->pluginconfig);
  299. // save LDAP settings
  300. set_config('host_url', trim($config->host_url), $this->pluginconfig);
  301. set_config('ldapencoding', trim($config->ldapencoding), $this->pluginconfig);
  302. set_config('contexts', trim($config->contexts), $this->pluginconfig);
  303. set_config('user_type', moodle_strtolower(trim($config->user_type)), $this->pluginconfig);
  304. set_config('user_attribute', moodle_strtolower(trim($config->user_attribute)), $this->pluginconfig);
  305. set_config('search_sub', $config->search_sub, $this->pluginconfig);
  306. set_config('opt_deref', $config->opt_deref, $this->pluginconfig);
  307. set_config('bind_dn', trim($config->bind_dn), $this->pluginconfig);
  308. set_config('bind_pw', $config->bind_pw, $this->pluginconfig);
  309. set_config('ldap_version', $config->ldap_version, $this->pluginconfig);
  310. set_config('objectclass', trim($config->objectclass), $this->pluginconfig);
  311. set_config('memberattribute', moodle_strtolower(trim($config->memberattribute)), $this->pluginconfig);
  312. set_config('memberattribute_isdn', $config->memberattribute_isdn, $this->pluginconfig);
  313. set_config('attrcreators', trim($config->attrcreators), $this->pluginconfig);
  314. set_config('groupecreators', trim($config->groupecreators), $this->pluginconfig);
  315. set_config('removeuser', $config->removeuser, $this->pluginconfig);
  316. return true;
  317. }
  318. /**
  319. * Returns true if user should be coursecreator.
  320. *
  321. * @param mixed $username username (without system magic quotes)
  322. * @return boolean result
  323. */
  324. function iscreator($username) {
  325. if ((empty($this->config->attrcreators) && empty($this->config->groupecreators)) or empty($this->config->memberattribute)) {
  326. return false;
  327. }
  328. $textlib = textlib_get_instance();
  329. $extusername = $textlib->convert($username, 'utf-8', $this->config->ldapencoding);
  330. // Test for group creator
  331. if (!empty($this->config->groupecreators)) {
  332. if ($this->config->memberattribute_isdn) {
  333. if(!($userid = $this->ldap_find_userdn($ldapconnection, $extusername))) {
  334. return false;
  335. }
  336. } else {
  337. $userid = $extusername;
  338. }
  339. $group_dns = explode(';', $this->config->groupecreators);
  340. if (ldap_isgroupmember($ldapconnection, $userid, $group_dns, $this->config->memberattribute)) {
  341. return true;
  342. }
  343. }
  344. // Build filter for attrcreator
  345. if (!empty($this->config->attrcreators)) {
  346. $attrs = explode(';', $this->config->attrcreators);
  347. $filter = '(& ('.$this->config->user_attribute."=$username)(|";
  348. foreach ($attrs as $attr){
  349. if(strpos($attr, '=')) {
  350. $filter .= "($attr)";
  351. } else {
  352. $filter .= '('.$this->config->memberattribute."=$attr)";
  353. }
  354. }
  355. $filter .= '))';
  356. // Search
  357. $result = $this->ldap_get_userlist($filter);
  358. if (count($result) != 0) {
  359. return true;
  360. }
  361. }
  362. return false;
  363. }
  364. }