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
b43d70df
Commit
b43d70df
authored
Dec 21, 2018
by
antirez
Browse files
ACL: refactoring of the original authentication code.
parent
4d80b0e9
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
b43d70df
...
...
@@ -164,7 +164,7 @@ endif
REDIS_SERVER_NAME
=
redis-server
REDIS_SENTINEL_NAME
=
redis-sentinel
REDIS_SERVER_OBJ
=
adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o
REDIS_SERVER_OBJ
=
adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o
acl.o
REDIS_CLI_NAME
=
redis-cli
REDIS_CLI_OBJ
=
anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o
REDIS_BENCHMARK_NAME
=
redis-benchmark
...
...
src/acl.c
0 → 100644
View file @
b43d70df
/*
* Copyright (c) 2018, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "server.h"
/* Return zero if strings are the same, non-zero if they are not.
* The comparison is performed in a way that prevents an attacker to obtain
* information about the nature of the strings just monitoring the execution
* time of the function.
*
* Note that limiting the comparison length to strings up to 512 bytes we
* can avoid leaking any information about the password length and any
* possible branch misprediction related leak.
*/
int
time_independent_strcmp
(
char
*
a
,
char
*
b
)
{
char
bufa
[
CONFIG_AUTHPASS_MAX_LEN
],
bufb
[
CONFIG_AUTHPASS_MAX_LEN
];
/* The above two strlen perform len(a) + len(b) operations where either
* a or b are fixed (our password) length, and the difference is only
* relative to the length of the user provided string, so no information
* leak is possible in the following two lines of code. */
unsigned
int
alen
=
strlen
(
a
);
unsigned
int
blen
=
strlen
(
b
);
unsigned
int
j
;
int
diff
=
0
;
/* We can't compare strings longer than our static buffers.
* Note that this will never pass the first test in practical circumstances
* so there is no info leak. */
if
(
alen
>
sizeof
(
bufa
)
||
blen
>
sizeof
(
bufb
))
return
1
;
memset
(
bufa
,
0
,
sizeof
(
bufa
));
/* Constant time. */
memset
(
bufb
,
0
,
sizeof
(
bufb
));
/* Constant time. */
/* Again the time of the following two copies is proportional to
* len(a) + len(b) so no info is leaked. */
memcpy
(
bufa
,
a
,
alen
);
memcpy
(
bufb
,
b
,
blen
);
/* Always compare all the chars in the two buffers without
* conditional expressions. */
for
(
j
=
0
;
j
<
sizeof
(
bufa
);
j
++
)
{
diff
|=
(
bufa
[
j
]
^
bufb
[
j
]);
}
/* Length must be equal as well. */
diff
|=
alen
^
blen
;
return
diff
;
/* If zero strings are the same. */
}
/* Check the username and password pair and return C_OK if they are valid,
* otherwise C_ERR is returned and errno is set to:
*
* EINVAL: if the username-password do not match.
* ENONENT: if the specified user does not exist at all.
*/
int
ACLCheckUserCredentials
(
robj
*
username
,
robj
*
password
)
{
/* For now only the "default" user is allowed. When the RCP1 ACLs
* will be implemented multiple usernames will be supproted. */
if
(
username
!=
NULL
&&
strcmp
(
username
->
ptr
,
"default"
))
{
errno
=
ENOENT
;
return
C_ERR
;
}
/* For now we just compare the password with the system wide one. */
if
(
!
time_independent_strcmp
(
password
->
ptr
,
server
.
requirepass
))
{
return
C_OK
;
}
else
{
errno
=
EINVAL
;
return
C_ERR
;
}
}
src/server.c
View file @
b43d70df
...
...
@@ -2864,52 +2864,10 @@ int writeCommandsDeniedByDiskError(void) {
}
}
/* Return zero if strings are the same, non-zero if they are not.
* The comparison is performed in a way that prevents an attacker to obtain
* information about the nature of the strings just monitoring the execution
* time of the function.
*
* Note that limiting the comparison length to strings up to 512 bytes we
* can avoid leaking any information about the password length and any
* possible branch misprediction related leak.
*/
int
time_independent_strcmp
(
char
*
a
,
char
*
b
)
{
char
bufa
[
CONFIG_AUTHPASS_MAX_LEN
],
bufb
[
CONFIG_AUTHPASS_MAX_LEN
];
/* The above two strlen perform len(a) + len(b) operations where either
* a or b are fixed (our password) length, and the difference is only
* relative to the length of the user provided string, so no information
* leak is possible in the following two lines of code. */
unsigned
int
alen
=
strlen
(
a
);
unsigned
int
blen
=
strlen
(
b
);
unsigned
int
j
;
int
diff
=
0
;
/* We can't compare strings longer than our static buffers.
* Note that this will never pass the first test in practical circumstances
* so there is no info leak. */
if
(
alen
>
sizeof
(
bufa
)
||
blen
>
sizeof
(
bufb
))
return
1
;
memset
(
bufa
,
0
,
sizeof
(
bufa
));
/* Constant time. */
memset
(
bufb
,
0
,
sizeof
(
bufb
));
/* Constant time. */
/* Again the time of the following two copies is proportional to
* len(a) + len(b) so no info is leaked. */
memcpy
(
bufa
,
a
,
alen
);
memcpy
(
bufb
,
b
,
blen
);
/* Always compare all the chars in the two buffers without
* conditional expressions. */
for
(
j
=
0
;
j
<
sizeof
(
bufa
);
j
++
)
{
diff
|=
(
bufa
[
j
]
^
bufb
[
j
]);
}
/* Length must be equal as well. */
diff
|=
alen
^
blen
;
return
diff
;
/* If zero strings are the same. */
}
void
authCommand
(
client
*
c
)
{
if
(
!
server
.
requirepass
)
{
addReplyError
(
c
,
"Client sent AUTH, but no password is set"
);
}
else
if
(
!
time_independent_strcmp
(
c
->
argv
[
1
]
->
ptr
,
server
.
requirepass
))
{
}
else
if
(
ACLCheckUserCredentials
(
NULL
,
c
->
argv
[
1
]
->
ptr
))
{
c
->
authenticated
=
1
;
addReply
(
c
,
shared
.
ok
);
}
else
{
...
...
src/server.h
View file @
b43d70df
...
...
@@ -1648,6 +1648,9 @@ void closeChildInfoPipe(void);
void
sendChildInfo
(
int
process_type
);
void
receiveChildInfo
(
void
);
/* acl.c -- Authentication related prototypes. */
int
ACLCheckUserCredentials
(
robj
*
username
,
robj
*
password
);
/* Sorted sets data type */
/* Input flags. */
...
...
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