Skip to content

Commit 135528a

Browse files
committed
Initial import
1 parent 686e42f commit 135528a

12 files changed

Lines changed: 476 additions & 0 deletions

File tree

.codecov.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
coverage:
2+
status:
3+
project: yes
4+
5+
comment:
6+
layout: "diff"
7+
behavior: once
8+
require_changes: true
9+
require_base: no
10+
require_head: yes
11+
branches: null

.php_cs.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
$finder = PhpCsFixer\Finder::create()
3+
->in([
4+
__DIR__ . '/lib',
5+
__DIR__ . '/tests',
6+
])
7+
;
8+
return PhpCsFixer\Config::create()
9+
->setRules([
10+
'@PSR2' => true,
11+
'@PSR4' => true,
12+
'@PSR5' => true,
13+
])
14+
->setFinder($finder)
15+
;

.travis.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
sudo: required
2+
3+
language: php
4+
5+
php:
6+
- 5.6
7+
- 7.0
8+
- 7.1
9+
- 7.2
10+
- 7.3
11+
12+
env:
13+
- SIMPLESAMLPHP_VERSION=1.17.*
14+
15+
matrix:
16+
allow_failures:
17+
- php: 7.3
18+
19+
before_script:
20+
- composer require "simplesamlphp/simplesamlphp:${SIMPLESAMLPHP_VERSION}" --no-update
21+
- composer update --no-interaction
22+
- if [[ "$TRAVIS_PHP_VERSION" == "7.3" ]]; then composer require --dev vimeo/psalm:1.1.9; fi
23+
24+
script:
25+
- bin/check-syntax.sh
26+
- if [[ "$TRAVIS_PHP_VERSION" == "5.6" ]]; then php vendor/phpunit/phpunit/phpunit; else php vendor/phpunit/phpunit/phpunit --no-coverage; fi
27+
- if [[ "$TRAVIS_PHP_VERSION" == "7.3" ]]; then vendor/bin/psalm; fi
28+
29+
after_success:
30+
# Codecov, need to edit bash uploader for incorrect TRAVIS_PYTHON_VERSION environment variable matching, at least until codecov/codecov-bash#133 is resolved
31+
- curl -s https://codecov.io/bash > .codecov
32+
- sed -i -e 's/TRAVIS_.*_VERSION/^TRAVIS_.*_VERSION=/' .codecov
33+
- chmod +x .codecov
34+
- if [[ $TRAVIS_PHP_VERSION == "5.6" ]]; then ./.codecov -X gcov; fi
35+
# - if [[ "$TRAVIS_PHP_VERSION" == "5.6" ]]; then bash <(curl -s https://codecov.io/bash); fi

bin/check-syntax.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env bash
2+
3+
PHP='/usr/bin/env php'
4+
RETURN=0
5+
6+
# check PHP files
7+
for FILE in `find lib tests -name "*.php"`; do
8+
$PHP -l $FILE > /dev/null 2>&1
9+
if [ $? -ne 0 ]; then
10+
echo "Syntax check failed for ${FILE}"
11+
RETURN=`expr ${RETURN} + 1`
12+
fi
13+
done
14+
15+
exit $RETURN

composer.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "simplesamlphp/simplesamlphp-module-authcrypt",
3+
"description": "This module provides authentication against password hashes or .htpasswd files",
4+
"type": "simplesamlphp-module",
5+
"keywords": ["simplesamlphp", "authcrypt"],
6+
"license": "LGPL-3.0-or-later",
7+
"authors": [
8+
{
9+
"name": "Olav Morken",
10+
"email": "olavmrk@gmail.com"
11+
}
12+
],
13+
"config": {
14+
"preferred-install": {
15+
"simplesamlphp/simplesamlphp": "source",
16+
"*": "dist"
17+
}
18+
},
19+
"autoload": {
20+
"psr-4": {
21+
"SimpleSAML\\Module\\authcrypt\\": "lib/"
22+
}
23+
},
24+
"autoload-dev": {
25+
"psr-4": {
26+
"SimpleSAML\\Test\\Utils\\": "vendor/simplesamlphp/simplesamlphp/tests/Utils"
27+
}
28+
},
29+
"require": {
30+
"php": ">=5.6",
31+
"simplesamlphp/composer-module-installer": "~1.1",
32+
"webmozart/assert": "~1.4",
33+
},
34+
"require-dev": {
35+
"simplesamlphp/simplesamlphp": "^1.17",
36+
"phpunit/phpunit": "~5.7"
37+
},
38+
"support": {
39+
"issues": "https://github.com/tvdijen/simplesamlphp-module-authcrypt/issues",
40+
"source": "https://github.com/tvdijen/simplesamlphp-module-authcrypt"
41+
}
42+
}

