[mod_auth] implement and use safe_memclear, using memset_s or explicit_bzero if available
From: Loganaden Velvindron <logan@elandsys.com> git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3045 152afb58-edef-0310-8abb-c4023f1b3aa9svn/tags/lighttpd-1.4.38
parent
37bdb250a4
commit
d7be04beb5
1
NEWS
1
NEWS
|
@ -8,6 +8,7 @@ NEWS
|
|||
* [core] allocate at least 4k buffer for incoming data
|
||||
* [core] fix search for header end if split across chunks (fixes #2670)
|
||||
* [core] check configparserAlloc() result with force_assert
|
||||
* [mod_auth] implement and use safe_memclear, using memset_s or explicit_bzero if available (thx loganaden)
|
||||
|
||||
- 1.4.37 - 2015-08-30
|
||||
* [mod_proxy] remove debug log line from error log (fixes #2659)
|
||||
|
|
79
SConstruct
79
SConstruct
|
@ -28,6 +28,52 @@ def checkTypes(autoconf, types):
|
|||
if autoconf.CheckType(type, '#include <sys/types.h>'):
|
||||
autoconf.env.Append(CPPFLAGS = [ '-DHAVE_' + p.sub('_', type.upper()) ])
|
||||
|
||||
def checkGmtOffInStructTm(context):
|
||||
source = """
|
||||
#include <time.h>
|
||||
int main() {
|
||||
struct tm a;
|
||||
a.tm_gmtoff = 0;
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
context.Message('Checking for tm_gmtoff in struct tm...')
|
||||
result = context.TryLink(source, '.c')
|
||||
context.Result(result)
|
||||
|
||||
return result
|
||||
|
||||
def checkIPv6(context):
|
||||
source = """
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int main() {
|
||||
struct sockaddr_in6 s; struct in6_addr t=in6addr_any; int i=AF_INET6; s; t.s6_addr[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
context.Message('Checking for IPv6 support...')
|
||||
result = context.TryLink(source, '.c')
|
||||
context.Result(result)
|
||||
|
||||
return result
|
||||
|
||||
def checkWeakSymbols(context):
|
||||
source = """
|
||||
__attribute__((weak)) void __dummy(void *x) { }
|
||||
int main() {
|
||||
void *x;
|
||||
__dummy(x);
|
||||
}
|
||||
"""
|
||||
context.Message('Checking for weak symbol support...')
|
||||
result = context.TryLink(source, '.c')
|
||||
context.Result(result)
|
||||
|
||||
return result
|
||||
|
||||
def checkProgram(env, withname, progname):
|
||||
withname = 'with_' + withname
|
||||
binpath = None
|
||||
|
@ -54,22 +100,6 @@ def checkProgram(env, withname, progname):
|
|||
|
||||
return binpath
|
||||
|
||||
def checkStructMember(context):
|
||||
struct_member = """
|
||||
#include <time.h>
|
||||
int main() {
|
||||
struct tm a;
|
||||
a.tm_gmtoff = 0;
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
context.Message('Checking for tm_gmtoff in struct tm...')
|
||||
result = context.TryLink(struct_member, '.c')
|
||||
context.Result(result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
VariantDir('sconsbuild/build', 'src', duplicate = 0)
|
||||
VariantDir('sconsbuild/tests', 'tests', duplicate = 0)
|
||||
|
||||
|
@ -114,7 +144,11 @@ if env['CC'] == 'gcc':
|
|||
|
||||
# cache configure checks
|
||||
if 1:
|
||||
autoconf = Configure(env, custom_tests = {'CheckStructMember': checkStructMember })
|
||||
autoconf = Configure(env, custom_tests = {
|
||||
'CheckGmtOffInStructTm': checkGmtOffInStructTm,
|
||||
'CheckIPv6': checkIPv6,
|
||||
'CheckWeakSymbols': checkWeakSymbols,
|
||||
})
|
||||
|
||||
if 'CFLAGS' in os.environ:
|
||||
autoconf.env.Append(CCFLAGS = os.environ['CFLAGS'])
|
||||
|
@ -175,7 +209,8 @@ if 1:
|
|||
strdup strerror strstr strtol sendfile getopt socket \
|
||||
gethostbyname poll epoll_ctl getrlimit chroot \
|
||||
getuid select signal pathconf madvise prctl\
|
||||
writev sigaction sendfile64 send_file kqueue port_create localtime_r posix_fadvise issetugid inet_pton'))
|
||||
writev sigaction sendfile64 send_file kqueue port_create localtime_r posix_fadvise issetugid inet_pton \
|
||||
memset_s explicit_bzero'))
|
||||
|
||||
checkTypes(autoconf, Split('pid_t size_t off_t'))
|
||||
|
||||
|
@ -242,9 +277,15 @@ if 1:
|
|||
if autoconf.CheckType('struct sockaddr_storage', '#include <sys/socket.h>\n'):
|
||||
autoconf.env.Append(CPPFLAGS = [ '-DHAVE_STRUCT_SOCKADDR_STORAGE' ])
|
||||
|
||||
if autoconf.CheckStructMember():
|
||||
if autoconf.CheckGmtOffInStructTm():
|
||||
autoconf.env.Append(CPPFLAGS = [ '-DHAVE_STRUCT_TM_GMTOFF' ])
|
||||
|
||||
if autoconf.CheckIPv6():
|
||||
autoconf.env.Append(CPPFLAGS = [ '-DHAVE_IPV6' ])
|
||||
|
||||
if autoconf.CheckWeakSymbols():
|
||||
autoconf.env.Append(CPPFLAGS = [ '-DHAVE_WEAK_SYMBOLS' ])
|
||||
|
||||
env = autoconf.Finish()
|
||||
|
||||
def TryLua(env, name):
|
||||
|
|
13
configure.ac
13
configure.ac
|
@ -586,7 +586,18 @@ AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \
|
|||
strdup strerror strstr strtol sendfile getopt socket lstat \
|
||||
gethostbyname poll epoll_ctl getrlimit chroot \
|
||||
getuid select signal pathconf madvise posix_fadvise posix_madvise \
|
||||
writev sigaction sendfile64 send_file kqueue port_create localtime_r gmtime_r])
|
||||
writev sigaction sendfile64 send_file kqueue port_create localtime_r gmtime_r \
|
||||
memset_s explicit_bzero])
|
||||
|
||||
AC_MSG_CHECKING(if weak symbols are supported)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
__attribute__((weak)) void __dummy(void *x) { }
|
||||
void f(void *x) { __dummy(x); }
|
||||
]])],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_WEAK_SYMBOLS], [1], [weak symbols are supported])
|
||||
],[AC_MSG_RESULT(no)])
|
||||
|
||||
AC_MSG_CHECKING(for Large File System support)
|
||||
AC_ARG_ENABLE(lfs,
|
||||
|
|
|
@ -105,6 +105,7 @@ else()
|
|||
check_library_exists(crypt crypt "" HAVE_LIBCRYPT)
|
||||
endif()
|
||||
check_function_exists(crypt_r HAVE_CRYPT_R)
|
||||
check_function_exists(crypt HAVE_CRYPT)
|
||||
|
||||
check_include_files(sys/inotify.h HAVE_SYS_INOTIFY_H)
|
||||
if(HAVE_SYS_INOTIFY_H)
|
||||
|
@ -119,7 +120,6 @@ check_type_size(long SIZEOF_LONG)
|
|||
check_type_size(off_t SIZEOF_OFF_T)
|
||||
|
||||
check_function_exists(chroot HAVE_CHROOT)
|
||||
check_function_exists(crypt HAVE_CRYPT)
|
||||
check_function_exists(epoll_ctl HAVE_EPOLL_CTL)
|
||||
check_function_exists(fork HAVE_FORK)
|
||||
check_function_exists(getrlimit HAVE_GETRLIMIT)
|
||||
|
@ -151,6 +151,10 @@ check_function_exists(strptime HAVE_STRPTIME)
|
|||
check_function_exists(syslog HAVE_SYSLOG)
|
||||
check_function_exists(writev HAVE_WRITEV)
|
||||
check_function_exists(inet_aton HAVE_INET_ATON)
|
||||
check_function_exists(issetugid HAVE_ISSETUGID)
|
||||
check_function_exists(inet_pton HAVE_INET_PTON)
|
||||
check_function_exists(memset_s HAVE_MEMSET_S)
|
||||
check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO)
|
||||
check_c_source_compiles("
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -160,8 +164,13 @@ check_c_source_compiles("
|
|||
struct sockaddr_in6 s; struct in6_addr t=in6addr_any; int i=AF_INET6; s; t.s6_addr[0] = 0;
|
||||
return 0;
|
||||
}" HAVE_IPV6)
|
||||
check_function_exists(issetugid HAVE_ISSETUGID)
|
||||
check_function_exists(inet_pton HAVE_INET_PTON)
|
||||
check_c_source_compiles("
|
||||
__attribute__((weak)) void __dummy(void *x) { }
|
||||
int main() {
|
||||
void *x;
|
||||
__dummy(x);
|
||||
}
|
||||
" HAVE_WEAK_SYMBOLS)
|
||||
|
||||
## refactor me
|
||||
macro(XCONFIG _package _include_DIR _link_DIR _link_FLAGS _cflags)
|
||||
|
@ -485,7 +494,7 @@ set(COMMON_SRC
|
|||
network_write.c network_linux_sendfile.c
|
||||
network_freebsd_sendfile.c
|
||||
network_solaris_sendfilev.c network_openssl.c
|
||||
status_counter.c
|
||||
status_counter.c safe_memclear.c
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
|
|
@ -75,7 +75,8 @@ common_src=buffer.c log.c \
|
|||
network_write_mmap.c network_write_no_mmap.c \
|
||||
network_freebsd_sendfile.c network_writev.c \
|
||||
network_solaris_sendfilev.c network_openssl.c \
|
||||
splaytree.c status_counter.c
|
||||
splaytree.c status_counter.c \
|
||||
safe_memclear.c
|
||||
|
||||
src = server.c response.c connections.c network.c \
|
||||
configfile.c configparser.c request.c proc_open.c
|
||||
|
@ -278,7 +279,7 @@ hdr = server.h buffer.h network.h log.h keyvalue.h \
|
|||
mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
|
||||
configparser.h mod_ssi_exprparser.h \
|
||||
sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
|
||||
splaytree.h proc_open.h status_counter.h \
|
||||
safe_memclear.h splaytree.h proc_open.h status_counter.h \
|
||||
mod_magnet_cache.h \
|
||||
version.h
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ common_src = Split("buffer.c log.c \
|
|||
network_write.c network_linux_sendfile.c \
|
||||
network_freebsd_sendfile.c \
|
||||
network_solaris_sendfilev.c network_openssl.c \
|
||||
status_counter.c \
|
||||
status_counter.c safe_memclear.c \
|
||||
")
|
||||
|
||||
src = Split("server.c response.c connections.c network.c \
|
||||
|
|
|
@ -170,8 +170,6 @@ static inline void buffer_append_slash(buffer *b); /* append '/' no non-empty st
|
|||
#define CONST_BUF_LEN(x) ((x) ? (x)->ptr : NULL), buffer_string_length(x)
|
||||
|
||||
|
||||
#define UNUSED(x) ( (void)(x) )
|
||||
|
||||
void print_backtrace(FILE *file);
|
||||
void log_failed_assert(const char *filename, unsigned int line, const char *msg) LI_NORETURN;
|
||||
#define force_assert(x) do { if (!(x)) log_failed_assert(__FILE__, __LINE__, "assertion failed: " #x); } while(0)
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
#cmakedefine HAVE_SYS_TIME_H
|
||||
#cmakedefine HAVE_UNISTD_H
|
||||
#cmakedefine HAVE_PTHREAD_H
|
||||
#cmakedefine HAVE_INET_ATON
|
||||
#cmakedefine HAVE_IPV6
|
||||
#cmakedefine HAVE_ISSETUGID
|
||||
#cmakedefine HAVE_WEAK_SYMBOLS
|
||||
|
||||
/* XATTR */
|
||||
#cmakedefine HAVE_ATTR_ATTRIBUTES_H
|
||||
|
@ -143,6 +142,11 @@
|
|||
#cmakedefine HAVE_STRPTIME
|
||||
#cmakedefine HAVE_SYSLOG
|
||||
#cmakedefine HAVE_WRITEV
|
||||
#cmakedefine HAVE_INET_ATON
|
||||
#cmakedefine HAVE_ISSETUGID
|
||||
#cmakedefine HAVE_INET_PTON
|
||||
#cmakedefine HAVE_MEMSET_S
|
||||
#cmakedefine HAVE_EXPLICIT_BZERO
|
||||
|
||||
/* libcrypt */
|
||||
#cmakedefine HAVE_CRYPT_H
|
||||
|
|
263
src/http_auth.c
263
src/http_auth.c
|
@ -34,6 +34,8 @@
|
|||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
#include "safe_memclear.h"
|
||||
|
||||
#define HASHLEN 16
|
||||
#define HASHHEXLEN 32
|
||||
typedef unsigned char HASH[HASHLEN];
|
||||
|
@ -431,164 +433,165 @@ int http_auth_match_rules(server *srv, array *req, const char *username, const c
|
|||
|
||||
static void to64(char *s, unsigned long v, int n)
|
||||
{
|
||||
static const unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
static const unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
while (--n >= 0) {
|
||||
*s++ = itoa64[v&0x3f];
|
||||
v >>= 6;
|
||||
}
|
||||
while (--n >= 0) {
|
||||
*s++ = itoa64[v&0x3f];
|
||||
v >>= 6;
|
||||
}
|
||||
}
|
||||
|
||||
static void apr_md5_encode(const char *pw, const char *salt, char *result, size_t nbytes) {
|
||||
/*
|
||||
* Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,
|
||||
* plus 4 for the '$' separators, plus the password hash itself.
|
||||
* Let's leave a goodly amount of leeway.
|
||||
*/
|
||||
/*
|
||||
* Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,
|
||||
* plus 4 for the '$' separators, plus the password hash itself.
|
||||
* Let's leave a goodly amount of leeway.
|
||||
*/
|
||||
|
||||
char passwd[120], *p;
|
||||
const char *sp, *ep;
|
||||
unsigned char final[APR_MD5_DIGESTSIZE];
|
||||
ssize_t sl, pl, i;
|
||||
li_MD5_CTX ctx, ctx1;
|
||||
unsigned long l;
|
||||
char passwd[120], *p;
|
||||
const char *sp, *ep;
|
||||
unsigned char final[APR_MD5_DIGESTSIZE];
|
||||
ssize_t sl, pl, i;
|
||||
li_MD5_CTX ctx, ctx1;
|
||||
unsigned long l;
|
||||
|
||||
/*
|
||||
* Refine the salt first. It's possible we were given an already-hashed
|
||||
* string as the salt argument, so extract the actual salt value from it
|
||||
* if so. Otherwise just use the string up to the first '$' as the salt.
|
||||
*/
|
||||
sp = salt;
|
||||
/*
|
||||
* Refine the salt first. It's possible we were given an already-hashed
|
||||
* string as the salt argument, so extract the actual salt value from it
|
||||
* if so. Otherwise just use the string up to the first '$' as the salt.
|
||||
*/
|
||||
sp = salt;
|
||||
|
||||
/*
|
||||
* If it starts with the magic string, then skip that.
|
||||
*/
|
||||
if (!strncmp(sp, APR1_ID, strlen(APR1_ID))) {
|
||||
sp += strlen(APR1_ID);
|
||||
}
|
||||
/*
|
||||
* If it starts with the magic string, then skip that.
|
||||
*/
|
||||
if (!strncmp(sp, APR1_ID, strlen(APR1_ID))) {
|
||||
sp += strlen(APR1_ID);
|
||||
}
|
||||
|
||||
/*
|
||||
* It stops at the first '$' or 8 chars, whichever comes first
|
||||
*/
|
||||
for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* It stops at the first '$' or 8 chars, whichever comes first
|
||||
*/
|
||||
for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the length of the true salt
|
||||
*/
|
||||
sl = ep - sp;
|
||||
/*
|
||||
* Get the length of the true salt
|
||||
*/
|
||||
sl = ep - sp;
|
||||
|
||||
/*
|
||||
* 'Time to make the doughnuts..'
|
||||
*/
|
||||
li_MD5_Init(&ctx);
|
||||
/*
|
||||
* 'Time to make the doughnuts..'
|
||||
*/
|
||||
li_MD5_Init(&ctx);
|
||||
|
||||
/*
|
||||
* The password first, since that is what is most unknown
|
||||
*/
|
||||
li_MD5_Update(&ctx, pw, strlen(pw));
|
||||
/*
|
||||
* The password first, since that is what is most unknown
|
||||
*/
|
||||
li_MD5_Update(&ctx, pw, strlen(pw));
|
||||
|
||||
/*
|
||||
* Then our magic string
|
||||
*/
|
||||
li_MD5_Update(&ctx, APR1_ID, strlen(APR1_ID));
|
||||
/*
|
||||
* Then our magic string
|
||||
*/
|
||||
li_MD5_Update(&ctx, APR1_ID, strlen(APR1_ID));
|
||||
|
||||
/*
|
||||
* Then the raw salt
|
||||
*/
|
||||
li_MD5_Update(&ctx, sp, sl);
|
||||
/*
|
||||
* Then the raw salt
|
||||
*/
|
||||
li_MD5_Update(&ctx, sp, sl);
|
||||
|
||||
/*
|
||||
* Then just as many characters of the MD5(pw, salt, pw)
|
||||
*/
|
||||
li_MD5_Init(&ctx1);
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
li_MD5_Update(&ctx1, sp, sl);
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
li_MD5_Final(final, &ctx1);
|
||||
for (pl = strlen(pw); pl > 0; pl -= APR_MD5_DIGESTSIZE) {
|
||||
li_MD5_Update(&ctx, final,
|
||||
(pl > APR_MD5_DIGESTSIZE) ? APR_MD5_DIGESTSIZE : pl);
|
||||
}
|
||||
/*
|
||||
* Then just as many characters of the MD5(pw, salt, pw)
|
||||
*/
|
||||
li_MD5_Init(&ctx1);
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
li_MD5_Update(&ctx1, sp, sl);
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
li_MD5_Final(final, &ctx1);
|
||||
for (pl = strlen(pw); pl > 0; pl -= APR_MD5_DIGESTSIZE) {
|
||||
li_MD5_Update(
|
||||
&ctx, final,
|
||||
(pl > APR_MD5_DIGESTSIZE) ? APR_MD5_DIGESTSIZE : pl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't leave anything around in vm they could use.
|
||||
*/
|
||||
memset(final, 0, sizeof(final));
|
||||
/*
|
||||
* Don't leave anything around in vm they could use.
|
||||
*/
|
||||
memset(final, 0, sizeof(final));
|
||||
|
||||
/*
|
||||
* Then something really weird...
|
||||
*/
|
||||
for (i = strlen(pw); i != 0; i >>= 1) {
|
||||
if (i & 1) {
|
||||
li_MD5_Update(&ctx, final, 1);
|
||||
}
|
||||
else {
|
||||
li_MD5_Update(&ctx, pw, 1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Then something really weird...
|
||||
*/
|
||||
for (i = strlen(pw); i != 0; i >>= 1) {
|
||||
if (i & 1) {
|
||||
li_MD5_Update(&ctx, final, 1);
|
||||
}
|
||||
else {
|
||||
li_MD5_Update(&ctx, pw, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now make the output string. We know our limitations, so we
|
||||
* can use the string routines without bounds checking.
|
||||
*/
|
||||
strcpy(passwd, APR1_ID);
|
||||
strncat(passwd, sp, sl);
|
||||
strcat(passwd, "$");
|
||||
/*
|
||||
* Now make the output string. We know our limitations, so we
|
||||
* can use the string routines without bounds checking.
|
||||
*/
|
||||
strcpy(passwd, APR1_ID);
|
||||
strncat(passwd, sp, sl);
|
||||
strcat(passwd, "$");
|
||||
|
||||
li_MD5_Final(final, &ctx);
|
||||
li_MD5_Final(final, &ctx);
|
||||
|
||||
/*
|
||||
* And now, just to make sure things don't run too fast..
|
||||
* On a 60 Mhz Pentium this takes 34 msec, so you would
|
||||
* need 30 seconds to build a 1000 entry dictionary...
|
||||
*/
|
||||
for (i = 0; i < 1000; i++) {
|
||||
li_MD5_Init(&ctx1);
|
||||
if (i & 1) {
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
}
|
||||
else {
|
||||
li_MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
|
||||
}
|
||||
if (i % 3) {
|
||||
li_MD5_Update(&ctx1, sp, sl);
|
||||
}
|
||||
/*
|
||||
* And now, just to make sure things don't run too fast..
|
||||
* On a 60 Mhz Pentium this takes 34 msec, so you would
|
||||
* need 30 seconds to build a 1000 entry dictionary...
|
||||
*/
|
||||
for (i = 0; i < 1000; i++) {
|
||||
li_MD5_Init(&ctx1);
|
||||
if (i & 1) {
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
}
|
||||
else {
|
||||
li_MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
|
||||
}
|
||||
if (i % 3) {
|
||||
li_MD5_Update(&ctx1, sp, sl);
|
||||
}
|
||||
|
||||
if (i % 7) {
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
}
|
||||
if (i % 7) {
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
}
|
||||
|
||||
if (i & 1) {
|
||||
li_MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
|
||||
}
|
||||
else {
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
}
|
||||
li_MD5_Final(final,&ctx1);
|
||||
}
|
||||
if (i & 1) {
|
||||
li_MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
|
||||
}
|
||||
else {
|
||||
li_MD5_Update(&ctx1, pw, strlen(pw));
|
||||
}
|
||||
li_MD5_Final(final,&ctx1);
|
||||
}
|
||||
|
||||
p = passwd + strlen(passwd);
|
||||
p = passwd + strlen(passwd);
|
||||
|
||||
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4;
|
||||
l = final[11] ; to64(p, l, 2); p += 2;
|
||||
*p = '\0';
|
||||
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4;
|
||||
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4;
|
||||
l = final[11] ; to64(p, l, 2); p += 2;
|
||||
*p = '\0';
|
||||
|
||||
/*
|
||||
* Don't leave anything around in vm they could use.
|
||||
*/
|
||||
memset(final, 0, sizeof(final));
|
||||
/*
|
||||
* Don't leave anything around in vm they could use.
|
||||
*/
|
||||
safe_memclear(final, sizeof(final));
|
||||
|
||||
/* FIXME
|
||||
*/
|
||||
#define apr_cpystrn strncpy
|
||||
apr_cpystrn(result, passwd, nbytes - 1);
|
||||
apr_cpystrn(result, passwd, nbytes - 1);
|
||||
}
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include "settings.h"
|
||||
|
||||
#include "safe_memclear.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(HAVE_MEMSET_S) && !defined(HAVE_EXPLICIT_BZERO)
|
||||
|
||||
# if defined(HAVE_WEAK_SYMBOLS)
|
||||
/* it seems weak functions are never inlined, even for static builds */
|
||||
__attribute__((weak)) void __li_safe_memset_hook(void *buf, size_t len);
|
||||
|
||||
void __li_safe_memset_hook(void *buf, size_t len)
|
||||
{
|
||||
UNUSED(buf);
|
||||
UNUSED(len);
|
||||
}
|
||||
# endif /* HAVE_WEAK_SYMBOLS */
|
||||
|
||||
static void* safe_memset(void *s, int c, size_t n)
|
||||
{
|
||||
if (n > 0) {
|
||||
volatile unsigned volatile_zero = 0;
|
||||
volatile unsigned char *vs = (volatile unsigned char*)s;
|
||||
|
||||
do {
|
||||
memset(s, c, n);
|
||||
} while (vs[volatile_zero] != (unsigned char)c);
|
||||
# if defined(HAVE_WEAK_SYMBOLS)
|
||||
__li_safe_memset_hook(s, n);
|
||||
# endif /* HAVE_WEAK_SYMBOLS */
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif /* !defined(HAVE_MEMSET_S) && !defined(HAVE_EXPLICIT_BZERO) */
|
||||
|
||||
|
||||
void safe_memclear(void *s, size_t n) {
|
||||
#if defined(HAVE_MEMSET_S)
|
||||
memset_s(s, 0, n);
|
||||
#elif defined(HAVE_EXPLICIT_BZERO)
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
safe_memset(s, 0, n);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _SAFE_MEMCLEAR_H_
|
||||
#define _SAFE_MEMCLEAR_H_
|
||||
|
||||
/* size_t */
|
||||
#include <sys/types.h>
|
||||
|
||||
void safe_memclear(void *s, size_t n);
|
||||
|
||||
#endif
|
|
@ -15,6 +15,8 @@
|
|||
# define LI_NORETURN
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) ( (void)(x) )
|
||||
|
||||
#define BV(x) (1 << x)
|
||||
|
||||
#define INET_NTOP_CACHE_MAX 4
|
||||
|
|
Loading…
Reference in New Issue