提交 09041b93 编写于 作者: A antirez

ACLs: change hashed passwords opcode to also remove them.

Related to PR #6405
上级 ea7c3fe7
...@@ -95,7 +95,7 @@ void ACLResetSubcommands(user *u); ...@@ -95,7 +95,7 @@ void ACLResetSubcommands(user *u);
void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub); void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub);
/* The length of the string representation of a hashed password. */ /* The length of the string representation of a hashed password. */
#define HASH_PASSWORD_LEN SHA256_BLOCK_SIZE*2 #define HASH_PASSWORD_LEN SHA256_BLOCK_SIZE*2
/* ============================================================================= /* =============================================================================
* Helper functions for the rest of the ACL implementation * Helper functions for the rest of the ACL implementation
...@@ -652,11 +652,14 @@ void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub) { ...@@ -652,11 +652,14 @@ void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub) {
* ><password> Add this password to the list of valid password for the user. * ><password> Add this password to the list of valid password for the user.
* For example >mypass will add "mypass" to the list. * For example >mypass will add "mypass" to the list.
* This directive clears the "nopass" flag (see later). * This directive clears the "nopass" flag (see later).
* #<password hash> Add this password hash to the list of valid hashes for * #<hash> Add this password hash to the list of valid hashes for
* the user. This is useful if you have previously computed * the user. This is useful if you have previously computed
* the hash, and don't want to store it in plaintext. * the hash, and don't want to store it in plaintext.
* This directive clears the "nopass" flag (see later). * This directive clears the "nopass" flag (see later).
* <<password> Remove this password from the list of valid passwords. * <<password> Remove this password from the list of valid passwords.
* !<hash> Remove this hashed password from the list of valid passwords.
* This is useful when you want to remove a password just by
* hash without knowing its plaintext version at all.
* nopass All the set passwords of the user are removed, and the user * nopass All the set passwords of the user are removed, and the user
* is flagged as requiring no password: it means that every * is flagged as requiring no password: it means that every
* password will work against this user. If this directive is * password will work against this user. If this directive is
...@@ -735,12 +738,12 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) { ...@@ -735,12 +738,12 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
} else { } else {
if (oplen != HASH_PASSWORD_LEN + 1) { if (oplen != HASH_PASSWORD_LEN + 1) {
errno = EBADMSG; errno = EBADMSG;
return C_ERR; return C_ERR;
} }
/* Password hashes can only be characters that represent /* Password hashes can only be characters that represent
* hexadecimal values, which are numbers and lowercase * hexadecimal values, which are numbers and lowercase
* characters 'a' through 'f'. * characters 'a' through 'f'.
*/ */
for(int i = 1; i < HASH_PASSWORD_LEN + 1; i++) { for(int i = 1; i < HASH_PASSWORD_LEN + 1; i++) {
char c = op[i]; char c = op[i];
...@@ -759,8 +762,17 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) { ...@@ -759,8 +762,17 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
else else
sdsfree(newpass); sdsfree(newpass);
u->flags &= ~USER_FLAG_NOPASS; u->flags &= ~USER_FLAG_NOPASS;
} else if (op[0] == '<') { } else if (op[0] == '<' || op[0] == '!') {
sds delpass = ACLHashPassword((unsigned char*)op+1,oplen-1); sds delpass;
if (op[0] == '<') {
delpass = ACLHashPassword((unsigned char*)op+1,oplen-1);
} else {
if (oplen != HASH_PASSWORD_LEN + 1) {
errno = EBADMSG;
return C_ERR;
}
delpass = sdsnewlen(op+1,oplen-1);
}
listNode *ln = listSearchKey(u->passwords,delpass); listNode *ln = listSearchKey(u->passwords,delpass);
sdsfree(delpass); sdsfree(delpass);
if (ln) { if (ln) {
......
...@@ -55,6 +55,12 @@ start_server {tags {"acl"}} { ...@@ -55,6 +55,12 @@ start_server {tags {"acl"}} {
assert_no_match {*passwd4*} $passstr assert_no_match {*passwd4*} $passstr
} }
test {Test hashed passwords removal} {
r ACL setuser newuser !34344e4d60c2b6d639b7bd22e18f2b0b91bc34bf0ac5f9952744435093cfb4e6
set passstr [dict get [r ACL getuser newuser] passwords]
assert_no_match {*34344e4d60c2b6d639b7bd22e18f2b0b91bc34bf0ac5f9952744435093cfb4e6*} $passstr
}
test {By default users are not able to access any command} { test {By default users are not able to access any command} {
catch {r SET foo bar} e catch {r SET foo bar} e
set e set e
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册