summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/core/lib/Auth/UserPassBase.php136
-rw-r--r--modules/core/templates/default/loginuserpass.php61
-rw-r--r--modules/core/www/loginuserpass.php46
-rw-r--r--modules/exampleauth/default-disable3
-rw-r--r--modules/exampleauth/lib/Auth/Source/Static.php60
-rw-r--r--modules/exampleauth/lib/Auth/Source/UserPass.php93
6 files changed, 399 insertions, 0 deletions
diff --git a/modules/core/lib/Auth/UserPassBase.php b/modules/core/lib/Auth/UserPassBase.php
new file mode 100644
index 0000000..01a1b8f
--- /dev/null
+++ b/modules/core/lib/Auth/UserPassBase.php
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * Helper class for username/password authentication.
+ *
+ * This helper class allows for implementations of username/password authentication by
+ * implementing a single function: login($username, $password)
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
+
+
+ /**
+ * The string used to identify our states.
+ */
+ const STAGEID = 'sspmod_core_Auth_UserPassBase.state';
+
+
+ /**
+ * The key of the AuthId field in the state.
+ */
+ const AUTHID = 'sspmod_core_Auth_UserPassBase.AuthId';
+
+
+ /**
+ * Constructor for this authentication source.
+ *
+ * All subclasses who implement their own constructor must call this constructor before
+ * using $config for anything.
+ *
+ * @param array $info Information about this authentication source.
+ * @param array &$config Configuration for this authentication source.
+ */
+ public function __construct($info, &$config) {
+ assert('is_array($info)');
+ assert('is_array($config)');
+
+ /* Call the parent constructor first, as required by the interface. */
+ parent::__construct($info, $config);
+ }
+
+
+ /**
+ * Initialize login.
+ *
+ * This function saves the information about the login, and redirects to a
+ * login page.
+ *
+ * @param array &$state Information about the current authentication.
+ */
+ public function authenticate(&$state) {
+ assert('is_array($state)');
+
+ /* We are going to need the authId in order to retrieve this authentication source later. */
+ $state[self::AUTHID] = $this->authId;
+
+ $id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
+
+ $url = SimpleSAML_Module::getModuleURL('core/loginuserpass.php');
+ SimpleSAML_Utilities::redirect($url, array('AuthState' => $id));
+ }
+
+
+ /**
+ * Attempt to log in using the given username and password.
+ *
+ * On a successful login, this function should return the users attributes. On failure,
+ * it should throw an exception/error. If the error was caused by the user entering the wrong
+ * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
+ *
+ * Note that both the username and the password are UTF-8 encoded.
+ *
+ * @param string $username The username the user wrote.
+ * @param string $password The password the user wrote.
+ * @return array Associative array with the user's attributes.
+ */
+ abstract protected function login($username, $password);
+
+
+ /**
+ * Handle login request.
+ *
+ * This function is used by the login form (core/www/loginuserpass.php) when the user
+ * enters a username and password. On success, it will not return. On wrong
+ * username/password failure, it will return the error code. Other failures will throw an
+ * exception.
+ *
+ * @param string $authStateId The identifier of the authentication state.
+ * @param string $username The username the user wrote.
+ * @param string $password The password the user wrote.
+ * @return string Error code in the case of an error.
+ */
+ public static function handleLogin($authStateId, $username, $password) {
+ assert('is_string($authStateId)');
+ assert('is_string($username)');
+ assert('is_string($password)');
+
+ /* Retrieve the authentication state. */
+ $state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID);
+
+ /* Find authentication source. */
+ assert('array_key_exists(self::AUTHID, $state)');
+ $source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]);
+ if ($source === NULL) {
+ throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
+ }
+
+
+ try {
+ /* Attempt to log in. */
+ $attributes = $source->login($username, $password);
+ } catch (SimpleSAML_Error_Error $e) {
+ /* An error occured during login. Check if it is because of the wrong
+ * username/password - if it is, we pass that error up to the login form,
+ * if not, we let the generic error handler deal with it.
+ */
+ if ($e->getErrorCode() === 'WRONGUSERPASS') {
+ return 'WRONGUSERPASS';
+ }
+
+ /* Some other error occured. Rethrow exception and let the generic error
+ * handler deal with it.
+ */
+ throw $e;
+ }
+
+ $state['Attributes'] = $attributes;
+ SimpleSAML_Auth_Source::completeAuth($state);
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/modules/core/templates/default/loginuserpass.php b/modules/core/templates/default/loginuserpass.php
new file mode 100644
index 0000000..810abda
--- /dev/null
+++ b/modules/core/templates/default/loginuserpass.php
@@ -0,0 +1,61 @@
+<?php
+$this->data['icon'] = 'lock.png';
+$this->data['header'] = $this->t('{login:user_pass_header}');
+
+if (strlen($this->data['username']) > 0) {
+ $this->data['autofocus'] = 'password';
+} else {
+ $this->data['autofocus'] = 'username';
+}
+$this->includeAtTemplateBase('includes/header.php');
+
+?>
+<div id="content">
+
+<?php
+if ($this->data['errorcode'] !== NULL) {
+?>
+ <div style="border-left: 1px solid #e8e8e8; border-bottom: 1px solid #e8e8e8; background: #f5f5f5">
+ <img src="/<?php echo $this->data['baseurlpath']; ?>resources/icons/bomb.png" style="float: left; margin: 15px " />
+ <h2><?php echo $this->t('{login:error_header}'); ?></h2>
+ <p><b><?php echo $this->t('{errors:title_' . $this->data['errorcode'] . '}'); ?></b></p>
+ <p><?php echo $this->t('{errors:descr_' . $this->data['errorcode'] . '}'); ?></p>
+ </div>
+<?php
+}
+?>
+ <h2 style="break: both"><?php echo $this->t('{login:user_pass_header}'); ?></h2>
+
+ <p><?php echo $this->t('{login:user_pass_text}'); ?></p>
+
+ <form action="?" method="post" name="f">
+
+ <table>
+ <tr>
+ <td rowspan="2"><img src="/<?php echo $this->data['baseurlpath']; ?>resources/icons/pencil.png" alt="" /></td>
+ <td style="padding: .3em;"><?php echo $this->t('{login:username}'); ?></td>
+ <td><input type="text" id="username" tabindex="1" name="username" value="<?php echo htmlspecialchars($this->data['username']); ?>" /></td>
+ <td style="padding: .4em;" rowspan="2">
+ <input type="submit" tabindex="3" value="<?php echo $this->t('{login:login_button}'); ?>" />
+ </td>
+ </tr>
+ <tr>
+ <td style="padding: .3em;"><?php echo $this->t('{login:password}'); ?></td>
+ <td><input id="password" type="password" tabindex="2" name="password" /></td>
+ </tr>
+ </table>
+
+<?php
+foreach ($this->data['stateparams'] as $name => $value) {
+ echo('<input type="hidden" name="' . htmlspecialchars($name) . '" value="' . htmlspecialchars($value) . '" />');
+}
+?>
+
+ </form>
+
+<?php
+echo('<h2>' . $this->t('{login:help_header}') . '</h2>');
+echo('<p>' . $this->t('{login:help_text}') . '</p>');
+
+$this->includeAtTemplateBase('includes/footer.php');
+?> \ No newline at end of file
diff --git a/modules/core/www/loginuserpass.php b/modules/core/www/loginuserpass.php
new file mode 100644
index 0000000..a7bfdb2
--- /dev/null
+++ b/modules/core/www/loginuserpass.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * This page shows a username/password login form, and passes information from it
+ * to the sspmod_core_Auth_UserPassBase class, which is a generic class for
+ * username/password authentication.
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+
+if (!array_key_exists('AuthState', $_REQUEST)) {
+ throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.');
+}
+$authStateId = $_REQUEST['AuthState'];
+
+if (array_key_exists('username', $_REQUEST)) {
+ $username = $_REQUEST['username'];
+} else {
+ $username = '';
+}
+
+if (array_key_exists('password', $_REQUEST)) {
+ $password = $_REQUEST['password'];
+} else {
+ $password = '';
+}
+
+if (!empty($username) || !empty($password)) {
+ /* Either username or password set - attempt to log in. */
+ $errorCode = sspmod_core_Auth_UserPassBase::handleLogin($authStateId, $username, $password);
+} else {
+ $errorCode = NULL;
+}
+
+$globalConfig = SimpleSAML_Configuration::getInstance();
+$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:loginuserpass.php');
+$t->data['stateparams'] = array('AuthState' => $authStateId);
+$t->data['username'] = $username;
+$t->data['errorcode'] = $errorCode;
+$t->show();
+exit();
+
+
+?> \ No newline at end of file
diff --git a/modules/exampleauth/default-disable b/modules/exampleauth/default-disable
new file mode 100644
index 0000000..fa0bd82
--- /dev/null
+++ b/modules/exampleauth/default-disable
@@ -0,0 +1,3 @@
+This file indicates that the default state of this module
+is disabled. To enable, create a file named enable in the
+same directory as this file.
diff --git a/modules/exampleauth/lib/Auth/Source/Static.php b/modules/exampleauth/lib/Auth/Source/Static.php
new file mode 100644
index 0000000..c2a07cc
--- /dev/null
+++ b/modules/exampleauth/lib/Auth/Source/Static.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * Example authentication source.
+ *
+ * This class is an example authentication source which will always return a user with
+ * a static set of attributes.
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_exampleauth_Auth_Source_Static extends SimpleSAML_Auth_Source {
+
+
+ /**
+ * The attributes we return.
+ */
+ private $attributes;
+
+
+ /**
+ * Constructor for this authentication source.
+ *
+ * @param array $info Information about this authentication source.
+ * @param array $config Configuration.
+ */
+ public function __construct($info, $config) {
+ assert('is_array($info)');
+ assert('is_array($config)');
+
+ /* Call the parent constructor first, as required by the interface. */
+ parent::__construct($info, $config);
+
+
+ /* Parse attributes. */
+ try {
+ $this->attributes = SimpleSAML_Utilities::parseAttributes($attributes);
+ } catch(Exception $e) {
+ throw new Exception('Invalid attributes for authentication source ' .
+ $this->authId . ': ' . $e->getMessage());
+ }
+
+ }
+
+
+ /**
+ * Log in using static attributes.
+ *
+ * @param array &$state Information about the current authentication.
+ */
+ public function authenticate(&$state) {
+ assert('is_array($state)');
+
+ $state['Attributes'] = $this->attributes;
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/modules/exampleauth/lib/Auth/Source/UserPass.php b/modules/exampleauth/lib/Auth/Source/UserPass.php
new file mode 100644
index 0000000..98440f5
--- /dev/null
+++ b/modules/exampleauth/lib/Auth/Source/UserPass.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * Example authentication source - username & password.
+ *
+ * This class is an example authentication source which stores all username/passwords in an array,
+ * and authenticates users against this array.
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_exampleauth_Auth_Source_UserPass extends sspmod_core_Auth_UserPassBase {
+
+
+ /**
+ * Our users, stored in an associative array. The key of the array is "<username>:<password>",
+ * while the value of each element is a new array with the attributes for each user.
+ */
+ private $users;
+
+
+ /**
+ * Constructor for this authentication source.
+ *
+ * @param array $info Information about this authentication source.
+ * @param array $config Configuration.
+ */
+ public function __construct($info, $config) {
+ assert('is_array($info)');
+ assert('is_array($config)');
+
+ /* Call the parent constructor first, as required by the interface. */
+ parent::__construct($info, $config);
+
+ $this->users = array();
+
+ /* Validate and parse our configuration. */
+ foreach ($config as $userpass => $attributes) {
+ if (!is_string($userpass)) {
+ throw new Exception('Invalid <username>:<password> for authentication source ' .
+ $this->authId . ': ' . $userpass);
+ }
+
+ $userpass = explode(':', $userpass, 2);
+ if (count($userpass) !== 2) {
+ throw new Exception('Invalid <username>:<password> for authentication source ' .
+ $this->authId . ': ' . $userpass[0]);
+ }
+ $username = $userpass[0];
+ $password = $userpass[1];
+
+ try {
+ $attributes = SimpleSAML_Utilities::parseAttributes($attributes);
+ } catch(Exception $e) {
+ throw new Exception('Invalid attributes for user ' . $username .
+ ' in authentication source ' . $this->authId . ': ' .
+ $e->getMessage());
+ }
+
+ $this->users[$username . ':' . $password] = $attributes;
+ }
+ }
+
+
+ /**
+ * Attempt to log in using the given username and password.
+ *
+ * On a successful login, this function should return the users attributes. On failure,
+ * it should throw an exception. If the error was caused by the user entering the wrong
+ * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
+ *
+ * Note that both the username and the password are UTF-8 encoded.
+ *
+ * @param string $username The username the user wrote.
+ * @param string $password The password the user wrote.
+ * @return array Associative array with the users attributes.
+ */
+ protected function login($username, $password) {
+ assert('is_string($username)');
+ assert('is_string($password)');
+
+ $userpass = $username . ':' . $password;
+ if (!array_key_exists($userpass, $this->users)) {
+ throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+ }
+
+ return $this->users[$userpass];
+ }
+
+}
+
+?> \ No newline at end of file