default-disable

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
This file indicates that the default state of this module
2+
is disabled. To enable, create a file named enable in the
3+
same directory as this file.

docs/authcrypt.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
AuthCrypt
2+
=========
3+
4+
This module provides two methods for authentication:
5+
6+
`authcrypt:Hash`
7+
: Username & password authentication with hashed passwords.
8+
9+
`authcrypt:Htpasswd`
10+
: Username & password authentication against an `.htpasswd` file.
11+
12+
13+
`authcrypt:Hash`
14+
----------------
15+
16+
This is based on `exampleAuth:UserPass`, and adds support for hashed passwords.
17+
Hashes can be generated with the included command line tool `bin/pwgen.sh`.
18+
This tool will interactively ask for a password, a hashing algorithm , and whether or not you want to use a salt:
19+
20+
[user@server simplesamlphp]$ bin/pwgen.php
21+
Enter password: hackme
22+
The following hashing algorithms are available:
23+
md2 md4 md5 sha1 sha224 sha256
24+
sha384 sha512 ripemd128 ripemd160 ripemd256 ripemd320
25+
whirlpool tiger128,3 tiger160,3 tiger192,3 tiger128,4 tiger160,4
26+
tiger192,4 snefru snefru256 gost adler32 crc32
27+
crc32b salsa10 salsa20 haval128,3 haval160,3 haval192,3
28+
haval224,3 haval256,3 haval128,4 haval160,4 haval192,4 haval224,4
29+
haval256,4 haval128,5 haval160,5 haval192,5 haval224,5 haval256,5
30+
31+
Which one do you want? [sha256]
32+
Do you want to use a salt? (yes/no) [yes]
33+
34+
{SSHA256}y1mj3xsZ4/+LoQyPNVJzXUFfBcLHfwcHx1xxltxeQ1C5MeyEX/RxWA==
35+
36+
Now create an authentication source in `config/authsources.php` and use the resulting string as the password:
37+
38+
'example-hashed' => array(
39+
'authCrypt:Hash',
40+
'student:{SSHA256}y1mj3xsZ4/+LoQyPNVJzXUFfBcLHfwcHx1xxltxeQ1C5MeyEX/RxWA==' => array(
41+
'uid' => array('student'),
42+
'eduPersonAffiliation' => array('member', 'student'),
43+
),
44+
),
45+
46+
This example creates a user `student` with password `hackme`, and some attributes.
47+
48+
### Compatibility ###
49+
The generated hashes can also be used in `config.php` for the administrative password:
50+
51+
'auth.adminpassword' => '{SSHA256}y1mj3xsZ4/+LoQyPNVJzXUFfBcLHfwcHx1xxltxeQ1C5MeyEX/RxWA==',
52+
53+
Instead of generating hashes, you can also use existing ones from OpenLDAP, provided that the `userPassword` attribute is stored as MD5, SMD5, SHA, or SSHA.
54+
55+
56+
`authCrypt:Htpasswd`
57+
--------------------
58+
59+
Authenticate users against an [`.htpasswd`](http://httpd.apache.org/docs/2.2/programs/htpasswd.html) file. It can be used for example when you migrate a web site from basic HTTP authentication to SimpleSAMLphp.
60+
61+
The simple structure of the `.htpasswd` file does not allow for per-user attributes, but you can define some static attributes for all users.
62+
63+
An example authentication source in `config/authsources.php` could look like this:
64+
65+
'htpasswd' => array(
66+
'authcrypt:Htpasswd',
67+
'htpasswd_file' => '/var/www/foo.edu/legacy_app/.htpasswd',
68+
'static_attributes' => array(
69+
'eduPersonAffiliation' => array('member', 'employee'),
70+
'Organization' => array('University of Foo'),
71+
),
72+
),
73+

lib/Auth/Source/Hash.php

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
namespace SimpleSAML\Module\authcrypt\Auth\Source;
4+
5+
/**
6+
* Authentication source for username & hashed password.
7+
*
8+
* This class is an authentication source which stores all username/hashes in an array,
9+
* and authenticates users against this array.
10+
*
11+
* @author Dyonisius Visser, TERENA.
12+
* @package SimpleSAMLphp
13+
*/
14+
15+
class Hash extends \SimpleSAML\Module\core\Auth\UserPassBase
16+
{
17+
/**
18+
* Our users, stored in an associative array. The key of the array is "<username>:<passwordhash>",
19+
* while the value of each element is a new array with the attributes for each user.
20+
*/
21+
private $users;
22+
23+
24+
/**
25+
* Constructor for this authentication source.
26+
*
27+
* @param array $info Information about this authentication source.
28+
* @param array $config Configuration.
29+
*
30+
* @throws Exception in case of a configuration error.
31+
*/
32+
public function __construct($info, $config)
33+
{
34+
assert(is_array($info));
35+
assert(is_array($config));
36+
37+
// Call the parent constructor first, as required by the interface
38+
parent::__construct($info, $config);
39+
40+
$this->users = [];
41+
42+
// Validate and parse our configuration
43+
foreach ($config as $userpass => $attributes) {
44+
if (!is_string($userpass)) {
45+
throw new \Exception('Invalid <username>:<passwordhash> for authentication source '.
46+
$this->authId.': '.$userpass);
47+
}
48+
49+
$userpass = explode(':', $userpass, 2);
50+
if (count($userpass) !== 2) {
51+
throw new \Exception('Invalid <username>:<passwordhash> for authentication source '.
52+
$this->authId.': '.$userpass[0]);
53+
}
54+
$username = $userpass[0];
55+
$passwordhash = $userpass[1];
56+
57+
try {
58+
$attributes = \SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes);
59+
} catch (\Exception $e) {
60+
throw new \Exception('Invalid attributes for user '.$username.
61+
' in authentication source '.$this->authId.': '.
62+
$e->getMessage());
63+
}
64+
65+
$this->users[$username.':'.$passwordhash] = $attributes;
66+
}
67+
}
68+
69+
70+
/**
71+
* Attempt to log in using the given username and password.
72+
*
73+
* On a successful login, this function should return the users attributes. On failure,
74+
* it should throw an exception. If the error was caused by the user entering the wrong
75+
* username OR password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
76+
*
77+
* The username is UTF-8 encoded, and the hash is base64 encoded.
78+
*
79+
* @param string $username The username the user wrote.
80+
* @param string $password The password the user wrote.
81+
*
82+
* @return array Associative array with the users attributes.
83+
*
84+
* @throws \SimpleSAML\Error\Error if authentication fails.
85+
*/
86+
protected function login($username, $password)
87+
{
88+
assert(is_string($username));
89+
assert(is_string($password));
90+
91+
foreach ($this->users as $userpass => $attrs) {
92+
$matches = explode(':', $userpass, 2);
93+
if ($matches[0] === $username) {
94+
if (\SimpleSAML\Utils\Crypto::pwValid($matches[1], $password)) {
95+
return $attrs;
96+
} else {
97+
\SimpleSAML\Logger::debug('Incorrect password "'.$password.'" for user '.$username);
98+
}
99+
}
100+
}
101+
throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
102+
}
103+
}

0 commit comments

Comments
 (0)