0
0
mirror of https://github.com/postfixadmin/postfixadmin.git synced 2024-09-19 19:22:14 +02:00

remove dead code

This commit is contained in:
David Goodwin 2022-06-06 20:34:05 +01:00
parent c4c7753740
commit 35486a2ca9
3 changed files with 10 additions and 406 deletions

View File

@ -1330,6 +1330,9 @@ function pacrypt($pw, $pw_db = "")
if ($mechanism == 'AUTHLIB') {
return _pacrypt_authlib($pw, $pw_db);
}
var_dump($mechanism, $pw_db);
$hasher = new \PostfixAdmin\PasswordHashing\Crypt($mechanism);
return $hasher->crypt($pw, $pw_db);
}

View File

@ -1,371 +0,0 @@
<?php
class PFACrypt
{
private $algorithm;
const DOVECOT_NATIVE = [
'SHA1', 'SHA1.HEX', 'SHA1.B64',
'SSHA',
'BLF-CRYPT', 'BLF-CRYPT.B64',
'SHA512-CRYPT', 'SHA512-CRYPT.B64',
'ARGON2I',
'ARGON2I.B64',
'ARGON2ID',
'ARGON2ID.B64',
'SHA256', 'SHA256-CRYPT', 'SHA256-CRYPT.B64',
'SHA512-CRYPT',
'SHA512', 'SHA512.B64',
'MD5-CRYPT',
'PLAIN-MD5',
'CRYPT',
];
public function __construct(string $algorithm)
{
$this->algorithm = $algorithm;
}
/**
* When called with a 'pw' and a 'pw_db' (hash from e.g. database).
*
* If the return value matches $pw_db, then the plain text password ('pw') is correct.
*
* @param string $pw - plain text password
* @param string $pw_db - hash from e.g. database (what we're comparing $pw to).
* @return string if $pw is correct (hashes to $pw_db) then we return $pw_db. Else we return a new hash.
*
* @throws Exception
*/
public function pacrypt(string $pw, string $pw_db = ''): string
{
$algorithm = strtoupper($this->algorithm);
// try and 'upgrade' some dovecot commands to use local algorithms (rather tnan a dependency on the dovecot binary).
if (preg_match('/^DOVECOT:/i', $algorithm)) {
$tmp = preg_replace('/^DOVECOT:/i', '', $algorithm);
if (in_array($tmp, self::DOVECOT_NATIVE)) {
$algorithm = $tmp;
} else {
error_log("Warning: using algorithm that requires proc_open: $algorithm, consider using one of : " . implode(', ', self::DOVECOT_NATIVE));
}
}
if (!empty($pw_db) && preg_match('/^{([0-9a-z-\.]+)}/i', $pw_db, $matches)) {
$method_in_hash = $matches[1];
if ('COURIER:' . strtoupper($method_in_hash) == $algorithm) {
// don't try and be clever.
} elseif ($algorithm != $method_in_hash) {
error_log("Hey, you fed me a password using {$method_in_hash}, but the system is configured to use {$algorithm}");
$algorithm = $method_in_hash;
}
}
if (!empty($pw_db) && preg_match('/^\$[0-9]\$/i', $pw_db, $matches)) {
$method_in_hash = $matches[0];
switch ($method_in_hash) {
case '$1$':
case '$6$':
$algorithm='SYSTEM';
}
}
if ($algorithm == 'SHA512CRYPT.B64') {
$algorithm = 'SHA512-CRYPT.B64';
}
switch ($algorithm) {
case 'SHA1':
case 'SHA1.B64':
case 'SHA1.HEX':
return $this->hashSha1($pw, $pw_db, $algorithm);
case 'BLF-CRYPT':
case 'BLF-CRYPT.B64':
return $this->blowfishCrypt($pw, $pw_db, $algorithm);
case 'SHA512-CRYPT':
case 'SHA512-CRYPT.B64':
return $this->sha512Crypt($pw, $pw_db, $algorithm);
case 'ARGON2I':
case 'ARGON2I.B64':
return $this->argon2iCrypt($pw, $pw_db, $algorithm);
case 'ARGON2ID':
case 'ARGON2ID.B64':
return $this->argon2idCrypt($pw, $pw_db, $algorithm);
case 'SSHA':
case 'COURIER:SSHA':
return $this->hashSha1Salted($pw, $pw_db);
case 'SHA256':
case 'COURIER:SHA256':
return $this->hashSha256($pw);
case 'SHA256-CRYPT':
case 'SHA256-CRYPT.B64':
return $this->sha256Crypt($pw, $pw_db, $algorithm);
case 'SHA512':
case 'SHA512B.b64':
case 'SHA512.B64':
return $this->hashSha512($pw, $algorithm);
case 'PLAIN-MD5': // {PLAIN-MD5} prefix
case 'MD5': // no prefix
return $this->hashMd5($pw, $algorithm); // this is hex encoded.
case 'COURIER:MD5':
return '{MD5}' . base64_encode(md5($pw, true)); // seems to need to be base64 encoded.
case 'COURIER:MD5RAW':
return '{MD5RAW}' . md5($pw);
case 'MD5-CRYPT':
return $this->cryptMd5($pw, $pw_db, $algorithm);
case 'CRYPT':
if (!empty($pw_db)) {
$pw_db = preg_replace('/^{CRYPT}/', '', $pw_db);
}
if (empty($pw_db)) {
$pw_db = '$2y$10$' . substr(sha1(random_bytes(8)), 0, 22);
}
return '{CRYPT}' . crypt($pw, $pw_db);
case 'SYSTEM':
return crypt($pw, $pw_db);
case 'CLEAR':
case 'PLAIN':
case 'CLEARTEXT':
if (!empty($pw_db)) {
if ($pw_db == "{{$algorithm}}$pw") {
return $pw_db;
}
return $pw;
}
return '{' . $algorithm . '}' . $pw;
case 'MYSQL_ENCRYPT':
return _pacrypt_mysql_encrypt($pw, $pw_db);
// these are all supported by the above (SHA,
case 'AUTHLIB':
return _pacrypt_authlib($pw, $pw_db);
}
if (preg_match("/^DOVECOT:/", $algorithm)) {
return _pacrypt_dovecot($pw, $pw_db);
}
if (substr($algorithm, 0, 9) === 'PHP_CRYPT') {
return _pacrypt_php_crypt($pw, $pw_db);
}
throw new Exception('unknown/invalid $CONF["encrypt"] setting: ' . $algorithm);
}
public function hashSha1(string $pw, string $pw_db = '', string $algorithm = 'SHA1'): string
{
$hash = hash('sha1', $pw, true);
if (preg_match('/\.HEX$/', $algorithm)) {
$hash = bin2hex($hash);
} else {
$hash = base64_encode($hash);
}
return "{{$algorithm}}{$hash}";
}
public function hashSha1Salted(string $pw, string $pw_db = ''): string
{
if (empty($pw_db)) {
$salt = base64_encode(random_bytes(3)); // 4 char salt.
} else {
$salt = substr(base64_decode(substr($pw_db, 6)), 20);
}
return '{SSHA}' . base64_encode(sha1($pw . $salt, true) . $salt);
}
public function hashSha512(string $pw, string $algorithm = 'SHA512')
{
$prefix = '{SHA512}';
if ($algorithm == 'SHA512.B64' || $algorithm == 'sha512b.b64') {
$prefix = '{SHA512.B64}';
}
return $prefix . base64_encode(hash('sha512', $pw, true));
}
public function hashMd5(string $pw, string $algorithm = 'PLAIN-MD5'): string
{
if ($algorithm == 'PLAIN-MD5') {
return '{PLAIN-MD5}' . md5($pw);
}
return md5($pw);
}
public function hashSha256(string $pw): string
{
return '{SHA256}' . base64_encode(hash('sha256', $pw, true));
}
public function cryptMd5(string $pw, string $pw_db = '', $algorithm = 'MD5-CRYPT')
{
if (!empty($pw_db)) {
$pw_db = preg_replace('/^{MD5.*}/', '', $pw_db);
}
if (empty($pw_db)) {
$pw_db = '$1$' . substr(sha1(random_bytes(8)), 0, 16);
}
return "{{$algorithm}}" . crypt($pw, $pw_db);
}
public function blowfishCrypt(string $pw, string $pw_db = '', string $algorithm = 'BLF-CRYPT'): string
{
if (!empty($pw_db)) {
if ($algorithm == 'BLF-CRYPT') {
$pw_db = preg_replace('/^{BLF-CRYPT}/', '', $pw_db);
}
if ($algorithm == 'BLF-CRYPT.B64') {
$pw_db = base64_decode(preg_replace('/^{BLF-CRYPT.B64}/', '', $pw_db));
}
$hash = crypt($pw, $pw_db);
if ($algorithm == 'BLF-CRYPT.B64') {
$hash = base64_encode($hash);
}
return "{{$algorithm}}{$hash}";
}
$r = password_hash($pw, PASSWORD_BCRYPT);
if (!is_string($r)) {
throw new \RuntimeException("Failed to generate password");
}
if ($algorithm == 'BLF-CRYPT.B64') {
return '{BLF-CRYPT.B64}' . base64_encode($r);
}
return '{BLF-CRYPT}' . $r;
}
public function sha256Crypt(string $pw, string $pw_db = '', string $algorithm = 'SHA256-CRYPT'): string
{
if (!empty($pw_db)) {
$pw_db = preg_replace('/^{SHA256-CRYPT(\.B64)?}/', '', $pw_db);
if ($algorithm == 'SHA256-CRYPT.B64') {
$pw_db = base64_decode($pw_db);
}
}
if (empty($pw_db)) {
$pw_db = '$5$' . substr(sha1(random_bytes(8)), 0, 16);
}
$hash = crypt($pw, $pw_db);
if ($algorithm == 'SHA256-CRYPT.B64') {
return '{SHA256-CRYPT.B64}' . base64_encode($hash);
}
return "{SHA256-CRYPT}" . $hash;
}
public function sha512Crypt(string $pw, string $pw_db = '', $algorithm = 'SHA512-CRYPT'): string
{
if (!empty($pw_db)) {
$pw_db = preg_replace('/^{SHA512-CRYPT(\.B64)?}/', '', $pw_db);
if ($algorithm == 'SHA512-CRYPT.B64') {
$pw_db = base64_decode($pw_db);
}
}
if (empty($pw_db)) {
$pw_db = '$6$' . substr(sha1(random_bytes(8)), 0, 16);
}
$hash = crypt($pw, $pw_db);
if ($algorithm == 'SHA512-CRYPT.B64') {
$hash = base64_encode($hash);
return "{SHA512-CRYPT.B64}{$hash}";
}
return "{SHA512-CRYPT}$hash";
}
public function argon2ICrypt(string $pw, string $pw_db = '', $algorithm = 'ARGON2I'): string
{
if (!empty($pw_db)) {
$pw_db = preg_replace('/^{ARGON2I(\.B64)?}/', '', $pw_db);
$orig_pwdb = $pw_db;
if ($algorithm == 'ARGON2I.B64') {
$pw_db = base64_decode($pw_db);
}
if (password_verify($pw, $pw_db)) {
return "{{$algorithm}}" . $orig_pwdb;
}
$hash = password_hash($pw, PASSWORD_ARGON2I);
if ($algorithm == 'ARGON2I') {
return '{ARGON2I}' . $hash;
}
return '{ARGON2I.B64}' . base64_encode($hash);
;
}
$hash = password_hash($pw, PASSWORD_ARGON2I);
if ($algorithm == 'ARGON2I') {
return '{ARGON2I}' . $hash;
}
return "{ARGON2I.B64}" . base64_encode($hash);
}
public function argon2idCrypt(string $pw, string $pw_db = '', string $algorithm = 'ARGON2ID'): string
{
if (!defined('PASSWORD_ARGON2ID')) {
throw new \Exception("Requires PHP 7.3+");
}
if (!empty($pw_db)) {
$pw_db = preg_replace('/^{ARGON2ID(\.B64)?}/', '', $pw_db);
$orig_pwdb = $pw_db;
if ($algorithm == 'ARGON2ID.B64') {
$pw_db = base64_decode($pw_db);
}
if (password_verify($pw, $pw_db)) {
return "{{$algorithm}}" . $orig_pwdb;
}
$hash = password_hash($pw, PASSWORD_ARGON2ID);
if ($algorithm == 'ARGON2ID') {
return '{ARGON2ID}' . $hash;
}
// if($algorithm == 'ARGON2ID.B64') {
return '{ARGON2ID.B64}' . base64_encode($hash);
}
$hash = password_hash($pw, PASSWORD_ARGON2ID);
if ($algorithm == 'ARGON2ID') {
return '{ARGON2ID}' . $hash;
}
return '{ARGON2ID.B64}' . base64_encode($hash);
}
}

