Skip to content

Commit ef4627a

Browse files
committed
More bindings (function missing in php)
- add crypt_gensalt(?string $salt = null, int $count = 0): ?string {} - add crypt_preferred_method(): ?string {} - add crypt_checksalt(string $salt): int {} and bump version to 1.1.0-dev (new functions)
1 parent 5bca398 commit ef4627a

File tree

9 files changed

+239
-5
lines changed

9 files changed

+239
-5
lines changed

package.xml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,37 @@ distributions, using extended crypt library (libxcrypt):
1818
</lead>
1919
<date>2024-09-09</date>
2020
<version>
21-
<release>1.0.1dev</release>
22-
<api>1.0.0</api>
21+
<release>1.1.0dev</release>
22+
<api>1.1.0</api>
2323
</version>
2424
<stability>
2525
<release>stable</release>
2626
<api>stable</api>
2727
</stability>
2828
<license uri="https://www.php.net/license/3_01.txt" filesource="LICENSE">PHP-3.01</license>
2929
<notes>
30-
-
30+
- add crypt_gensalt(?string $salt = null, int $count = 0): ?string {}
31+
- add crypt_preferred_method(): ?string {}
32+
- add crypt_checksalt(string $salt): int {}
3133
</notes>
3234
<contents>
3335
<dir name="/">
3436
<!-- sources -->
3537
<file name="config.m4" role="src"/>
3638
<file name="php_xpass.h" role="src" />
3739
<file name="xpass.c" role="src"/>
40+
<file name="xpass.stub.php" role="src"/>
41+
<file name="xpass_arginfo.h" role="src"/>
3842
<!-- documentation -->
3943
<file name="CREDITS" role="doc"/>
4044
<file name="LICENSE" role="doc"/>
4145
<file name="README.md" role="doc"/>
46+
<!-- tests -->
4247
<dir name ="tests">
48+
<file name="crypt_checksalt.phpt" role="test"/>
49+
<file name="crypt_gensalt.phpt" role="test"/>
50+
<file name="crypt_preferred_method.phpt" role="test"/>
51+
<file name="password_compat.phpt" role="test"/>
4352
<file name="sha512.phpt" role="test"/>
4453
<file name="xpass.phpt" role="test"/>
4554
<file name="yescrypt.phpt" role="test"/>

php_xpass.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
extern zend_module_entry xpass_module_entry;
2323
#define phpext_xpass_ptr &xpass_module_entry
2424

25-
#define PHP_XPASS_VERSION "1.0.1-dev"
25+
#define PHP_XPASS_VERSION "1.1.0-dev"
2626
#define PHP_XPASS_AUTHOR "Remi Collet"
2727
#define PHP_XPASS_LICENSE "PHP-3.01"
2828

tests/crypt_checksalt.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Test crypt_checksalt
3+
--FILE--
4+
<?php
5+
var_dump(crypt_checksalt(crypt_gensalt(XPASS_CRYPT_STD_DES)) === CRYPT_SALT_METHOD_LEGACY);
6+
var_dump(crypt_checksalt(crypt_gensalt()) === CRYPT_SALT_OK);
7+
var_dump(crypt_checksalt("!not_a_valid_hash") === CRYPT_SALT_INVALID);
8+
?>
9+
--EXPECT--
10+
bool(true)
11+
bool(true)
12+
bool(true)

tests/crypt_gensalt.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Test crypt_gensalt
3+
--FILE--
4+
<?php
5+
var_dump(crypt_gensalt(XPASS_CRYPT_STD_DES));
6+
var_dump(crypt_gensalt(XPASS_CRYPT_EXT_DES));
7+
var_dump(crypt_gensalt(XPASS_CRYPT_MD5));
8+
var_dump(crypt_gensalt(XPASS_CRYPT_BLOWFISH));
9+
var_dump(crypt_gensalt(XPASS_CRYPT_SHA256));
10+
var_dump(crypt_gensalt(XPASS_CRYPT_SHA512));
11+
var_dump(crypt_gensalt(XPASS_CRYPT_SCRYPT));
12+
var_dump(crypt_gensalt(XPASS_CRYPT_GOST_YESCRYPT));
13+
var_dump(crypt_gensalt(XPASS_CRYPT_YESCRYPT));
14+
15+
?>
16+
--EXPECTF--
17+
string(2) "%s"
18+
string(9) "_%s"
19+
string(11) "$1$%s"
20+
string(29) "$2y$%s"
21+
string(19) "$5$%s"
22+
string(19) "$6$%s"
23+
string(36) "$7$%s"
24+
string(30) "$gy$%s"
25+
string(29) "$y$j%s"

