Index: lang/en/auth_db.php =================================================================== --- lang/en/auth_db.php (wersja 4) +++ lang/en/auth_db.php (kopia robocza) @@ -70,3 +70,9 @@ $string['auth_dbuserstoremove'] = 'User entries to remove: {$a}'; $string['pluginname'] = 'External database'; $string['privacy:metadata'] = 'The External database authentication plugin does not store any personal data.'; +$string['passlibhandlers'] = 'Passlib crypt handlers'; +$string['passlibhandlerhelp'] = '

Using \'Passlib crypt handlers\' requires python-passlib libraries installed on the server along with python binary itself and pathtopyton moodle variable set properly. See Passlib documentation for more explanation.

'; +$string['pathtopythonnotset'] = 'Path to python not set!'; +$string['pythonpipeerror'] = 'Python pipe error!'; +$string['pythonexecerror'] = 'Python code execute error!'; + Index: auth.php =================================================================== --- auth.php (wersja 4) +++ auth.php (kopia robocza) @@ -138,7 +138,9 @@ return (strtolower($fromdb) == sha1($extpassword)); } else if ($this->config->passtype === 'saltedcrypt') { return password_verify($extpassword, $fromdb); - } else { + } else if (strpos($this->config->passtype, 'passlib:') === 0) { + return $this->passlib_verify($extpassword, $fromdb); + } else { return false; } @@ -146,6 +148,79 @@ } /** + * Execude python code using configured pathtopython + * + * @param string $code + * @return string + * @throws moodle_exception + */ + public static function python_exec($code) { + global $CFG; + if(empty($CFG->pathtopython)) { + throw new moodle_exception('pathtopythonnotset', 'auth_db'); + } + + $proc = proc_open( + $CFG->pathtopython, + [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], + $pipes + ); + if(!is_resource($proc)) { + throw new moodle_exception('pythonpipeerror', 'auth_db'); + } + + fwrite($pipes[0], $code); + fclose($pipes[0]); + $stdout = stream_get_contents($pipes[1]); + fclose($pipes[1]); + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + $exitcode = proc_close($proc); + + if($exitcode != 0) { + debugging($stdout."\n".$stderr."\n"); + throw new moodle_exception('pythonexecerror', 'auth_db'); + } + return trim($stdout); + } + + /** + * Verify password using Passlib + * + * @param string $password + * @param string $hash + * @return bool + * @throws moodle_exception + */ + function passlib_verify($password, $hash) { + $passlibhandler = substr( + $this->config->passtype, + strpos($this->config->passtype, ':') + 1 + ); + $password = addslashes($password); + $hash = addslashes($hash); + $code = <<dirroot.'/auth/db/auth.php'); + try { + foreach (auth_plugin_db::passlib_list_crypt_handlers() as $passlibhandler) { + $passtype['passlib:'.$passlibhandler] = $passlibhandler; + } + } catch(moodle_exception $e) {} + $settings->add(new admin_setting_configselect('auth_db/passtype', - new lang_string('auth_dbpasstype_key', 'auth_db'), new lang_string('auth_dbpasstype', 'auth_db'), 'plaintext', $passtype)); + new lang_string('auth_dbpasstype_key', 'auth_db'), new lang_string('auth_dbpasstype', 'auth_db').new lang_string('passlibhandlerhelp', 'auth_db'), 'plaintext', $passtype)); // Encoding. $settings->add(new admin_setting_configtext('auth_db/extencoding', get_string('auth_dbextencoding', 'auth_db'),