View File

@ -1,15 +1,11 @@
<?php
require_once(__DIR__ . '/../model/PFACrypt.php');
class PaCryptTest extends \PHPUnit\Framework\TestCase
{
public function testMd5Crypt()
{
$hash = _pacrypt_md5crypt('test', '');
$h = new PFACrypt('MD5-CRYPT');
$this->assertNotEmpty($hash);
$this->assertNotEquals('test', $hash);
@ -99,7 +95,6 @@ class PaCryptTest extends \PHPUnit\Framework\TestCase
$config = Config::getInstance();
Config::write('encrypt', 'php_crypt');
$CONF = Config::getInstance()->getAll();
$sha512_crypt = '$6$ijF8bgunALqnEHTo$LHVa6XQBpM5Gt16RMFQuXqrGAS0y0ymaLS8pnkeVUTSx3t2DrGqWwRj6q4ef3V3SWYkb5xkuN9bv7joxNd8kA1';
@ -236,29 +231,20 @@ class PaCryptTest extends \PHPUnit\Framework\TestCase
}
}
public function testSha512CryptB64()
{
$c = new PFACrypt('SHA512CRYPT.B64');
// "SHA512-CRYPT.B64": "{SHA512-CRYPT.B64}JDYkR2JwY3NiZXNMWk9DdERXbiRYdXlhdEZTdy9oa3lyUFE0d24wenpGQTZrSlpTUE9QVWdPcjVRUC40bTRMTjEzdy81aWMvWTdDZllRMWVqSWlhNkd3Q2Z0ZnNjZEFpam9OWjl3OU5tLw==",
$crypt = '{SHA512-CRYPT.B64}JDYkR2JwY3NiZXNMWk9DdERXbiRYdXlhdEZTdy9oa3lyUFE0d24wenpGQTZrSlpTUE9QVWdPcjVRUC40bTRMTjEzdy81aWMvWTdDZllRMWVqSWlhNkd3Q2Z0ZnNjZEFpam9OWjl3OU5tLw==';
$this->assertEquals($crypt, $c->pacrypt('test123', $crypt));
}
public function testWeCopeWithDifferentMethodThanConfigured()
{
$c = new PFACrypt('MD5-CRYPT');
global $CONF;
$CONF['encrypt'] = 'MD5-CRYPT';
$md5Crypt = '{MD5-CRYPT}$1$AIjpWveQ$2s3eEAbZiqkJhMYUIVR240';
$this->assertEquals($md5Crypt, $c->pacrypt('test123', $md5Crypt));
$c = new PFACrypt('SHA1');
$this->assertEquals($md5Crypt, $c->pacrypt('test123', $md5Crypt));
$this->assertEquals($md5Crypt, pacrypt('test123', $md5Crypt));
$CONF['encrypt'] = 'MD5-CRYPT';
$this->assertEquals($md5Crypt, pacrypt('test123', $md5Crypt));
$sha1Crypt = '{SHA1}cojt0Pw//L6ToM8G41aOKFIWh7w=';
$this->assertEquals($sha1Crypt, $c->pacrypt('test123', $sha1Crypt));
$this->assertEquals($sha1Crypt, pacrypt('test123', $sha1Crypt));
}
public function testSomeCourierHashes()
@ -290,20 +276,6 @@ class PaCryptTest extends \PHPUnit\Framework\TestCase
}
}
public function testWeSupportWhatWeSayWeDo()
{
foreach (PFACrypt::DOVECOT_NATIVE as $algorithm) {
if (phpversion() < 7.3 && ($algorithm == 'ARGON2ID' || $algorithm == 'ARGON2ID.B64')) {
continue; // needs PHP7.3+
}
$c = new PFACrypt($algorithm);
$hash1 = $c->pacrypt('test123');
$this->assertEquals($hash1, $c->pacrypt('test123', $hash1));
$this->assertNotEquals($hash1, $c->pacrypt('9999test9999', $hash1));
}
}
public function testObviousMechanisms()
{
global $CONF;