tests/crypt_preferred_method.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--TEST--
2+
Test crypt_preferred_method
3+
--FILE--
4+
<?php
5+
var_dump(crypt_preferred_method());
6+
?>
7+
--EXPECTF--
8+
string(%d) "$%s$"
9+

tests/password_compat.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Test crypt compatibility with password_hash
3+
--FILE--
4+
<?php
5+
$secret = 'mysecret';
6+
7+
/* generate with password_hash, check with both */
8+
$h = password_hash($secret, PASSWORD_BCRYPT);
9+
var_dump($h, password_verify($secret, $h), $h===crypt($secret, $h));
10+
11+
/* generate with crypt, check with both */
12+
$h = crypt($secret, crypt_gensalt(XPASS_CRYPT_BLOWFISH));
13+
var_dump($h, password_verify($secret, $h), $h===crypt($secret, $h));
14+
?>
15+
--EXPECTF--
16+
string(60) "$2y$%s$%s"
17+
bool(true)
18+
bool(true)
19+
string(60) "$2y$%s$%s"
20+
bool(true)
21+
bool(true)
22+

xpass.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "php_xpass.h"
2727
#include <crypt.h>
2828

29+
#include "xpass_arginfo.h"
30+
2931
/* {{{ PHP_RINIT_FUNCTION */
3032
PHP_RINIT_FUNCTION(xpass)
3133
{
@@ -149,8 +151,60 @@ static const php_password_algo xpass_algo_yescrypt = {
149151
NULL,
150152
};
151153

154+
/* {{{ Generates a salt for algo */
155+
PHP_FUNCTION(crypt_gensalt)
156+
{
157+
char salt[CRYPT_GENSALT_OUTPUT_SIZE + 1];
158+
char *prefix = NULL;
159+
size_t prefix_len = 0;
160+
zend_long count = 0;
161+
162+
ZEND_PARSE_PARAMETERS_START(0, 2)
163+
Z_PARAM_OPTIONAL
164+
Z_PARAM_STRING(prefix, prefix_len)
165+
Z_PARAM_LONG(count)
166+
ZEND_PARSE_PARAMETERS_END();
167+
168+
if (crypt_gensalt_rn(prefix, (unsigned long)count, NULL, 0, salt, CRYPT_GENSALT_OUTPUT_SIZE)) {
169+
RETURN_STRING(salt);
170+
}
171+
RETURN_NULL();
172+
}
173+
/* }}} */
174+
175+
/* {{{ Get preferred hasing method prefix */
176+
PHP_FUNCTION(crypt_preferred_method)
177+
{
178+
const char *prefix;
179+
180+
ZEND_PARSE_PARAMETERS_NONE();
181+
182+
prefix = crypt_preferred_method();
183+
if (prefix) {
184+
RETURN_STRING(prefix);
185+
}
186+
RETURN_NULL();
187+
}
188+
/* }}} */
189+
190+
/* {{{ Determine whether the user's passphrase should be re-hashed using the currently preferred hashing method */
191+
PHP_FUNCTION(crypt_checksalt)
192+
{
193+
char *prefix;
194+
size_t prefix_len;
195+
196+
ZEND_PARSE_PARAMETERS_START(1, 1)
197+
Z_PARAM_STRING(prefix, prefix_len)
198+
ZEND_PARSE_PARAMETERS_END();
199+
200+
RETURN_LONG(crypt_checksalt(prefix));
201+
}
202+
/* }}} */
203+
152204
PHP_MINIT_FUNCTION(xpass) /* {{{ */ {
153205

206+
register_xpass_symbols(module_number);
207+
154208
#ifdef HAVE_CRYPT_SHA512
155209
if (FAILURE == php_password_algo_register("6", &xpass_algo_sha512)) {
156210
return FAILURE;
@@ -172,7 +226,7 @@ PHP_MINIT_FUNCTION(xpass) /* {{{ */ {
172226
zend_module_entry xpass_module_entry = {
173227
STANDARD_MODULE_HEADER,
174228
"xpass", /* Extension name */
175-
NULL, /* zend_function_entry */
229+
ext_functions, /* zend_function_entry */
176230
PHP_MINIT(xpass), /* PHP_MINIT - Module initialization */
177231
NULL, /* PHP_MSHUTDOWN - Module shutdown */
178232
PHP_RINIT(xpass), /* PHP_RINIT - Request initialization */

xpass.stub.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/** @generate-class-entries */
4+
5+
/* use XPASS prefix to avoid conflicts with standard constants */
6+
7+
/** @var string */
8+
const XPASS_CRYPT_STD_DES = '';
9+
/** @var string */
10+
const XPASS_CRYPT_EXT_DES = '_';
11+
/** @var string */
12+
const XPASS_CRYPT_MD5 = '$1$';
13+
/** @var string */
14+
const XPASS_CRYPT_BLOWFISH = '$2y$';
15+
/** @var string */
16+
const XPASS_CRYPT_SHA256 = '$5$';
17+
/** @var string */
18+
const XPASS_CRYPT_SHA512 = '$6$';
19+
/** @var string */
20+
const XPASS_CRYPT_SCRYPT = '$7$';
21+
/** @var string */
22+
const XPASS_CRYPT_GOST_YESCRYPT = '$gy$';
23+
/** @var string */
24+
const XPASS_CRYPT_YESCRYPT = '$y$';
25+
26+
/**
27+
* @var int
28+
* @cvalue CRYPT_SALT_OK
29+
*/
30+
const CRYPT_SALT_OK = UNKNOWN;
31+
/**
32+
* @var int
33+
* @cvalue CRYPT_SALT_INVALID
34+
*/
35+
const CRYPT_SALT_INVALID = UNKNOWN;
36+
/**
37+
* @var int
38+
* @cvalue CRYPT_SALT_METHOD_DISABLED
39+
*/
40+
const CRYPT_SALT_METHOD_DISABLED = UNKNOWN;
41+
/**
42+
* @var int
43+
* @cvalue CRYPT_SALT_METHOD_LEGACY
44+
*/
45+
const CRYPT_SALT_METHOD_LEGACY = UNKNOWN;
46+
/**
47+
* @var int
48+
* @cvalue CRYPT_SALT_TOO_CHEAP
49+
*/
50+
const CRYPT_SALT_TOO_CHEAP = UNKNOWN;
51+
52+
53+
function crypt_gensalt(?string $salt = null, int $count = 0): ?string {}
54+
55+
function crypt_preferred_method(): ?string {}
56+
57+
function crypt_checksalt(string $salt): int {}
58+

xpass_arginfo.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* This is a generated file, edit the .stub.php file instead.
2+
* Stub hash: 6a2b53f488db292839749c125a6d81f89316e9c9 */
3+
4+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crypt_gensalt, 0, 0, IS_STRING, 1)
5+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, salt, IS_STRING, 1, "null")
6+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, count, IS_LONG, 0, "0")
7+
ZEND_END_ARG_INFO()
8+
9+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crypt_preferred_method, 0, 0, IS_STRING, 1)
10+
ZEND_END_ARG_INFO()
11+
12+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crypt_checksalt, 0, 1, IS_LONG, 0)
13+
ZEND_ARG_TYPE_INFO(0, salt, IS_STRING, 0)
14+
ZEND_END_ARG_INFO()
15+
16+
17+
ZEND_FUNCTION(crypt_gensalt);
18+
ZEND_FUNCTION(crypt_preferred_method);
19+
ZEND_FUNCTION(crypt_checksalt);
20+
21+
22+
static const zend_function_entry ext_functions[] = {
23+
ZEND_FE(crypt_gensalt, arginfo_crypt_gensalt)
24+
ZEND_FE(crypt_preferred_method, arginfo_crypt_preferred_method)
25+
ZEND_FE(crypt_checksalt, arginfo_crypt_checksalt)
26+
ZEND_FE_END
27+
};
28+
29+
static void register_xpass_symbols(int module_number)
30+
{
31+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_STD_DES", "", CONST_PERSISTENT);
32+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_EXT_DES", "_", CONST_PERSISTENT);
33+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_MD5", "$1$", CONST_PERSISTENT);
34+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_BLOWFISH", "$2y$", CONST_PERSISTENT);
35+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_SHA256", "$5$", CONST_PERSISTENT);
36+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_SHA512", "$6$", CONST_PERSISTENT);
37+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_SCRYPT", "$7$", CONST_PERSISTENT);
38+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_GOST_YESCRYPT", "$gy$", CONST_PERSISTENT);
39+
REGISTER_STRING_CONSTANT("XPASS_CRYPT_YESCRYPT", "$y$", CONST_PERSISTENT);
40+
REGISTER_LONG_CONSTANT("CRYPT_SALT_OK", CRYPT_SALT_OK, CONST_PERSISTENT);
41+
REGISTER_LONG_CONSTANT("CRYPT_SALT_INVALID", CRYPT_SALT_INVALID, CONST_PERSISTENT);
42+
REGISTER_LONG_CONSTANT("CRYPT_SALT_METHOD_DISABLED", CRYPT_SALT_METHOD_DISABLED, CONST_PERSISTENT);
43+
REGISTER_LONG_CONSTANT("CRYPT_SALT_METHOD_LEGACY", CRYPT_SALT_METHOD_LEGACY, CONST_PERSISTENT);
44+
REGISTER_LONG_CONSTANT("CRYPT_SALT_TOO_CHEAP", CRYPT_SALT_TOO_CHEAP, CONST_PERSISTENT);
45+
}

0 commit comments

Comments
 (0)