summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2019-09-30 18:22:55 +0200
committerantirez <antirez@gmail.com>2019-09-30 18:28:45 +0200
commit09041b9359dfcdc84cf5570ded44160fbe7e2bfb (patch)
treeed5908e67b0b61a58c0b614cdc866501dbdfcfc0
parentea7c3fe7fd6d269e1e09443db3e2148cb445febb (diff)
downloadredis-hashed-pass-opcode.tar.gz
ACLs: change hashed passwords opcode to also remove them.hashed-pass-opcode
Related to PR #6405
-rw-r--r--src/acl.c32
-rw-r--r--tests/unit/acl.tcl6
2 files changed, 28 insertions, 10 deletions
diff --git a/src/acl.c b/src/acl.c
index 9c5196f48..4c43add14 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -95,7 +95,7 @@ void ACLResetSubcommands(user *u);
void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub);
/* 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
@@ -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.
* For example >mypass will add "mypass" to the list.
* This directive clears the "nopass" flag (see later).
- * #<password hash> Add this password hash to the list of valid hashes for
- * the user. This is useful if you have previously computed
- * the hash, and don't want to store it in plaintext.
- * This directive clears the "nopass" flag (see later).
+ * #<hash> Add this password hash to the list of valid hashes for
+ * the user. This is useful if you have previously computed
+ * the hash, and don't want to store it in plaintext.
+ * This directive clears the "nopass" flag (see later).
* <<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
* is flagged as requiring no password: it means that every
* password will work against this user. If this directive is
@@ -735,12 +738,12 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
} else {
if (oplen != HASH_PASSWORD_LEN + 1) {
errno = EBADMSG;
- return C_ERR;
+ return C_ERR;
}
/* Password hashes can only be characters that represent
- * hexadecimal values, which are numbers and lowercase
- * characters 'a' through 'f'.
+ * hexadecimal values, which are numbers and lowercase
+ * characters 'a' through 'f'.
*/
for(int i = 1; i < HASH_PASSWORD_LEN + 1; i++) {
char c = op[i];
@@ -759,8 +762,17 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
else
sdsfree(newpass);
u->flags &= ~USER_FLAG_NOPASS;
- } else if (op[0] == '<') {
- sds delpass = ACLHashPassword((unsigned char*)op+1,oplen-1);
+ } else if (op[0] == '<' || op[0] == '!') {
+ 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);
sdsfree(delpass);
if (ln) {
diff --git a/tests/unit/acl.tcl b/tests/unit/acl.tcl
index d3b721205..2205d2d86 100644
--- a/tests/unit/acl.tcl
+++ b/tests/unit/acl.tcl
@@ -55,6 +55,12 @@ start_server {tags {"acl"}} {
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} {
catch {r SET foo bar} e
set e