parent
3519a5a026
commit
503a5a24fb
40
src/acl.c
40
src/acl.c
@ -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,15 +803,10 @@ 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
|
|
||||||
* using quoting. */
|
|
||||||
for (int i = 1; i < oplen; i++) {
|
|
||||||
if (isspace(op[i]) || op[i] == 0) {
|
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return C_ERR;
|
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);
|
||||||
/* Avoid re-adding the same pattern multiple times. */
|
/* Avoid re-adding the same pattern multiple times. */
|
||||||
@ -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) {
|
|||||||
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) {
|
|||||||
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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user