Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
503a5a24
Commit
503a5a24
authored
Apr 15, 2020
by
antirez
Browse files
Don't allow empty spaces in ACL usernames.
Fixes issue #6418.
parent
3519a5a0
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/acl.c
View file @
503a5a24
...
@@ -170,6 +170,18 @@ sds ACLHashPassword(unsigned char *cleartext, size_t len) {
...
@@ -170,6 +170,18 @@ sds ACLHashPassword(unsigned char *cleartext, size_t len) {
* Low level ACL API
* Low level ACL API
* ==========================================================================*/
* ==========================================================================*/
/* Return 1 if the specified string contains spaces or null characters.
* We do this for usernames and key patterns for simpler rewriting of
* ACL rules, presentation on ACL list, and to avoid subtle security bugs
* that may arise from parsing the rules in presence of escapes.
* The function returns 0 if the string has no spaces. */
int
ACLStringHasSpaces
(
const
char
*
s
,
size_t
len
)
{
for
(
size_t
i
=
0
;
i
<
len
;
i
++
)
{
if
(
isspace
(
s
[
i
])
||
s
[
i
]
==
0
)
return
1
;
}
return
0
;
}
/* Given the category name the command returns the corresponding flag, or
/* Given the category name the command returns the corresponding flag, or
* zero if there is no match. */
* zero if there is no match. */
uint64_t
ACLGetCommandCategoryFlagByName
(
const
char
*
name
)
{
uint64_t
ACLGetCommandCategoryFlagByName
(
const
char
*
name
)
{
...
@@ -791,14 +803,9 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
...
@@ -791,14 +803,9 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
errno
=
EEXIST
;
errno
=
EEXIST
;
return
C_ERR
;
return
C_ERR
;
}
}
/* Validate the pattern: no spaces nor null characters
if
(
ACLStringHasSpaces
(
op
+
1
,
oplen
-
1
))
{
* are allowed, for simpler rewriting of the ACLs without
errno
=
EINVAL
;
* using quoting. */
return
C_ERR
;
for
(
int
i
=
1
;
i
<
oplen
;
i
++
)
{
if
(
isspace
(
op
[
i
])
||
op
[
i
]
==
0
)
{
errno
=
EINVAL
;
return
C_ERR
;
}
}
}
sds
newpat
=
sdsnewlen
(
op
+
1
,
oplen
-
1
);
sds
newpat
=
sdsnewlen
(
op
+
1
,
oplen
-
1
);
listNode
*
ln
=
listSearchKey
(
u
->
patterns
,
newpat
);
listNode
*
ln
=
listSearchKey
(
u
->
patterns
,
newpat
);
...
@@ -1175,6 +1182,12 @@ int ACLLoadConfiguredUsers(void) {
...
@@ -1175,6 +1182,12 @@ int ACLLoadConfiguredUsers(void) {
while
((
ln
=
listNext
(
&
li
))
!=
NULL
)
{
while
((
ln
=
listNext
(
&
li
))
!=
NULL
)
{
sds
*
aclrules
=
listNodeValue
(
ln
);
sds
*
aclrules
=
listNodeValue
(
ln
);
sds
username
=
aclrules
[
0
];
sds
username
=
aclrules
[
0
];
if
(
ACLStringHasSpaces
(
aclrules
[
0
],
sdslen
(
aclrules
[
0
])))
{
serverLog
(
LL_WARNING
,
"Spaces not allowed in ACL usernames"
);
return
C_ERR
;
}
user
*
u
=
ACLCreateUser
(
username
,
sdslen
(
username
));
user
*
u
=
ACLCreateUser
(
username
,
sdslen
(
username
));
if
(
!
u
)
{
if
(
!
u
)
{
u
=
ACLGetUserByName
(
username
,
sdslen
(
username
));
u
=
ACLGetUserByName
(
username
,
sdslen
(
username
));
...
@@ -1300,6 +1313,14 @@ sds ACLLoadFromFile(const char *filename) {
...
@@ -1300,6 +1313,14 @@ sds ACLLoadFromFile(const char *filename) {
continue
;
continue
;
}
}
/* Spaces are not allowed in usernames. */
if
(
ACLStringHasSpaces
(
argv
[
1
],
sdslen
(
argv
[
1
])))
{
errors
=
sdscatprintf
(
errors
,
"'%s:%d: username '%s' contains invalid characters. "
,
server
.
acl_filename
,
linenum
,
argv
[
1
]);
continue
;
}
/* Try to process the line using the fake user to validate iif
/* Try to process the line using the fake user to validate iif
* the rules are able to apply cleanly. */
* the rules are able to apply cleanly. */
ACLSetUser
(
fakeuser
,
"reset"
,
-
1
);
ACLSetUser
(
fakeuser
,
"reset"
,
-
1
);
...
@@ -1609,6 +1630,13 @@ void aclCommand(client *c) {
...
@@ -1609,6 +1630,13 @@ void aclCommand(client *c) {
char
*
sub
=
c
->
argv
[
1
]
->
ptr
;
char
*
sub
=
c
->
argv
[
1
]
->
ptr
;
if
(
!
strcasecmp
(
sub
,
"setuser"
)
&&
c
->
argc
>=
3
)
{
if
(
!
strcasecmp
(
sub
,
"setuser"
)
&&
c
->
argc
>=
3
)
{
sds
username
=
c
->
argv
[
2
]
->
ptr
;
sds
username
=
c
->
argv
[
2
]
->
ptr
;
/* Check username validity. */
if
(
ACLStringHasSpaces
(
username
,
sdslen
(
username
)))
{
addReplyErrorFormat
(
c
,
"Usernames can't contain spaces or null characters"
);
return
;
}
/* Create a temporary user to validate and stage all changes against
/* Create a temporary user to validate and stage all changes against
* before applying to an existing user or creating a new user. If all
* before applying to an existing user or creating a new user. If all
* arguments are valid the user parameters will all be applied together.
* arguments are valid the user parameters will all be applied together.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment