mirror of
https://github.com/3proxy/3proxy.git
synced 2026-06-13 11:00:11 +08:00
Compare commits
8 Commits
4c0e3a1bac
...
a3729354b8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3729354b8 | ||
|
|
45796f66c7 | ||
|
|
260cbf7a3d | ||
|
|
bba9871ed8 | ||
|
|
f1af44f3a9 | ||
|
|
4ee7f71fb9 | ||
|
|
98604b5421 | ||
|
|
a0d580b36d |
1
.gitignore
vendored
1
.gitignore
vendored
@ -258,3 +258,4 @@ pip-log.txt
|
|||||||
#Mr Developer
|
#Mr Developer
|
||||||
.mr.developer.cfg
|
.mr.developer.cfg
|
||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
|
bin/3proxy_crypt
|
||||||
|
|||||||
@ -283,16 +283,20 @@ set(3PROXY_CORE_SOURCES
|
|||||||
src/3proxy.c
|
src/3proxy.c
|
||||||
src/auth.c
|
src/auth.c
|
||||||
src/authradius.c
|
src/authradius.c
|
||||||
|
src/hash.c
|
||||||
|
src/resolve.c
|
||||||
|
src/sql.c
|
||||||
src/conf.c
|
src/conf.c
|
||||||
src/datatypes.c
|
src/datatypes.c
|
||||||
src/plugins.c
|
src/plugins.c
|
||||||
src/stringtable.c
|
src/stringtable.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# MD4/MD5 sources for mycrypt
|
# MD4/MD5/BLAKE2 sources for 3proxy_crypt
|
||||||
set(MD_SOURCES
|
set(MD_SOURCES
|
||||||
src/libs/md4.c
|
src/libs/md4.c
|
||||||
src/libs/md5.c
|
src/libs/md5.c
|
||||||
|
src/libs/blake2b-ref.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@ -345,9 +349,9 @@ target_compile_definitions(mainfunc PRIVATE MODULEMAINFUNC=mainfunc)
|
|||||||
add_library(ftp_obj OBJECT src/ftp.c)
|
add_library(ftp_obj OBJECT src/ftp.c)
|
||||||
target_include_directories(ftp_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
target_include_directories(ftp_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
# mycrypt object for 3proxy (without WITHMAIN)
|
# 3proxy_crypt object for 3proxy (without WITHMAIN)
|
||||||
add_library(mycrypt_obj OBJECT src/mycrypt.c)
|
add_library(3proxy_crypt_obj OBJECT src/3proxy_crypt.c)
|
||||||
target_include_directories(mycrypt_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
target_include_directories(3proxy_crypt_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Main 3proxy executable
|
# Main 3proxy executable
|
||||||
@ -362,7 +366,7 @@ add_executable(3proxy
|
|||||||
$<TARGET_OBJECTS:common_obj>
|
$<TARGET_OBJECTS:common_obj>
|
||||||
$<TARGET_OBJECTS:base64_obj>
|
$<TARGET_OBJECTS:base64_obj>
|
||||||
$<TARGET_OBJECTS:ftp_obj>
|
$<TARGET_OBJECTS:ftp_obj>
|
||||||
$<TARGET_OBJECTS:mycrypt_obj>
|
$<TARGET_OBJECTS:3proxy_crypt_obj>
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(3proxy PRIVATE
|
target_include_directories(3proxy PRIVATE
|
||||||
@ -395,18 +399,18 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Build mycrypt utility
|
# Build 3proxy_crypt utility
|
||||||
add_executable(mycrypt
|
add_executable(3proxy_crypt
|
||||||
src/mycrypt.c
|
src/3proxy_crypt.c
|
||||||
${MD_SOURCES}
|
${MD_SOURCES}
|
||||||
$<TARGET_OBJECTS:base64_obj>
|
$<TARGET_OBJECTS:base64_obj>
|
||||||
)
|
)
|
||||||
target_compile_definitions(mycrypt PRIVATE WITHMAIN)
|
target_compile_definitions(3proxy_crypt PRIVATE WITHMAIN)
|
||||||
target_include_directories(mycrypt PRIVATE
|
target_include_directories(3proxy_crypt PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
|
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
|
||||||
)
|
)
|
||||||
target_link_libraries(mycrypt PRIVATE Threads::Threads)
|
target_link_libraries(3proxy_crypt PRIVATE Threads::Threads)
|
||||||
|
|
||||||
# Build standalone proxy executables
|
# Build standalone proxy executables
|
||||||
foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
||||||
@ -493,7 +497,7 @@ if(PAM_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Installation rules
|
# Installation rules
|
||||||
install(TARGETS 3proxy mycrypt proxy socks pop3p smtpp ftppr tcppm udppm tlspr
|
install(TARGETS 3proxy 3proxy_crypt proxy socks pop3p smtpp ftppr tcppm udppm tlspr
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@ include Makefile.inc
|
|||||||
install: all
|
install: all
|
||||||
if [ ! -d "/usr/local/3proxy/bin" ]; then mkdir -p /usr/local/3proxy/bin/; fi
|
if [ ! -d "/usr/local/3proxy/bin" ]; then mkdir -p /usr/local/3proxy/bin/; fi
|
||||||
install bin/3proxy /usr/local/3proxy/bin/3proxy
|
install bin/3proxy /usr/local/3proxy/bin/3proxy
|
||||||
install bin/mycrypt /usr/local/3proxy/bin/mycrypt
|
install bin/3proxy_crypt /usr/local/3proxy/bin/3proxy_crypt
|
||||||
install scripts/rc.d/3proxy /usr/local/etc/rc.d/3proxy
|
install scripts/rc.d/3proxy /usr/local/etc/rc.d/3proxy
|
||||||
install scripts/add3proxyuser.sh /usr/local/3proxy/bin/
|
install scripts/add3proxyuser.sh /usr/local/3proxy/bin/
|
||||||
if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then /usr/local/3proxy/3proxy.cfg already exists ; else install scripts/3proxy.cfg /usr/local/etc/3proxy/; fi
|
if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then /usr/local/3proxy/3proxy.cfg already exists ; else install scripts/3proxy.cfg /usr/local/etc/3proxy/; fi
|
||||||
|
|||||||
@ -62,7 +62,7 @@ INSTALL_BIN = $(INSTALL) -m 755
|
|||||||
INSTALL_DATA = $(INSTALL) -m 644
|
INSTALL_DATA = $(INSTALL) -m 644
|
||||||
INSTALL_OBJS = bin/3proxy \
|
INSTALL_OBJS = bin/3proxy \
|
||||||
bin/ftppr \
|
bin/ftppr \
|
||||||
bin/mycrypt \
|
bin/3proxy_crypt \
|
||||||
bin/pop3p \
|
bin/pop3p \
|
||||||
bin/proxy \
|
bin/proxy \
|
||||||
bin/socks \
|
bin/socks \
|
||||||
|
|||||||
@ -63,7 +63,7 @@ INSTALL_BIN = $(INSTALL) -m 755
|
|||||||
INSTALL_DATA = $(INSTALL) -m 644
|
INSTALL_DATA = $(INSTALL) -m 644
|
||||||
INSTALL_OBJS = src/3proxy \
|
INSTALL_OBJS = src/3proxy \
|
||||||
src/ftppr \
|
src/ftppr \
|
||||||
src/mycrypt \
|
src/3proxy_crypt \
|
||||||
src/pop3p \
|
src/pop3p \
|
||||||
src/proxy \
|
src/proxy \
|
||||||
src/socks \
|
src/socks \
|
||||||
|
|||||||
@ -51,7 +51,7 @@ include Makefile.inc
|
|||||||
install: all
|
install: all
|
||||||
if [ ! -d "/usr/local/3proxy/bin" ]; then mkdir -p /usr/local/3proxy/bin/; fi
|
if [ ! -d "/usr/local/3proxy/bin" ]; then mkdir -p /usr/local/3proxy/bin/; fi
|
||||||
install bin/3proxy /usr/local/3proxy/bin/3proxy
|
install bin/3proxy /usr/local/3proxy/bin/3proxy
|
||||||
install bin/mycrypt /usr/local/3proxy/bin/mycrypt
|
install bin/3proxy_crypt /usr/local/3proxy/bin/3proxy_crypt
|
||||||
install scripts/rc.d/3proxy /usr/local/etc/rc.d/3proxy
|
install scripts/rc.d/3proxy /usr/local/etc/rc.d/3proxy
|
||||||
install scripts/add3proxyuser.sh /usr/local/3proxy/bin/
|
install scripts/add3proxyuser.sh /usr/local/3proxy/bin/
|
||||||
if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then /usr/local/3proxy/3proxy.cfg already exists ; else install scripts/3proxy.cfg /usr/local/etc/3proxy/; fi
|
if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then /usr/local/3proxy/3proxy.cfg already exists ; else install scripts/3proxy.cfg /usr/local/etc/3proxy/; fi
|
||||||
|
|||||||
10
README.md
10
README.md
@ -200,7 +200,7 @@ sudo launchctl unload /Library/LaunchDaemons/org.3proxy.3proxy.plist
|
|||||||
- User authentication by DNS hostname
|
- User authentication by DNS hostname
|
||||||
- Authentication cache with possibility to limit user to single IP address
|
- Authentication cache with possibility to limit user to single IP address
|
||||||
- Access control by username/password for SOCKSv5 and HTTP/HTTPS/FTP
|
- Access control by username/password for SOCKSv5 and HTTP/HTTPS/FTP
|
||||||
- Cleartext or encrypted (crypt/MD5 or NT) passwords
|
- Cleartext or encrypted passwords
|
||||||
- Connection redirection
|
- Connection redirection
|
||||||
- Access control by requested action (CONNECT/BIND, HTTP GET/POST/PUT/HEAD/OTHER)
|
- Access control by requested action (CONNECT/BIND, HTTP GET/POST/PUT/HEAD/OTHER)
|
||||||
- All access control entries now support weekday and time limitations
|
- All access control entries now support weekday and time limitations
|
||||||
@ -286,12 +286,12 @@ TLS proxy (SNI proxy) - sniffs hostname from TLS handshake
|
|||||||
### udppm
|
### udppm
|
||||||
UDP port mapping. Maps some UDP port on local machine to UDP port on remote machine. Only one user simultaneously can use UDP mapping, so it can't be used for public service in large networks. It's OK to use it to map to DNS server in small network or to map Counter-Strike server for single client (you can use few mappings on different ports for different clients in last case).
|
UDP port mapping. Maps some UDP port on local machine to UDP port on remote machine. Only one user simultaneously can use UDP mapping, so it can't be used for public service in large networks. It's OK to use it to map to DNS server in small network or to map Counter-Strike server for single client (you can use few mappings on different ports for different clients in last case).
|
||||||
|
|
||||||
### mycrypt
|
### 3proxy_crypt
|
||||||
Program to obtain crypted password for cleartext. Supports both MD5/crypt and NT password.
|
Program to obtain crypted password for cleartext. Supports both salted and NT password.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mycrypt password # produces NT password
|
3proxy_crypt password # produces NT password
|
||||||
mycrypt salt password # produces MD5/crypt password with salt "salt"
|
3proxy_crypt salt password # produces password hash with salt "salt"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -969,7 +969,7 @@ or
|
|||||||
<pre>
|
<pre>
|
||||||
users $"c:\Program Files\3proxy\passwords"
|
users $"c:\Program Files\3proxy\passwords"
|
||||||
</pre>
|
</pre>
|
||||||
It's possible to create NT and crypt passwords with the mycrypt utility included
|
It's possible to create NT and crypt passwords with the 3proxy_crypt utility included
|
||||||
in the distribution.
|
in the distribution.
|
||||||
<br>The user list is system-wide. To manage user access to a specific service, use ACLs.
|
<br>The user list is system-wide. To manage user access to a specific service, use ACLs.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -983,7 +983,7 @@ openssl pkcs12 -export -out client.p12 -passout pass: \
|
|||||||
или
|
или
|
||||||
<pre>
|
<pre>
|
||||||
users $"c:\Program Files\3proxy\passwords"</pre>
|
users $"c:\Program Files\3proxy\passwords"</pre>
|
||||||
Шифрованные NT и crypt пароли можно создавать с помощью утилиты mycrypt.
|
Шифрованные NT и crypt пароли можно создавать с помощью утилиты 3proxy_crypt.
|
||||||
<br>Список пользователей един для всех служб. Разграничение доступа по службам
|
<br>Список пользователей един для всех служб. Разграничение доступа по службам
|
||||||
необходимо производить с помощью списков доступа.
|
необходимо производить с помощью списков доступа.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -6,7 +6,7 @@ if [ $3 ]; then
|
|||||||
echo countin \"`wc -l /etc/3proxy/conf/counters|awk '{print $1}'`/$1\" D $3 $1 >> /etc/3proxy/conf/counters
|
echo countin \"`wc -l /etc/3proxy/conf/counters|awk '{print $1}'`/$1\" D $3 $1 >> /etc/3proxy/conf/counters
|
||||||
fi
|
fi
|
||||||
if [ $2 ]; then
|
if [ $2 ]; then
|
||||||
echo $1:`/bin/mycrypt $$ $2` >> /etc/3proxy/conf/passwd
|
echo $1:`/bin/3proxy_crypt $$ $2` >> /etc/3proxy/conf/passwd
|
||||||
else
|
else
|
||||||
echo usage: $0 username password [day_limit] [bandwidth]
|
echo usage: $0 username password [day_limit] [bandwidth]
|
||||||
echo " "day_limit - traffic limit in MB per day
|
echo " "day_limit - traffic limit in MB per day
|
||||||
|
|||||||
@ -33,7 +33,7 @@ make clean
|
|||||||
%files
|
%files
|
||||||
/bin/3proxy
|
/bin/3proxy
|
||||||
/bin/ftppr
|
/bin/ftppr
|
||||||
/bin/mycrypt
|
/bin/3proxy_crypt
|
||||||
/bin/pop3p
|
/bin/pop3p
|
||||||
/bin/proxy
|
/bin/proxy
|
||||||
/bin/socks
|
/bin/socks
|
||||||
|
|||||||
@ -5,8 +5,11 @@
|
|||||||
please read License Agreement
|
please read License Agreement
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
#ifndef WITHMAIN
|
||||||
#include "libs/md5.h"
|
#include "libs/md5.h"
|
||||||
|
#endif
|
||||||
#include "libs/md4.h"
|
#include "libs/md4.h"
|
||||||
|
#include "libs/blake2.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define MD5_SIZE 16
|
#define MD5_SIZE 16
|
||||||
@ -64,20 +67,21 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
|
|||||||
unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){
|
unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){
|
||||||
|
|
||||||
const unsigned char *ep;
|
const unsigned char *ep;
|
||||||
|
unsigned char *magic;
|
||||||
|
unsigned char *p;
|
||||||
|
const unsigned char *sp;
|
||||||
|
unsigned char final[MD5_SIZE];
|
||||||
|
int sl;
|
||||||
|
unsigned long l;
|
||||||
|
|
||||||
|
#ifndef WITHMAIN
|
||||||
if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
||||||
static unsigned char *magic = (unsigned char *)"$1$";
|
|
||||||
unsigned char *p;
|
|
||||||
const unsigned char *sp;
|
|
||||||
unsigned char final[MD5_SIZE];
|
|
||||||
int sl,pl,i;
|
|
||||||
MD5_CTX ctx,ctx1;
|
MD5_CTX ctx,ctx1;
|
||||||
unsigned long l;
|
int pl, i;
|
||||||
|
|
||||||
/* Refine the Salt first */
|
|
||||||
sp = salt +3;
|
sp = salt +3;
|
||||||
|
|
||||||
/* get the length of the true salt */
|
|
||||||
sl = (int)(ep - sp);
|
sl = (int)(ep - sp);
|
||||||
|
magic = (unsigned char *)"$1$";
|
||||||
|
|
||||||
MD5Init(&ctx);
|
MD5Init(&ctx);
|
||||||
|
|
||||||
@ -109,10 +113,6 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
|
|||||||
else
|
else
|
||||||
MD5Update(&ctx, pw, 1);
|
MD5Update(&ctx, pw, 1);
|
||||||
|
|
||||||
/* Now make the output string */
|
|
||||||
strcpy((char *)passwd,(char *)magic);
|
|
||||||
strncat((char *)passwd,(char *)sp,sl);
|
|
||||||
strcat((char *)passwd,"$");
|
|
||||||
|
|
||||||
MD5Final(final,&ctx);
|
MD5Final(final,&ctx);
|
||||||
|
|
||||||
@ -141,28 +141,42 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
|
|||||||
MD5Final(final,&ctx1);
|
MD5Final(final,&ctx1);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = passwd + strlen((char *)passwd);
|
|
||||||
|
|
||||||
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
|
|
||||||
_crypt_to64(p,l,4); p += 4;
|
|
||||||
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
|
|
||||||
_crypt_to64(p,l,4); p += 4;
|
|
||||||
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
|
|
||||||
_crypt_to64(p,l,4); p += 4;
|
|
||||||
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
|
|
||||||
_crypt_to64(p,l,4); p += 4;
|
|
||||||
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
|
|
||||||
_crypt_to64(p,l,4); p += 4;
|
|
||||||
l = final[11] ;
|
|
||||||
_crypt_to64(p,l,2); p += 2;
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
/* Don't leave anything around in vm they could use. */
|
/* Don't leave anything around in vm they could use. */
|
||||||
memset(final,0,sizeof final);
|
memset(final,0,sizeof final);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if(salt[0] == '$' && salt[1] == '3' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
||||||
|
sp = salt +3;
|
||||||
|
sl = (int)(ep - sp);
|
||||||
|
magic = (unsigned char *)"$3$";
|
||||||
|
|
||||||
|
blake2b(final, MD5_SIZE, pw, strlen((char *)pw), salt, strlen((char *)salt) );
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
*passwd = 0;
|
*passwd = 0;
|
||||||
|
return passwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcpy((char *)passwd,(char *)magic);
|
||||||
|
strncat((char *)passwd,(char *)sp,sl);
|
||||||
|
strcat((char *)passwd,"$");
|
||||||
|
p = passwd + strlen((char *)passwd);
|
||||||
|
|
||||||
|
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
|
||||||
|
_crypt_to64(p,l,4); p += 4;
|
||||||
|
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
|
||||||
|
_crypt_to64(p,l,4); p += 4;
|
||||||
|
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
|
||||||
|
_crypt_to64(p,l,4); p += 4;
|
||||||
|
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
|
||||||
|
_crypt_to64(p,l,4); p += 4;
|
||||||
|
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
|
||||||
|
_crypt_to64(p,l,4); p += 4;
|
||||||
|
l = final[11] ;
|
||||||
|
_crypt_to64(p,l,2); p += 2;
|
||||||
|
*p = '\0';
|
||||||
return passwd;
|
return passwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +190,7 @@ int main(int argc, char* argv[]){
|
|||||||
fprintf(stderr, "usage: \n"
|
fprintf(stderr, "usage: \n"
|
||||||
"\t%s <password>\n"
|
"\t%s <password>\n"
|
||||||
"\t%s <salt> <password>\n"
|
"\t%s <salt> <password>\n"
|
||||||
"Performs NT crypt if no salt specified, MD5 crypt with salt\n"
|
"Performs NT crypt if no salt specified, BLAKE2 crypt with salt\n"
|
||||||
"This software uses:\n"
|
"This software uses:\n"
|
||||||
" RSA Data Security, Inc. MD4 Message-Digest Algorithm\n"
|
" RSA Data Security, Inc. MD4 Message-Digest Algorithm\n"
|
||||||
" RSA Data Security, Inc. MD5 Message-Digest Algorithm\n",
|
" RSA Data Security, Inc. MD5 Message-Digest Algorithm\n",
|
||||||
@ -190,7 +204,7 @@ int main(int argc, char* argv[]){
|
|||||||
else {
|
else {
|
||||||
i = (int)strlen((char *)argv[1]);
|
i = (int)strlen((char *)argv[1]);
|
||||||
if (i > 64) argv[1][64] = 0;
|
if (i > 64) argv[1][64] = 0;
|
||||||
sprintf((char *)buf, "$1$%s$", argv[1]);
|
sprintf((char *)buf, "$3$%s$", argv[1]);
|
||||||
printf("CR:%s\n", mycrypt((unsigned char *)argv[2], buf, buf+256));
|
printf("CR:%s\n", mycrypt((unsigned char *)argv[2], buf, buf+256));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -2,7 +2,7 @@
|
|||||||
# 3 proxy common Makefile
|
# 3 proxy common Makefile
|
||||||
#
|
#
|
||||||
|
|
||||||
all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)mycrypt$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)tlspr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins
|
all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)3proxy_crypt$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)tlspr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins
|
||||||
|
|
||||||
|
|
||||||
sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
|
sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
|
||||||
@ -119,6 +119,12 @@ srvdnspr$(OBJSUFFICS): dnspr.c proxy.h structures.h
|
|||||||
auth$(OBJSUFFICS): auth.c proxy.h structures.h
|
auth$(OBJSUFFICS): auth.c proxy.h structures.h
|
||||||
$(CC) $(COUT)auth$(OBJSUFFICS) $(CFLAGS) auth.c
|
$(CC) $(COUT)auth$(OBJSUFFICS) $(CFLAGS) auth.c
|
||||||
|
|
||||||
|
hash$(OBJSUFFICS): hash.c proxy.h structures.h
|
||||||
|
$(CC) $(COUT)hash$(OBJSUFFICS) $(CFLAGS) hash.c
|
||||||
|
|
||||||
|
resolve$(OBJSUFFICS): resolve.c proxy.h structures.h
|
||||||
|
$(CC) $(COUT)resolve$(OBJSUFFICS) $(CFLAGS) resolve.c
|
||||||
|
|
||||||
authradius$(OBJSUFFICS): authradius.c proxy.h structures.h
|
authradius$(OBJSUFFICS): authradius.c proxy.h structures.h
|
||||||
$(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c
|
$(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c
|
||||||
|
|
||||||
@ -131,15 +137,11 @@ log$(OBJSUFFICS): log.c proxy.h structures.h
|
|||||||
datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h
|
datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h
|
||||||
$(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c
|
$(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c
|
||||||
|
|
||||||
mycrypt$(OBJSUFFICS): mycrypt.c
|
3proxy_crypt$(OBJSUFFICS): 3proxy_crypt.c
|
||||||
$(CC) $(COUT)mycrypt$(OBJSUFFICS) $(CFLAGS) mycrypt.c
|
$(CC) $(COUT)3proxy_crypt$(OBJSUFFICS) $(CFLAGS) 3proxy_crypt.c
|
||||||
|
|
||||||
mycryptmain$(OBJSUFFICS): mycrypt.c
|
|
||||||
$(CC) $(COUT)mycryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN mycrypt.c
|
|
||||||
|
|
||||||
$(BUILDDIR)mycrypt$(EXESUFFICS): md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycryptmain$(OBJSUFFICS) base64$(OBJSUFFICS)
|
|
||||||
$(LN) $(LNOUT)$(BUILDDIR)mycrypt$(EXESUFFICS) $(LDFLAGS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) base64$(OBJSUFFICS) mycryptmain$(OBJSUFFICS)
|
|
||||||
|
|
||||||
|
3proxy_cryptmain$(OBJSUFFICS): 3proxy_crypt.c
|
||||||
|
$(CC) $(COUT)3proxy_cryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN 3proxy_crypt.c
|
||||||
|
|
||||||
md4$(OBJSUFFICS): libs/md4.h libs/md4.c
|
md4$(OBJSUFFICS): libs/md4.h libs/md4.c
|
||||||
$(CC) $(COUT)md4$(OBJSUFFICS) $(CFLAGS) libs/md4.c
|
$(CC) $(COUT)md4$(OBJSUFFICS) $(CFLAGS) libs/md4.c
|
||||||
@ -147,9 +149,15 @@ md4$(OBJSUFFICS): libs/md4.h libs/md4.c
|
|||||||
md5$(OBJSUFFICS): libs/md5.h libs/md5.c
|
md5$(OBJSUFFICS): libs/md5.h libs/md5.c
|
||||||
$(CC) $(COUT)md5$(OBJSUFFICS) $(CFLAGS) libs/md5.c
|
$(CC) $(COUT)md5$(OBJSUFFICS) $(CFLAGS) libs/md5.c
|
||||||
|
|
||||||
|
blake2$(OBJSUFFICS): libs/blake2.h libs/blake2-impl.h libs/blake2b-ref.c
|
||||||
|
$(CC) $(COUT)blake2$(OBJSUFFICS) $(CFLAGS) libs/blake2b-ref.c
|
||||||
|
|
||||||
|
$(BUILDDIR)3proxy_crypt$(EXESUFFICS): md4$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) base64$(OBJSUFFICS)
|
||||||
|
$(LN) $(LNOUT)$(BUILDDIR)3proxy_crypt$(EXESUFFICS) $(LDFLAGS) md4$(OBJSUFFICS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS)
|
||||||
|
|
||||||
stringtable$(OBJSUFFICS): stringtable.c
|
stringtable$(OBJSUFFICS): stringtable.c
|
||||||
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
|
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
|
||||||
|
|
||||||
$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP)
|
$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP)
|
||||||
$(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
$(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||||
|
|
||||||
|
|||||||
513
src/auth.c
513
src/auth.c
@ -1035,516 +1035,3 @@ struct auth authfuncs[] = {
|
|||||||
{NULL, NULL, NULL, ""}
|
{NULL, NULL, NULL, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, NULL};
|
|
||||||
struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, NULL};
|
|
||||||
|
|
||||||
|
|
||||||
void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd){
|
|
||||||
unsigned i, j, k;
|
|
||||||
memcpy(hash, rnd, sizeof(unsigned)*4);
|
|
||||||
for(i=0, j=0, k=0; name[j]; j++){
|
|
||||||
hash[i] += (toupper(name[j]) - 32)+rnd[((toupper(name[j]))*29277+rnd[(k+j+i)%16]+k+j+i)%16];
|
|
||||||
if(++i == sizeof(unsigned)*4) {
|
|
||||||
i = 0;
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned hashindex(struct hashtable *ht, const unsigned char* hash){
|
|
||||||
unsigned t1, t2, t3, t4;
|
|
||||||
t1 = *(unsigned *)hash;
|
|
||||||
t2 = *(unsigned *)(hash + sizeof(unsigned));
|
|
||||||
t3 = *(unsigned *)(hash + (2*sizeof(unsigned)));
|
|
||||||
t4 = *(unsigned *)(hash + (3*sizeof(unsigned)));
|
|
||||||
return (t1 + (t2 * 7) + (t3 * 17) + (t4 * 29) ) % (ht->hashsize >> 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void destroyhashtable(struct hashtable *ht){
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(ht->hashtable){
|
|
||||||
myfree(ht->hashtable);
|
|
||||||
ht->hashtable = NULL;
|
|
||||||
}
|
|
||||||
if(ht->hashvalues){
|
|
||||||
myfree(ht->hashvalues);
|
|
||||||
ht->hashvalues = NULL;
|
|
||||||
}
|
|
||||||
ht->hashsize = 0;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define hvalue(I) ((struct hashentry *)((char *)ht->hashvalues + (I)*(sizeof(struct hashentry) + ht->recsize - 4)))
|
|
||||||
int inithashtable(struct hashtable *ht, unsigned nhashsize){
|
|
||||||
unsigned i;
|
|
||||||
clock_t c;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
struct timeb tb;
|
|
||||||
|
|
||||||
ftime(&tb);
|
|
||||||
|
|
||||||
#else
|
|
||||||
struct timeval tb;
|
|
||||||
struct timezone tz;
|
|
||||||
gettimeofday(&tb, &tz);
|
|
||||||
#endif
|
|
||||||
c = clock();
|
|
||||||
|
|
||||||
if(nhashsize<4) return 1;
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(ht->hashtable){
|
|
||||||
myfree(ht->hashtable);
|
|
||||||
ht->hashtable = NULL;
|
|
||||||
}
|
|
||||||
if(ht->hashvalues){
|
|
||||||
myfree(ht->hashvalues);
|
|
||||||
ht->hashvalues = NULL;
|
|
||||||
}
|
|
||||||
ht->hashsize = 0;
|
|
||||||
if(!(ht->hashtable = myalloc((nhashsize>>2) * sizeof(struct hashentry *)))){
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if(!(ht->hashvalues = myalloc(nhashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
|
|
||||||
myfree(ht->hashtable);
|
|
||||||
ht->hashtable = NULL;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
ht->hashsize = nhashsize;
|
|
||||||
ht->rnd[0] = myrand(&tb, sizeof(tb));
|
|
||||||
ht->rnd[1] = myrand(ht->hashtable, sizeof(ht->hashtable));
|
|
||||||
ht->rnd[2] = myrand(&c, sizeof(c));
|
|
||||||
ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
|
|
||||||
memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *));
|
|
||||||
memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize -4));
|
|
||||||
|
|
||||||
for(i = 0; i< (ht->hashsize - 1); i++) {
|
|
||||||
hvalue(i)->next = hvalue(i+1);
|
|
||||||
}
|
|
||||||
ht->hashempty = ht->hashvalues;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires){
|
|
||||||
struct hashentry * hen, *he;
|
|
||||||
struct hashentry ** hep;
|
|
||||||
|
|
||||||
unsigned index;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(!ht||!value||!name||!ht->hashtable||!ht->hashempty) {
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hen = ht->hashempty;
|
|
||||||
ht->hashempty = ht->hashempty->next;
|
|
||||||
nametohash(name, hen->hash, (unsigned char *)ht->rnd);
|
|
||||||
memcpy(hen->value, value, ht->recsize);
|
|
||||||
hen->expires = expires;
|
|
||||||
hen->next = NULL;
|
|
||||||
index = hashindex(ht, hen->hash);
|
|
||||||
|
|
||||||
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
|
|
||||||
if(he->expires < conf.time || !memcmp(hen->hash, he->hash, sizeof(he->hash))) {
|
|
||||||
(*hep) = he->next;
|
|
||||||
he->expires = 0;
|
|
||||||
he->next = ht->hashempty;
|
|
||||||
ht->hashempty = he;
|
|
||||||
}
|
|
||||||
else hep=&(he->next);
|
|
||||||
}
|
|
||||||
hen->next = ht->hashtable[index];
|
|
||||||
ht->hashtable[index] = hen;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t hashresolv(struct hashtable *ht, const unsigned char* name, unsigned char* value, uint32_t *ttl){
|
|
||||||
unsigned char hash[sizeof(unsigned)*4];
|
|
||||||
struct hashentry ** hep;
|
|
||||||
struct hashentry *he;
|
|
||||||
unsigned index;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(!ht || !ht->hashtable || !name) {
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
nametohash(name, hash, (unsigned char *)ht->rnd);
|
|
||||||
index = hashindex(ht, hash);
|
|
||||||
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
|
|
||||||
if(he->expires < conf.time) {
|
|
||||||
(*hep) = he->next;
|
|
||||||
he->expires = 0;
|
|
||||||
he->next = ht->hashempty;
|
|
||||||
ht->hashempty = he;
|
|
||||||
}
|
|
||||||
else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){
|
|
||||||
if(ttl) *ttl = (uint32_t)(he->expires - conf.time);
|
|
||||||
memcpy(value, he->value, ht->recsize);
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else hep=&(he->next);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
|
||||||
struct nserver authnserver;
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_t *retttl, struct clientparam* param, int makeauth){
|
|
||||||
|
|
||||||
int i,n;
|
|
||||||
uint32_t retval;
|
|
||||||
|
|
||||||
if((af == AF_INET) && (retval = hashresolv(&dns_table, name, value, retttl))) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
if((af == AF_INET6) && (retval = hashresolv(&dns6_table, name, value, retttl))) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
|
|
||||||
for(i=0; i<n; i++){
|
|
||||||
unsigned short nq, na;
|
|
||||||
unsigned char b[4098], *buf, *s1, *s2;
|
|
||||||
int j, k, len, flen;
|
|
||||||
SOCKET sock;
|
|
||||||
uint32_t ttl;
|
|
||||||
PROXYSOCKADDRTYPE addr;
|
|
||||||
PROXYSOCKADDRTYPE *sinsr, *sinsl;
|
|
||||||
int usetcp = 0;
|
|
||||||
unsigned short serial = 1;
|
|
||||||
|
|
||||||
buf = b+2;
|
|
||||||
|
|
||||||
sinsl = (param && !makeauth)? ¶m->sinsl : &addr;
|
|
||||||
sinsr = (param && !makeauth)? ¶m->sinsr : &addr;
|
|
||||||
memset(sinsl, 0, sizeof(addr));
|
|
||||||
memset(sinsr, 0, sizeof(addr));
|
|
||||||
|
|
||||||
|
|
||||||
if(makeauth && !SAISNULL(&authnserver.addr)){
|
|
||||||
usetcp = authnserver.usetcp;
|
|
||||||
*SAFAMILY(sinsl) = *SAFAMILY(&authnserver.addr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
usetcp = nservers[i].usetcp;
|
|
||||||
*SAFAMILY(sinsl) = *SAFAMILY(&nservers[i].addr);
|
|
||||||
}
|
|
||||||
if((sock=so._socket(so.state, SASOCK(sinsl), usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
|
|
||||||
if(so._bind(so.state, sock,(struct sockaddr *)sinsl,SASIZE(sinsl))){
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(makeauth && !SAISNULL(&authnserver.addr)){
|
|
||||||
*sinsr = authnserver.addr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*sinsr = nservers[i].addr;
|
|
||||||
}
|
|
||||||
if(usetcp){
|
|
||||||
if(connectwithpoll(NULL, sock,(struct sockaddr *)sinsr,SASIZE(sinsr),conf.timeouts[CONNECT_TO])) {
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef TCP_NODELAY
|
|
||||||
{
|
|
||||||
int opt = 1;
|
|
||||||
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
len = (int)strlen((char *)name);
|
|
||||||
|
|
||||||
serial = myrand(name,len);
|
|
||||||
*(unsigned short*)buf = serial; /* query id */
|
|
||||||
buf[2] = 1; /* recursive */
|
|
||||||
buf[3] = 0;
|
|
||||||
buf[4] = 0;
|
|
||||||
buf[5] = 1; /* 1 request */
|
|
||||||
buf[6] = buf[7] = 0; /* no replies */
|
|
||||||
buf[8] = buf[9] = 0; /* no ns count */
|
|
||||||
buf[10] = buf[11] = 0; /* no additional */
|
|
||||||
if(len > 255) {
|
|
||||||
len = 255;
|
|
||||||
}
|
|
||||||
memcpy(buf + 13, name, len);
|
|
||||||
len += 13;
|
|
||||||
buf[len] = 0;
|
|
||||||
for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
|
|
||||||
*s2 = (len - (int)(s2 - buf)) - 1;
|
|
||||||
len++;
|
|
||||||
buf[len++] = 0;
|
|
||||||
buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01); /* PTR:host address */
|
|
||||||
buf[len++] = 0;
|
|
||||||
buf[len++] = 1; /* INET */
|
|
||||||
if(usetcp){
|
|
||||||
buf-=2;
|
|
||||||
*(unsigned short*)buf = htons(len);
|
|
||||||
len+=2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(socksendto(NULL, sock, (struct sockaddr *)sinsr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(param) param->statscli64 += len;
|
|
||||||
len = sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf, 4096, conf.timeouts[DNS_TO]*1000);
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
if(len <= 13) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(param) param->statssrv64 += len;
|
|
||||||
if(usetcp){
|
|
||||||
unsigned short us;
|
|
||||||
us = ntohs(*(unsigned short*)buf);
|
|
||||||
len-=2;
|
|
||||||
buf+=2;
|
|
||||||
if(us > 4096 || us < len || (us > len && sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf+len, us-len, conf.timeouts[DNS_TO]*1000) != us-len)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(*(unsigned short *)buf != serial)continue;
|
|
||||||
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
nq = buf[5] + (((unsigned short)buf[4])<<8);
|
|
||||||
if (nq != 1) {
|
|
||||||
continue; /* we did only 1 request */
|
|
||||||
}
|
|
||||||
for(k = 13; k<len && buf[k]; k++) {
|
|
||||||
}
|
|
||||||
k++;
|
|
||||||
if( (k+4) >= len) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
k += 4;
|
|
||||||
if(na > 255) na = 255; /* somebody is very evil */
|
|
||||||
for (j = 0; j < na; j++) { /* now there should be answers */
|
|
||||||
while(buf[k] < 192 && buf[k] !=0 && (k+buf[k]+14) < len) k+= (buf[k] + 1);
|
|
||||||
if(!buf[k]) k--;
|
|
||||||
if((k+(af == AF_INET6?28:16)) > len) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
|
|
||||||
if((k+12+flen) > len) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(makeauth != 1){
|
|
||||||
if(buf[k+2] != 0 || buf[k+3] != (af == AF_INET6?0x1c:0x1) || flen != (af == AF_INET6?16:4)) {
|
|
||||||
k+= (12 + flen);
|
|
||||||
continue; /* we need A IPv4 */
|
|
||||||
}
|
|
||||||
ttl = ntohl(*(uint32_t *)(buf + k + 6));
|
|
||||||
memcpy(value, buf + k + 12, af == AF_INET6? 16:4);
|
|
||||||
if(ttl < 0 || ttl > (3600*12)) ttl = 3600*12;
|
|
||||||
if(!ttl) ttl = 1;
|
|
||||||
hashadd(af == AF_INET6?&dns6_table:&dns_table, name, value, conf.time+ttl);
|
|
||||||
if(retttl) *retttl = ttl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
if(buf[k+2] != 0 || buf[k+3] != 0x0c) {
|
|
||||||
k+= (12 + flen);
|
|
||||||
continue; /* we need A PTR */
|
|
||||||
}
|
|
||||||
for (s2 = buf + k + 12; s2 < (buf + k + 12 + len) && *s2; ){
|
|
||||||
s1 = s2 + ((unsigned)*s2) + 1;
|
|
||||||
*s2 = '.';
|
|
||||||
s2 = s1;
|
|
||||||
}
|
|
||||||
*s2 = 0;
|
|
||||||
if(param->username)myfree(param->username);
|
|
||||||
param->username = (unsigned char *)mystrdup ((char *)buf + k + 13);
|
|
||||||
|
|
||||||
return udpresolve(af,param->username, value, NULL, NULL, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t myresolver(int af, unsigned char * name, unsigned char * value){
|
|
||||||
return udpresolve(af, name, value, NULL, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fakeresolver (int af, unsigned char *name, unsigned char * value){
|
|
||||||
memset(value, 0, af == AF_INET6? 16 : 4);
|
|
||||||
if(af == AF_INET6){
|
|
||||||
memset(value, 0, 16);
|
|
||||||
value[15] = 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
value[0] = 127;
|
|
||||||
value[1] = 0;
|
|
||||||
value[2] = 0;
|
|
||||||
value[3] = 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NOODBC
|
|
||||||
|
|
||||||
SQLHENV henv = NULL;
|
|
||||||
SQLHSTMT hstmt = NULL;
|
|
||||||
SQLHDBC hdbc = NULL;
|
|
||||||
char * sqlstring = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
void close_sql(){
|
|
||||||
if(hstmt) {
|
|
||||||
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
|
||||||
hstmt = NULL;
|
|
||||||
}
|
|
||||||
if(hdbc){
|
|
||||||
SQLDisconnect(hdbc);
|
|
||||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
|
||||||
hdbc = NULL;
|
|
||||||
}
|
|
||||||
if(henv) {
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
|
||||||
henv = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int attempt = 0;
|
|
||||||
time_t attempt_time = 0;
|
|
||||||
|
|
||||||
int init_sql(char * s){
|
|
||||||
SQLRETURN retcode;
|
|
||||||
char * datasource;
|
|
||||||
char * username;
|
|
||||||
char * password;
|
|
||||||
char * string;
|
|
||||||
|
|
||||||
if(!s) return 0;
|
|
||||||
if(!sqlstring || strcmp(sqlstring, s)){
|
|
||||||
string = sqlstring;
|
|
||||||
sqlstring=mystrdup(s);
|
|
||||||
if(string)myfree(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hstmt || hdbc || henv) close_sql();
|
|
||||||
attempt++;
|
|
||||||
attempt_time = time(0);
|
|
||||||
if(!henv){
|
|
||||||
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
|
||||||
if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
|
|
||||||
henv = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
|
|
||||||
|
|
||||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!hdbc){
|
|
||||||
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
|
||||||
if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
|
|
||||||
hdbc = NULL;
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
|
||||||
henv = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
|
|
||||||
}
|
|
||||||
string = mystrdup(sqlstring);
|
|
||||||
if(!string) return 0;
|
|
||||||
datasource = strtok(string, ",");
|
|
||||||
username = strtok(NULL, ",");
|
|
||||||
password = strtok(NULL, ",");
|
|
||||||
|
|
||||||
|
|
||||||
/* Connect to data source */
|
|
||||||
retcode = SQLConnect(hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
|
|
||||||
(SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
|
|
||||||
(SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
|
|
||||||
|
|
||||||
myfree(string);
|
|
||||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
|
||||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
|
||||||
hdbc = NULL;
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
|
||||||
henv = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
|
||||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
|
||||||
close_sql();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sqlerr (char *buf){
|
|
||||||
if(conf.stdlog){
|
|
||||||
fprintf(conf.stdlog, "%s\n", buf);
|
|
||||||
fflush(conf.stdlog);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&log_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char statbuf[8192];
|
|
||||||
|
|
||||||
void logsql(struct clientparam * param, const unsigned char *s) {
|
|
||||||
SQLRETURN ret;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
|
|
||||||
if(param->nolog) return;
|
|
||||||
pthread_mutex_lock(&log_mutex);
|
|
||||||
len = dobuf(param, statbuf, s, (unsigned char *)"\'");
|
|
||||||
|
|
||||||
if(attempt > 5){
|
|
||||||
time_t t;
|
|
||||||
|
|
||||||
t = time(0);
|
|
||||||
if (t - attempt_time < 180){
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!hstmt){
|
|
||||||
if(!init_sql(sqlstring)) {
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(hstmt){
|
|
||||||
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
|
||||||
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
|
||||||
close_sql();
|
|
||||||
if(!init_sql(sqlstring)){
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(hstmt) {
|
|
||||||
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
|
||||||
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
attempt = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attempt = 0;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&log_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
199
src/hash.c
Normal file
199
src/hash.c
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
#include "proxy.h"
|
||||||
|
#include "libs/blake2.h"
|
||||||
|
|
||||||
|
static uint32_t hashindex(struct hashtable *ht, const uint8_t* hash){
|
||||||
|
return (*(unsigned *)hash ) % (ht->tablesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void destroyhashtable(struct hashtable *ht){
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(ht->ihashtable){
|
||||||
|
myfree(ht->ihashtable);
|
||||||
|
ht->ihashtable = NULL;
|
||||||
|
}
|
||||||
|
if(ht->hashvalues){
|
||||||
|
myfree(ht->hashvalues);
|
||||||
|
ht->hashvalues = NULL;
|
||||||
|
}
|
||||||
|
ht->hashsize = 0;
|
||||||
|
ht->tablesize = 0;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I-1)*(sizeof(struct hashentry) + ht->recsize - 4)))
|
||||||
|
|
||||||
|
int inithashtable(struct hashtable *ht, unsigned nhashsize){
|
||||||
|
unsigned i;
|
||||||
|
unsigned tablesize, hashsize;
|
||||||
|
clock_t c;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
struct timeb tb;
|
||||||
|
|
||||||
|
ftime(&tb);
|
||||||
|
|
||||||
|
#else
|
||||||
|
struct timeval tb;
|
||||||
|
struct timezone tz;
|
||||||
|
gettimeofday(&tb, &tz);
|
||||||
|
#endif
|
||||||
|
c = clock();
|
||||||
|
|
||||||
|
hashsize = tablesize = (nhashsize >> 2);
|
||||||
|
if(tablesize < 2) return 1;
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(ht->ihashtable){
|
||||||
|
myfree(ht->ihashtable);
|
||||||
|
ht->ihashtable = NULL;
|
||||||
|
}
|
||||||
|
if(ht->hashvalues){
|
||||||
|
myfree(ht->hashvalues);
|
||||||
|
ht->hashvalues = NULL;
|
||||||
|
}
|
||||||
|
ht->hashsize = 0;
|
||||||
|
ht->tablesize = 0;
|
||||||
|
if(!(ht->ihashtable = myalloc(tablesize * sizeof(uint32_t)))){
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if(!(ht->hashvalues = myalloc(hashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
|
||||||
|
myfree(ht->ihashtable);
|
||||||
|
ht->ihashtable = NULL;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
ht->hashsize = hashsize;
|
||||||
|
ht->tablesize = tablesize;
|
||||||
|
ht->growlimit = nhashsize;
|
||||||
|
ht->rnd[0] = myrand(&tb, sizeof(tb));
|
||||||
|
ht->rnd[1] = myrand(ht->ihashtable, sizeof(ht->ihashtable));
|
||||||
|
ht->rnd[2] = myrand(&c, sizeof(c));
|
||||||
|
ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
|
||||||
|
memset(ht->ihashtable, 0, ht->tablesize * sizeof(struct hashentry *));
|
||||||
|
memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize - 4));
|
||||||
|
|
||||||
|
for(i = 1; i < ht->hashsize; i++) {
|
||||||
|
hvalue(ht,i)->inext = i+1;
|
||||||
|
}
|
||||||
|
ht->ihashempty = 1;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hashgrow(struct hashtable *ht){
|
||||||
|
unsigned newsize = (ht->hashsize + (ht->hashsize >> 1));
|
||||||
|
unsigned i;
|
||||||
|
void * newvalues;
|
||||||
|
|
||||||
|
if(!ht->tablesize || !ht->hashsize) return;
|
||||||
|
if(ht->hashsize >= ht->growlimit) return;
|
||||||
|
if(ht->hashsize / ht->tablesize > 100) return;
|
||||||
|
if(newsize > ht->growlimit) newsize = ht->growlimit;
|
||||||
|
newvalues = myrealloc(ht->hashvalues, newsize * (sizeof(struct hashentry) + ht->recsize - 4));
|
||||||
|
if(!newvalues) return;
|
||||||
|
memset(ht->hashvalues + (ht->hashsize * (sizeof(struct hashentry) + ht->recsize - 4)), 0, (newsize - ht->hashsize) * (sizeof(struct hashentry) + ht->recsize - 4));
|
||||||
|
for(i = ht->hashsize + 1; i < newsize; i++) {
|
||||||
|
hvalue(ht,i)->inext = i+1;
|
||||||
|
}
|
||||||
|
hvalue(ht,newsize)->inext = ht->ihashempty;
|
||||||
|
ht->ihashempty = ht->hashsize + 1;
|
||||||
|
ht->hashsize = newsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static void hashcompact(struct hashtable *ht){
|
||||||
|
int i;
|
||||||
|
uint32_t he, *hep;
|
||||||
|
|
||||||
|
if((conf.time - ht->compacted) < 60 || !ht->tablesize || !ht->hashsize || ht->ihashempty) return;
|
||||||
|
if(ht->grow && ht->hashsize/ht->tablesize < 100){
|
||||||
|
hashgrow(ht);
|
||||||
|
if(ht->ihashempty) return;
|
||||||
|
}
|
||||||
|
if(ht->hashsize/ht->tablesize < 4){
|
||||||
|
for(i = 0; i < ht->tablesize; i++){
|
||||||
|
for(hep = ht->ihashtable + i; (he = *hep) != 0; ){
|
||||||
|
if(hvalue(ht,he)->expires < conf.time ) {
|
||||||
|
(*hep) = hvalue(ht,he)->inext;
|
||||||
|
hvalue(ht,he)->expires = 0;
|
||||||
|
hvalue(ht,he)->inext = ht->ihashempty;
|
||||||
|
ht->ihashempty = he;
|
||||||
|
}
|
||||||
|
else hep=&(hvalue(ht,he)->inext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ht->compacted = conf.time;
|
||||||
|
if(ht->ihashempty) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires){
|
||||||
|
uint32_t hen, he;
|
||||||
|
uint32_t *hep;
|
||||||
|
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(!ht->ihashempty){
|
||||||
|
hashgrow(ht);
|
||||||
|
}
|
||||||
|
if(!ht||!value||!name||!ht->ihashtable||!ht->ihashempty) {
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hen = ht->ihashempty;
|
||||||
|
ht->ihashempty = hvalue(ht,ht->ihashempty)->inext;
|
||||||
|
ht->index2hash(name, hvalue(ht,hen)->hash, (unsigned char *)ht->rnd);
|
||||||
|
memcpy(hvalue(ht,hen)->value, value, ht->recsize);
|
||||||
|
hvalue(ht,hen)->expires = expires;
|
||||||
|
hvalue(ht,hen)->inext = 0;
|
||||||
|
index = hashindex(ht, hvalue(ht,hen)->hash);
|
||||||
|
|
||||||
|
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
|
||||||
|
if(hvalue(ht,he)->expires < conf.time || !memcmp(hvalue(ht,hen)->hash, hvalue(ht,he)->hash, HASH_SIZE)) {
|
||||||
|
(*hep) = hvalue(ht,he)->inext;
|
||||||
|
hvalue(ht,he)->expires = 0;
|
||||||
|
hvalue(ht,he)->inext = ht->ihashempty;
|
||||||
|
ht->ihashempty = he;
|
||||||
|
}
|
||||||
|
else hep=&(hvalue(ht,he)->inext);
|
||||||
|
}
|
||||||
|
hvalue(ht,hen)->inext = ht->ihashtable[index];
|
||||||
|
ht->ihashtable[index] = hen;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl){
|
||||||
|
uint8_t hash[HASH_SIZE];
|
||||||
|
uint32_t *hep;
|
||||||
|
uint32_t he;
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(!ht || !ht->ihashtable || !name) {
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ht->index2hash(name, hash, (unsigned char *)ht->rnd);
|
||||||
|
index = hashindex(ht, hash);
|
||||||
|
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
|
||||||
|
if(hvalue(ht, he)->expires < conf.time) {
|
||||||
|
(*hep) = hvalue(ht,he)->inext;
|
||||||
|
hvalue(ht,he)->expires = 0;
|
||||||
|
hvalue(ht,he)->inext = ht->ihashempty;
|
||||||
|
ht->ihashempty = he;
|
||||||
|
}
|
||||||
|
else if(!memcmp(hash, hvalue(ht,he)->hash, HASH_SIZE)){
|
||||||
|
if(ttl) *ttl = (uint32_t)(hvalue(ht,he)->expires - conf.time);
|
||||||
|
memcpy(value, hvalue(ht,he)->value, ht->recsize);
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else hep=&(hvalue(ht,he)->inext);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
160
src/libs/blake2-impl.h
Normal file
160
src/libs/blake2-impl.h
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - reference C implementations
|
||||||
|
|
||||||
|
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||||
|
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||||
|
your option. The terms of these licenses can be found at:
|
||||||
|
|
||||||
|
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||||
|
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||||
|
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
More information about the BLAKE2 hash function can be found at
|
||||||
|
https://blake2.net.
|
||||||
|
*/
|
||||||
|
#ifndef BLAKE2_IMPL_H
|
||||||
|
#define BLAKE2_IMPL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define BLAKE2_INLINE __inline
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define BLAKE2_INLINE __inline__
|
||||||
|
#else
|
||||||
|
#define BLAKE2_INLINE
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define BLAKE2_INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static BLAKE2_INLINE uint32_t load32( const void *src )
|
||||||
|
{
|
||||||
|
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||||
|
uint32_t w;
|
||||||
|
memcpy(&w, src, sizeof w);
|
||||||
|
return w;
|
||||||
|
#else
|
||||||
|
const uint8_t *p = ( const uint8_t * )src;
|
||||||
|
return (( uint32_t )( p[0] ) << 0) |
|
||||||
|
(( uint32_t )( p[1] ) << 8) |
|
||||||
|
(( uint32_t )( p[2] ) << 16) |
|
||||||
|
(( uint32_t )( p[3] ) << 24) ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE uint64_t load64( const void *src )
|
||||||
|
{
|
||||||
|
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||||
|
uint64_t w;
|
||||||
|
memcpy(&w, src, sizeof w);
|
||||||
|
return w;
|
||||||
|
#else
|
||||||
|
const uint8_t *p = ( const uint8_t * )src;
|
||||||
|
return (( uint64_t )( p[0] ) << 0) |
|
||||||
|
(( uint64_t )( p[1] ) << 8) |
|
||||||
|
(( uint64_t )( p[2] ) << 16) |
|
||||||
|
(( uint64_t )( p[3] ) << 24) |
|
||||||
|
(( uint64_t )( p[4] ) << 32) |
|
||||||
|
(( uint64_t )( p[5] ) << 40) |
|
||||||
|
(( uint64_t )( p[6] ) << 48) |
|
||||||
|
(( uint64_t )( p[7] ) << 56) ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE uint16_t load16( const void *src )
|
||||||
|
{
|
||||||
|
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||||
|
uint16_t w;
|
||||||
|
memcpy(&w, src, sizeof w);
|
||||||
|
return w;
|
||||||
|
#else
|
||||||
|
const uint8_t *p = ( const uint8_t * )src;
|
||||||
|
return ( uint16_t )((( uint32_t )( p[0] ) << 0) |
|
||||||
|
(( uint32_t )( p[1] ) << 8));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE void store16( void *dst, uint16_t w )
|
||||||
|
{
|
||||||
|
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||||
|
memcpy(dst, &w, sizeof w);
|
||||||
|
#else
|
||||||
|
uint8_t *p = ( uint8_t * )dst;
|
||||||
|
*p++ = ( uint8_t )w; w >>= 8;
|
||||||
|
*p++ = ( uint8_t )w;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE void store32( void *dst, uint32_t w )
|
||||||
|
{
|
||||||
|
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||||
|
memcpy(dst, &w, sizeof w);
|
||||||
|
#else
|
||||||
|
uint8_t *p = ( uint8_t * )dst;
|
||||||
|
p[0] = (uint8_t)(w >> 0);
|
||||||
|
p[1] = (uint8_t)(w >> 8);
|
||||||
|
p[2] = (uint8_t)(w >> 16);
|
||||||
|
p[3] = (uint8_t)(w >> 24);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE void store64( void *dst, uint64_t w )
|
||||||
|
{
|
||||||
|
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||||
|
memcpy(dst, &w, sizeof w);
|
||||||
|
#else
|
||||||
|
uint8_t *p = ( uint8_t * )dst;
|
||||||
|
p[0] = (uint8_t)(w >> 0);
|
||||||
|
p[1] = (uint8_t)(w >> 8);
|
||||||
|
p[2] = (uint8_t)(w >> 16);
|
||||||
|
p[3] = (uint8_t)(w >> 24);
|
||||||
|
p[4] = (uint8_t)(w >> 32);
|
||||||
|
p[5] = (uint8_t)(w >> 40);
|
||||||
|
p[6] = (uint8_t)(w >> 48);
|
||||||
|
p[7] = (uint8_t)(w >> 56);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE uint64_t load48( const void *src )
|
||||||
|
{
|
||||||
|
const uint8_t *p = ( const uint8_t * )src;
|
||||||
|
return (( uint64_t )( p[0] ) << 0) |
|
||||||
|
(( uint64_t )( p[1] ) << 8) |
|
||||||
|
(( uint64_t )( p[2] ) << 16) |
|
||||||
|
(( uint64_t )( p[3] ) << 24) |
|
||||||
|
(( uint64_t )( p[4] ) << 32) |
|
||||||
|
(( uint64_t )( p[5] ) << 40) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE void store48( void *dst, uint64_t w )
|
||||||
|
{
|
||||||
|
uint8_t *p = ( uint8_t * )dst;
|
||||||
|
p[0] = (uint8_t)(w >> 0);
|
||||||
|
p[1] = (uint8_t)(w >> 8);
|
||||||
|
p[2] = (uint8_t)(w >> 16);
|
||||||
|
p[3] = (uint8_t)(w >> 24);
|
||||||
|
p[4] = (uint8_t)(w >> 32);
|
||||||
|
p[5] = (uint8_t)(w >> 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
|
||||||
|
{
|
||||||
|
return ( w >> c ) | ( w << ( 32 - c ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
|
||||||
|
{
|
||||||
|
return ( w >> c ) | ( w << ( 64 - c ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prevents compiler optimizing out memset() */
|
||||||
|
static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
|
||||||
|
{
|
||||||
|
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
|
||||||
|
memset_v(v, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
195
src/libs/blake2.h
Normal file
195
src/libs/blake2.h
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - reference C implementations
|
||||||
|
|
||||||
|
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||||
|
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||||
|
your option. The terms of these licenses can be found at:
|
||||||
|
|
||||||
|
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||||
|
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||||
|
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
More information about the BLAKE2 hash function can be found at
|
||||||
|
https://blake2.net.
|
||||||
|
*/
|
||||||
|
#ifndef BLAKE2_H
|
||||||
|
#define BLAKE2_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
|
||||||
|
#else
|
||||||
|
#define BLAKE2_PACKED(x) x __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum blake2s_constant
|
||||||
|
{
|
||||||
|
BLAKE2S_BLOCKBYTES = 64,
|
||||||
|
BLAKE2S_OUTBYTES = 32,
|
||||||
|
BLAKE2S_KEYBYTES = 32,
|
||||||
|
BLAKE2S_SALTBYTES = 8,
|
||||||
|
BLAKE2S_PERSONALBYTES = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
enum blake2b_constant
|
||||||
|
{
|
||||||
|
BLAKE2B_BLOCKBYTES = 128,
|
||||||
|
BLAKE2B_OUTBYTES = 64,
|
||||||
|
BLAKE2B_KEYBYTES = 64,
|
||||||
|
BLAKE2B_SALTBYTES = 16,
|
||||||
|
BLAKE2B_PERSONALBYTES = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct blake2s_state__
|
||||||
|
{
|
||||||
|
uint32_t h[8];
|
||||||
|
uint32_t t[2];
|
||||||
|
uint32_t f[2];
|
||||||
|
uint8_t buf[BLAKE2S_BLOCKBYTES];
|
||||||
|
size_t buflen;
|
||||||
|
size_t outlen;
|
||||||
|
uint8_t last_node;
|
||||||
|
} blake2s_state;
|
||||||
|
|
||||||
|
typedef struct blake2b_state__
|
||||||
|
{
|
||||||
|
uint64_t h[8];
|
||||||
|
uint64_t t[2];
|
||||||
|
uint64_t f[2];
|
||||||
|
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||||
|
size_t buflen;
|
||||||
|
size_t outlen;
|
||||||
|
uint8_t last_node;
|
||||||
|
} blake2b_state;
|
||||||
|
|
||||||
|
typedef struct blake2sp_state__
|
||||||
|
{
|
||||||
|
blake2s_state S[8][1];
|
||||||
|
blake2s_state R[1];
|
||||||
|
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
||||||
|
size_t buflen;
|
||||||
|
size_t outlen;
|
||||||
|
} blake2sp_state;
|
||||||
|
|
||||||
|
typedef struct blake2bp_state__
|
||||||
|
{
|
||||||
|
blake2b_state S[4][1];
|
||||||
|
blake2b_state R[1];
|
||||||
|
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
||||||
|
size_t buflen;
|
||||||
|
size_t outlen;
|
||||||
|
} blake2bp_state;
|
||||||
|
|
||||||
|
|
||||||
|
BLAKE2_PACKED(struct blake2s_param__
|
||||||
|
{
|
||||||
|
uint8_t digest_length; /* 1 */
|
||||||
|
uint8_t key_length; /* 2 */
|
||||||
|
uint8_t fanout; /* 3 */
|
||||||
|
uint8_t depth; /* 4 */
|
||||||
|
uint32_t leaf_length; /* 8 */
|
||||||
|
uint32_t node_offset; /* 12 */
|
||||||
|
uint16_t xof_length; /* 14 */
|
||||||
|
uint8_t node_depth; /* 15 */
|
||||||
|
uint8_t inner_length; /* 16 */
|
||||||
|
/* uint8_t reserved[0]; */
|
||||||
|
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
|
||||||
|
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
|
||||||
|
});
|
||||||
|
|
||||||
|
typedef struct blake2s_param__ blake2s_param;
|
||||||
|
|
||||||
|
BLAKE2_PACKED(struct blake2b_param__
|
||||||
|
{
|
||||||
|
uint8_t digest_length; /* 1 */
|
||||||
|
uint8_t key_length; /* 2 */
|
||||||
|
uint8_t fanout; /* 3 */
|
||||||
|
uint8_t depth; /* 4 */
|
||||||
|
uint32_t leaf_length; /* 8 */
|
||||||
|
uint32_t node_offset; /* 12 */
|
||||||
|
uint32_t xof_length; /* 16 */
|
||||||
|
uint8_t node_depth; /* 17 */
|
||||||
|
uint8_t inner_length; /* 18 */
|
||||||
|
uint8_t reserved[14]; /* 32 */
|
||||||
|
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
|
||||||
|
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
|
||||||
|
});
|
||||||
|
|
||||||
|
typedef struct blake2b_param__ blake2b_param;
|
||||||
|
|
||||||
|
typedef struct blake2xs_state__
|
||||||
|
{
|
||||||
|
blake2s_state S[1];
|
||||||
|
blake2s_param P[1];
|
||||||
|
} blake2xs_state;
|
||||||
|
|
||||||
|
typedef struct blake2xb_state__
|
||||||
|
{
|
||||||
|
blake2b_state S[1];
|
||||||
|
blake2b_param P[1];
|
||||||
|
} blake2xb_state;
|
||||||
|
|
||||||
|
/* Padded structs result in a compile-time error */
|
||||||
|
enum {
|
||||||
|
BLAKE2_DUMMY_1 = 1/(int)(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),
|
||||||
|
BLAKE2_DUMMY_2 = 1/(int)(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Streaming API */
|
||||||
|
int blake2s_init( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update( blake2s_state *S, const void *in, size_t inlen );
|
||||||
|
int blake2s_final( blake2s_state *S, void *out, size_t outlen );
|
||||||
|
|
||||||
|
int blake2b_init( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update( blake2b_state *S, const void *in, size_t inlen );
|
||||||
|
int blake2b_final( blake2b_state *S, void *out, size_t outlen );
|
||||||
|
|
||||||
|
int blake2sp_init( blake2sp_state *S, size_t outlen );
|
||||||
|
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );
|
||||||
|
int blake2sp_final( blake2sp_state *S, void *out, size_t outlen );
|
||||||
|
|
||||||
|
int blake2bp_init( blake2bp_state *S, size_t outlen );
|
||||||
|
int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );
|
||||||
|
int blake2bp_final( blake2bp_state *S, void *out, size_t outlen );
|
||||||
|
|
||||||
|
/* Variable output length API */
|
||||||
|
int blake2xs_init( blake2xs_state *S, const size_t outlen );
|
||||||
|
int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );
|
||||||
|
int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);
|
||||||
|
|
||||||
|
int blake2xb_init( blake2xb_state *S, const size_t outlen );
|
||||||
|
int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );
|
||||||
|
int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);
|
||||||
|
|
||||||
|
/* Simple API */
|
||||||
|
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||||
|
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||||
|
|
||||||
|
int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||||
|
int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||||
|
|
||||||
|
int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||||
|
int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||||
|
|
||||||
|
/* This is simply an alias for blake2b */
|
||||||
|
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
379
src/libs/blake2b-ref.c
Normal file
379
src/libs/blake2b-ref.c
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - reference C implementations
|
||||||
|
|
||||||
|
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||||
|
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||||
|
your option. The terms of these licenses can be found at:
|
||||||
|
|
||||||
|
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||||
|
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||||
|
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
More information about the BLAKE2 hash function can be found at
|
||||||
|
https://blake2.net.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "blake2.h"
|
||||||
|
#include "blake2-impl.h"
|
||||||
|
|
||||||
|
static const uint64_t blake2b_IV[8] =
|
||||||
|
{
|
||||||
|
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
|
||||||
|
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
|
||||||
|
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||||
|
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t blake2b_sigma[12][16] =
|
||||||
|
{
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||||
|
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||||
|
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||||
|
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||||
|
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||||
|
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||||
|
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||||
|
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||||
|
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||||
|
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||||
|
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void blake2b_set_lastnode( blake2b_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = (uint64_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some helper functions, not necessarily useful */
|
||||||
|
static int blake2b_is_lastblock( const blake2b_state *S )
|
||||||
|
{
|
||||||
|
return S->f[0] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blake2b_set_lastblock( blake2b_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2b_set_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = (uint64_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
|
||||||
|
{
|
||||||
|
S->t[0] += inc;
|
||||||
|
S->t[1] += ( S->t[0] < inc );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blake2b_init0( blake2b_state *S )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
memset( S, 0, sizeof( blake2b_state ) );
|
||||||
|
|
||||||
|
for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init xors IV with input parameter block */
|
||||||
|
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
|
||||||
|
{
|
||||||
|
const uint8_t *p = ( const uint8_t * )( P );
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
blake2b_init0( S );
|
||||||
|
|
||||||
|
/* IV XOR ParamBlock */
|
||||||
|
for( i = 0; i < 8; ++i )
|
||||||
|
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
|
||||||
|
|
||||||
|
S->outlen = P->digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int blake2b_init( blake2b_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
blake2b_param P[1];
|
||||||
|
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
P->digest_length = (uint8_t)outlen;
|
||||||
|
P->key_length = 0;
|
||||||
|
P->fanout = 1;
|
||||||
|
P->depth = 1;
|
||||||
|
store32( &P->leaf_length, 0 );
|
||||||
|
store32( &P->node_offset, 0 );
|
||||||
|
store32( &P->xof_length, 0 );
|
||||||
|
P->node_depth = 0;
|
||||||
|
P->inner_length = 0;
|
||||||
|
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||||
|
memset( P->salt, 0, sizeof( P->salt ) );
|
||||||
|
memset( P->personal, 0, sizeof( P->personal ) );
|
||||||
|
return blake2b_init_param( S, P );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2b_param P[1];
|
||||||
|
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
P->digest_length = (uint8_t)outlen;
|
||||||
|
P->key_length = (uint8_t)keylen;
|
||||||
|
P->fanout = 1;
|
||||||
|
P->depth = 1;
|
||||||
|
store32( &P->leaf_length, 0 );
|
||||||
|
store32( &P->node_offset, 0 );
|
||||||
|
store32( &P->xof_length, 0 );
|
||||||
|
P->node_depth = 0;
|
||||||
|
P->inner_length = 0;
|
||||||
|
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||||
|
memset( P->salt, 0, sizeof( P->salt ) );
|
||||||
|
memset( P->personal, 0, sizeof( P->personal ) );
|
||||||
|
|
||||||
|
if( blake2b_init_param( S, P ) < 0 ) return -1;
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||||
|
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||||
|
memcpy( block, key, keylen );
|
||||||
|
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
|
||||||
|
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define G(r,i,a,b,c,d) \
|
||||||
|
do { \
|
||||||
|
a = a + b + m[blake2b_sigma[r][2*i+0]]; \
|
||||||
|
d = rotr64(d ^ a, 32); \
|
||||||
|
c = c + d; \
|
||||||
|
b = rotr64(b ^ c, 24); \
|
||||||
|
a = a + b + m[blake2b_sigma[r][2*i+1]]; \
|
||||||
|
d = rotr64(d ^ a, 16); \
|
||||||
|
c = c + d; \
|
||||||
|
b = rotr64(b ^ c, 63); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define ROUND(r) \
|
||||||
|
do { \
|
||||||
|
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||||
|
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||||
|
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||||
|
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||||
|
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||||
|
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||||
|
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||||
|
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
|
||||||
|
{
|
||||||
|
uint64_t m[16];
|
||||||
|
uint64_t v[16];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for( i = 0; i < 16; ++i ) {
|
||||||
|
m[i] = load64( block + i * sizeof( m[i] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < 8; ++i ) {
|
||||||
|
v[i] = S->h[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
v[ 8] = blake2b_IV[0];
|
||||||
|
v[ 9] = blake2b_IV[1];
|
||||||
|
v[10] = blake2b_IV[2];
|
||||||
|
v[11] = blake2b_IV[3];
|
||||||
|
v[12] = blake2b_IV[4] ^ S->t[0];
|
||||||
|
v[13] = blake2b_IV[5] ^ S->t[1];
|
||||||
|
v[14] = blake2b_IV[6] ^ S->f[0];
|
||||||
|
v[15] = blake2b_IV[7] ^ S->f[1];
|
||||||
|
|
||||||
|
ROUND( 0 );
|
||||||
|
ROUND( 1 );
|
||||||
|
ROUND( 2 );
|
||||||
|
ROUND( 3 );
|
||||||
|
ROUND( 4 );
|
||||||
|
ROUND( 5 );
|
||||||
|
ROUND( 6 );
|
||||||
|
ROUND( 7 );
|
||||||
|
ROUND( 8 );
|
||||||
|
ROUND( 9 );
|
||||||
|
ROUND( 10 );
|
||||||
|
ROUND( 11 );
|
||||||
|
|
||||||
|
for( i = 0; i < 8; ++i ) {
|
||||||
|
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef G
|
||||||
|
#undef ROUND
|
||||||
|
|
||||||
|
int blake2b_update( blake2b_state *S, const void *pin, size_t inlen )
|
||||||
|
{
|
||||||
|
const unsigned char * in = (const unsigned char *)pin;
|
||||||
|
if( inlen > 0 )
|
||||||
|
{
|
||||||
|
size_t left = S->buflen;
|
||||||
|
size_t fill = BLAKE2B_BLOCKBYTES - left;
|
||||||
|
if( inlen > fill )
|
||||||
|
{
|
||||||
|
S->buflen = 0;
|
||||||
|
memcpy( S->buf + left, in, fill ); /* Fill buffer */
|
||||||
|
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||||
|
blake2b_compress( S, S->buf ); /* Compress */
|
||||||
|
in += fill; inlen -= fill;
|
||||||
|
while(inlen > BLAKE2B_BLOCKBYTES) {
|
||||||
|
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||||
|
blake2b_compress( S, in );
|
||||||
|
in += BLAKE2B_BLOCKBYTES;
|
||||||
|
inlen -= BLAKE2B_BLOCKBYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy( S->buf + S->buflen, in, inlen );
|
||||||
|
S->buflen += inlen;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_final( blake2b_state *S, void *out, size_t outlen )
|
||||||
|
{
|
||||||
|
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if( out == NULL || outlen < S->outlen )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if( blake2b_is_lastblock( S ) )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
blake2b_increment_counter( S, S->buflen );
|
||||||
|
blake2b_set_lastblock( S );
|
||||||
|
memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
|
||||||
|
blake2b_compress( S, S->buf );
|
||||||
|
|
||||||
|
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||||
|
store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||||
|
|
||||||
|
memcpy( out, buffer, S->outlen );
|
||||||
|
secure_zero_memory(buffer, sizeof(buffer));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* inlen, at least, should be uint64_t. Others can be size_t. */
|
||||||
|
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2b_state S[1];
|
||||||
|
|
||||||
|
/* Verify parameters */
|
||||||
|
if ( NULL == in && inlen > 0 ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == out ) return -1;
|
||||||
|
|
||||||
|
if( NULL == key && keylen > 0 ) return -1;
|
||||||
|
|
||||||
|
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||||
|
|
||||||
|
if( keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
if( keylen > 0 )
|
||||||
|
{
|
||||||
|
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( blake2b_init( S, outlen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
blake2b_update( S, ( const uint8_t * )in, inlen );
|
||||||
|
blake2b_final( S, out, outlen );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {
|
||||||
|
return blake2b(out, outlen, in, inlen, key, keylen);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SUPERCOP)
|
||||||
|
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
|
||||||
|
{
|
||||||
|
return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BLAKE2B_SELFTEST)
|
||||||
|
#include <string.h>
|
||||||
|
#include "blake2-kat.h"
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
uint8_t key[BLAKE2B_KEYBYTES];
|
||||||
|
uint8_t buf[BLAKE2_KAT_LENGTH];
|
||||||
|
size_t i, step;
|
||||||
|
|
||||||
|
for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
|
||||||
|
key[i] = ( uint8_t )i;
|
||||||
|
|
||||||
|
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||||
|
buf[i] = ( uint8_t )i;
|
||||||
|
|
||||||
|
/* Test simple API */
|
||||||
|
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||||
|
{
|
||||||
|
uint8_t hash[BLAKE2B_OUTBYTES];
|
||||||
|
blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES );
|
||||||
|
|
||||||
|
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
|
||||||
|
{
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test streaming API */
|
||||||
|
for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {
|
||||||
|
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
|
||||||
|
uint8_t hash[BLAKE2B_OUTBYTES];
|
||||||
|
blake2b_state S;
|
||||||
|
uint8_t * p = buf;
|
||||||
|
size_t mlen = i;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mlen >= step) {
|
||||||
|
if ( (err = blake2b_update(&S, p, step)) < 0 ) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
mlen -= step;
|
||||||
|
p += step;
|
||||||
|
}
|
||||||
|
if ( (err = blake2b_update(&S, p, mlen)) < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts( "ok" );
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
puts("error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -11,8 +11,6 @@
|
|||||||
unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout);
|
unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout);
|
||||||
void trafcountfunc(struct clientparam *param);
|
void trafcountfunc(struct clientparam *param);
|
||||||
int checkACL(struct clientparam * param);
|
int checkACL(struct clientparam * param);
|
||||||
void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd);
|
|
||||||
unsigned hashindex(struct hashtable *ht, const unsigned char* hash);
|
|
||||||
void decodeurl(unsigned char *s, int allowcr);
|
void decodeurl(unsigned char *s, int allowcr);
|
||||||
int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize);
|
int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize);
|
||||||
struct ace * make_ace (int argc, unsigned char ** argv);
|
struct ace * make_ace (int argc, unsigned char ** argv);
|
||||||
@ -45,38 +43,36 @@ struct symbol symbols[] = {
|
|||||||
{symbols+18, "ipauth", (void *) ipauth},
|
{symbols+18, "ipauth", (void *) ipauth},
|
||||||
{symbols+19, "strongauth", (void *) strongauth},
|
{symbols+19, "strongauth", (void *) strongauth},
|
||||||
{symbols+20, "checkACL", (void *) checkACL},
|
{symbols+20, "checkACL", (void *) checkACL},
|
||||||
{symbols+21, "nametohash", (void *) nametohash},
|
{symbols+21, "nservers", (void *) nservers},
|
||||||
{symbols+22, "hashindex", (void *) hashindex},
|
{symbols+22, "udpresolve", (void *) udpresolve},
|
||||||
{symbols+23, "nservers", (void *) nservers},
|
{symbols+23, "bandlim_mutex", (void *) &bandlim_mutex},
|
||||||
{symbols+24, "udpresolve", (void *) udpresolve},
|
{symbols+24, "tc_mutex", (void *) &tc_mutex},
|
||||||
{symbols+25, "bandlim_mutex", (void *) &bandlim_mutex},
|
{symbols+25, "hash_mutex", (void *) &hash_mutex},
|
||||||
{symbols+26, "tc_mutex", (void *) &tc_mutex},
|
{symbols+26, "pwl_mutex", (void *) &pwl_mutex},
|
||||||
{symbols+27, "hash_mutex", (void *) &hash_mutex},
|
{symbols+27, "linenum", (void *) &linenum},
|
||||||
{symbols+28, "pwl_mutex", (void *) &pwl_mutex},
|
{symbols+28, "proxy_stringtable", (void *) proxy_stringtable},
|
||||||
{symbols+29, "linenum", (void *) &linenum},
|
{symbols+29, "en64", (void *) en64},
|
||||||
{symbols+30, "proxy_stringtable", (void *) proxy_stringtable},
|
{symbols+30, "de64", (void *) de64},
|
||||||
{symbols+31, "en64", (void *) en64},
|
{symbols+31, "tohex", (void *) tohex},
|
||||||
{symbols+32, "de64", (void *) de64},
|
{symbols+32, "fromhex", (void *) fromhex},
|
||||||
{symbols+33, "tohex", (void *) tohex},
|
{symbols+33, "dnspr", (void *) dnsprchild},
|
||||||
{symbols+34, "fromhex", (void *) fromhex},
|
{symbols+34, "pop3p", (void *) pop3pchild},
|
||||||
{symbols+35, "dnspr", (void *) dnsprchild},
|
{symbols+35, "proxy", (void *) proxychild},
|
||||||
{symbols+36, "pop3p", (void *) pop3pchild},
|
{symbols+36, "socks", (void *) sockschild},
|
||||||
{symbols+37, "proxy", (void *) proxychild},
|
{symbols+37, "tcppm", (void *) tcppmchild},
|
||||||
{symbols+38, "socks", (void *) sockschild},
|
{symbols+38, "udppm", (void *) udppmchild},
|
||||||
{symbols+39, "tcppm", (void *) tcppmchild},
|
{symbols+39, "admin", (void *) adminchild},
|
||||||
{symbols+40, "udppm", (void *) udppmchild},
|
{symbols+40, "ftppr", (void *) ftpprchild},
|
||||||
{symbols+41, "admin", (void *) adminchild},
|
{symbols+41, "smtpp", (void *) smtppchild},
|
||||||
{symbols+42, "ftppr", (void *) ftpprchild},
|
{symbols+42, "auto", (void *) smtppchild},
|
||||||
{symbols+43, "smtpp", (void *) smtppchild},
|
{symbols+43, "tlspr", (void *) smtppchild},
|
||||||
{symbols+44, "auto", (void *) smtppchild},
|
{symbols+44, "authfuncs", (void *) &authfuncs},
|
||||||
{symbols+45, "tlspr", (void *) smtppchild},
|
{symbols+45, "commandhandlers", (void *) &commandhandlers},
|
||||||
{symbols+46, "authfuncs", (void *) &authfuncs},
|
{symbols+46, "decodeurl", (void *) decodeurl},
|
||||||
{symbols+47, "commandhandlers", (void *) &commandhandlers},
|
{symbols+47, "parsestr", (void *) parsestr},
|
||||||
{symbols+48, "decodeurl", (void *) decodeurl},
|
{symbols+48, "make_ace", (void *) make_ace},
|
||||||
{symbols+49, "parsestr", (void *) parsestr},
|
{symbols+49, "freeacl", (void *) freeacl},
|
||||||
{symbols+50, "make_ace", (void *) make_ace},
|
{symbols+50, "handleredirect", (void *) handleredirect},
|
||||||
{symbols+51, "freeacl", (void *) freeacl},
|
|
||||||
{symbols+52, "handleredirect", (void *) handleredirect},
|
|
||||||
{NULL, "", NULL}
|
{NULL, "", NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -111,8 +107,6 @@ struct pluginlink pluginlink = {
|
|||||||
ACLmatches,
|
ACLmatches,
|
||||||
alwaysauth,
|
alwaysauth,
|
||||||
checkACL,
|
checkACL,
|
||||||
nametohash,
|
|
||||||
hashindex,
|
|
||||||
en64,
|
en64,
|
||||||
de64,
|
de64,
|
||||||
tohex,
|
tohex,
|
||||||
|
|||||||
@ -204,7 +204,6 @@ uint32_t getip46(int family, unsigned char *name, struct sockaddr *sa);
|
|||||||
int afdetect(unsigned char *name);
|
int afdetect(unsigned char *name);
|
||||||
uint32_t myresolver(int, unsigned char *, unsigned char *);
|
uint32_t myresolver(int, unsigned char *, unsigned char *);
|
||||||
uint32_t fakeresolver (int, unsigned char *, unsigned char*);
|
uint32_t fakeresolver (int, unsigned char *, unsigned char*);
|
||||||
int inithashtable(struct hashtable *hashtable, unsigned nhashsize);
|
|
||||||
void freeparam(struct clientparam * param);
|
void freeparam(struct clientparam * param);
|
||||||
void clearstat(struct clientparam * param);
|
void clearstat(struct clientparam * param);
|
||||||
void dumpcounters(struct trafcount *tl, int counterd);
|
void dumpcounters(struct trafcount *tl, int counterd);
|
||||||
@ -244,8 +243,10 @@ void genchallenge(struct clientparam *param, char * challenge, char *buf);
|
|||||||
void mschap(const unsigned char *win_password,
|
void mschap(const unsigned char *win_password,
|
||||||
const unsigned char *challenge, unsigned char *response);
|
const unsigned char *challenge, unsigned char *response);
|
||||||
|
|
||||||
struct hashtable;
|
void destroyhashtable(struct hashtable *ht);
|
||||||
void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires);
|
int inithashtable(struct hashtable *ht, unsigned nhashsize);
|
||||||
|
void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires);
|
||||||
|
int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl);
|
||||||
|
|
||||||
int parsehost(int family, unsigned char *host, struct sockaddr *sa);
|
int parsehost(int family, unsigned char *host, struct sockaddr *sa);
|
||||||
int parsehostname(char *hostname, struct clientparam *param, uint16_t port);
|
int parsehostname(char *hostname, struct clientparam *param, uint16_t port);
|
||||||
|
|||||||
212
src/resolve.c
Normal file
212
src/resolve.c
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
#include "proxy.h"
|
||||||
|
#include "libs/blake2.h"
|
||||||
|
|
||||||
|
|
||||||
|
void char_index2hash(const void *index, uint8_t *hash, const unsigned char *rnd){
|
||||||
|
const char* name = index;
|
||||||
|
|
||||||
|
blake2b(hash, HASH_SIZE, index, strlen((const char*)index), rnd, 4*sizeof(unsigned) );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, 0, char_index2hash};
|
||||||
|
struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, 0, char_index2hash};
|
||||||
|
|
||||||
|
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
||||||
|
struct nserver authnserver;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_t *retttl, struct clientparam* param, int makeauth){
|
||||||
|
|
||||||
|
int i,n;
|
||||||
|
uint32_t retval;
|
||||||
|
|
||||||
|
if((af == AF_INET) && (retval = hashresolv(&dns_table, name, value, retttl))) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
if((af == AF_INET6) && (retval = hashresolv(&dns6_table, name, value, retttl))) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
|
||||||
|
for(i=0; i<n; i++){
|
||||||
|
unsigned short nq, na;
|
||||||
|
unsigned char b[4098], *buf, *s1, *s2;
|
||||||
|
int j, k, len, flen;
|
||||||
|
SOCKET sock;
|
||||||
|
uint32_t ttl;
|
||||||
|
PROXYSOCKADDRTYPE addr;
|
||||||
|
PROXYSOCKADDRTYPE *sinsr, *sinsl;
|
||||||
|
int usetcp = 0;
|
||||||
|
unsigned short serial = 1;
|
||||||
|
|
||||||
|
buf = b+2;
|
||||||
|
|
||||||
|
sinsl = (param && !makeauth)? ¶m->sinsl : &addr;
|
||||||
|
sinsr = (param && !makeauth)? ¶m->sinsr : &addr;
|
||||||
|
memset(sinsl, 0, sizeof(addr));
|
||||||
|
memset(sinsr, 0, sizeof(addr));
|
||||||
|
|
||||||
|
|
||||||
|
if(makeauth && !SAISNULL(&authnserver.addr)){
|
||||||
|
usetcp = authnserver.usetcp;
|
||||||
|
*SAFAMILY(sinsl) = *SAFAMILY(&authnserver.addr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
usetcp = nservers[i].usetcp;
|
||||||
|
*SAFAMILY(sinsl) = *SAFAMILY(&nservers[i].addr);
|
||||||
|
}
|
||||||
|
if((sock=so._socket(so.state, SASOCK(sinsl), usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
|
||||||
|
if(so._bind(so.state, sock,(struct sockaddr *)sinsl,SASIZE(sinsl))){
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(makeauth && !SAISNULL(&authnserver.addr)){
|
||||||
|
*sinsr = authnserver.addr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*sinsr = nservers[i].addr;
|
||||||
|
}
|
||||||
|
if(usetcp){
|
||||||
|
if(connectwithpoll(NULL, sock,(struct sockaddr *)sinsr,SASIZE(sinsr),conf.timeouts[CONNECT_TO])) {
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef TCP_NODELAY
|
||||||
|
{
|
||||||
|
int opt = 1;
|
||||||
|
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
len = (int)strlen((char *)name);
|
||||||
|
|
||||||
|
serial = myrand(name,len);
|
||||||
|
*(unsigned short*)buf = serial; /* query id */
|
||||||
|
buf[2] = 1; /* recursive */
|
||||||
|
buf[3] = 0;
|
||||||
|
buf[4] = 0;
|
||||||
|
buf[5] = 1; /* 1 request */
|
||||||
|
buf[6] = buf[7] = 0; /* no replies */
|
||||||
|
buf[8] = buf[9] = 0; /* no ns count */
|
||||||
|
buf[10] = buf[11] = 0; /* no additional */
|
||||||
|
if(len > 255) {
|
||||||
|
len = 255;
|
||||||
|
}
|
||||||
|
memcpy(buf + 13, name, len);
|
||||||
|
len += 13;
|
||||||
|
buf[len] = 0;
|
||||||
|
for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
|
||||||
|
*s2 = (len - (int)(s2 - buf)) - 1;
|
||||||
|
len++;
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01);/* PTR:host address */
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = 1; /* INET */
|
||||||
|
if(usetcp){
|
||||||
|
buf-=2;
|
||||||
|
*(unsigned short*)buf = htons(len);
|
||||||
|
len+=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(socksendto(NULL, sock, (struct sockaddr *)sinsr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(param) param->statscli64 += len;
|
||||||
|
len = sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf, 4096, conf.timeouts[DNS_TO]*1000);
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
if(len <= 13) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(param) param->statssrv64 += len;
|
||||||
|
if(usetcp){
|
||||||
|
unsigned short us;
|
||||||
|
us = ntohs(*(unsigned short*)buf);
|
||||||
|
len-=2;
|
||||||
|
buf+=2;
|
||||||
|
if(us > 4096 || us < len || (us > len && sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf+len, us-len, conf.timeouts[DNS_TO]*1000) != us-len)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(*(unsigned short *)buf != serial)continue;
|
||||||
|
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
nq = buf[5] + (((unsigned short)buf[4])<<8);
|
||||||
|
if (nq != 1) {
|
||||||
|
continue; /* we did only 1 request */
|
||||||
|
}
|
||||||
|
for(k = 13; k<len && buf[k]; k++) {
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
if( (k+4) >= len) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
k += 4;
|
||||||
|
if(na > 255) na = 255; /* somebody is very evil */
|
||||||
|
for (j = 0; j < na; j++) { /* now there should be answers */
|
||||||
|
while(buf[k] < 192 && buf[k] !=0 && (k+buf[k]+14) < len) k+= (buf[k] + 1);
|
||||||
|
if(!buf[k]) k--;
|
||||||
|
if((k+(af == AF_INET6?28:16)) > len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
|
||||||
|
if((k+12+flen) > len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(makeauth != 1){
|
||||||
|
if(buf[k+2] != 0 || buf[k+3] != (af == AF_INET6?0x1c:0x1) || flen != (af == AF_INET6?16:4)) {
|
||||||
|
k+= (12 + flen);
|
||||||
|
continue; /* we need A IPv4 */
|
||||||
|
}
|
||||||
|
ttl = ntohl(*(uint32_t *)(buf + k + 6));
|
||||||
|
memcpy(value, buf + k + 12, af == AF_INET6? 16:4);
|
||||||
|
if(ttl < 0 || ttl > (3600*12)) ttl = 3600*12;
|
||||||
|
if(!ttl) ttl = 1;
|
||||||
|
hashadd(af == AF_INET6?&dns6_table:&dns_table, name, value, conf.time+ttl);
|
||||||
|
if(retttl) *retttl = ttl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if(buf[k+2] != 0 || buf[k+3] != 0x0c) {
|
||||||
|
k+= (12 + flen);
|
||||||
|
continue; /* we need A PTR */
|
||||||
|
}
|
||||||
|
for (s2 = buf + k + 12; s2 < (buf + k + 12 + len) && *s2; ){
|
||||||
|
s1 = s2 + ((unsigned)*s2) + 1;
|
||||||
|
*s2 = '.';
|
||||||
|
s2 = s1;
|
||||||
|
}
|
||||||
|
*s2 = 0;
|
||||||
|
if(param->username)myfree(param->username);
|
||||||
|
param->username = (unsigned char *)mystrdup ((char *)buf + k + 13);
|
||||||
|
|
||||||
|
return udpresolve(af,param->username, value, NULL, NULL, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t myresolver(int af, unsigned char * name, unsigned char * value){
|
||||||
|
return udpresolve(af, name, value, NULL, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fakeresolver (int af, unsigned char *name, unsigned char * value){
|
||||||
|
memset(value, 0, af == AF_INET6? 16 : 4);
|
||||||
|
if(af == AF_INET6){
|
||||||
|
memset(value, 0, 16);
|
||||||
|
value[15] = 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value[0] = 127;
|
||||||
|
value[1] = 0;
|
||||||
|
value[2] = 0;
|
||||||
|
value[3] = 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
152
src/sql.c
Normal file
152
src/sql.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include "proxy.h"
|
||||||
|
#ifndef NOODBC
|
||||||
|
|
||||||
|
SQLHENV henv = NULL;
|
||||||
|
SQLHSTMT hstmt = NULL;
|
||||||
|
SQLHDBC hdbc = NULL;
|
||||||
|
char * sqlstring = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
void close_sql(){
|
||||||
|
if(hstmt) {
|
||||||
|
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||||
|
hstmt = NULL;
|
||||||
|
}
|
||||||
|
if(hdbc){
|
||||||
|
SQLDisconnect(hdbc);
|
||||||
|
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||||
|
hdbc = NULL;
|
||||||
|
}
|
||||||
|
if(henv) {
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
|
henv = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int attempt = 0;
|
||||||
|
time_t attempt_time = 0;
|
||||||
|
|
||||||
|
int init_sql(char * s){
|
||||||
|
SQLRETURN retcode;
|
||||||
|
char * datasource;
|
||||||
|
char * username;
|
||||||
|
char * password;
|
||||||
|
char * string;
|
||||||
|
|
||||||
|
if(!s) return 0;
|
||||||
|
if(!sqlstring || strcmp(sqlstring, s)){
|
||||||
|
string = sqlstring;
|
||||||
|
sqlstring=mystrdup(s);
|
||||||
|
if(string)myfree(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hstmt || hdbc || henv) close_sql();
|
||||||
|
attempt++;
|
||||||
|
attempt_time = time(0);
|
||||||
|
if(!henv){
|
||||||
|
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||||
|
if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
|
||||||
|
henv = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
|
||||||
|
|
||||||
|
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!hdbc){
|
||||||
|
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||||
|
if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
|
||||||
|
hdbc = NULL;
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
|
henv = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
|
||||||
|
}
|
||||||
|
string = mystrdup(sqlstring);
|
||||||
|
if(!string) return 0;
|
||||||
|
datasource = strtok(string, ",");
|
||||||
|
username = strtok(NULL, ",");
|
||||||
|
password = strtok(NULL, ",");
|
||||||
|
|
||||||
|
|
||||||
|
/* Connect to data source */
|
||||||
|
retcode = SQLConnect(hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
|
||||||
|
(SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
|
||||||
|
(SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
|
||||||
|
|
||||||
|
myfree(string);
|
||||||
|
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
||||||
|
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||||
|
hdbc = NULL;
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
|
henv = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||||
|
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
||||||
|
close_sql();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sqlerr (char *buf){
|
||||||
|
if(conf.stdlog){
|
||||||
|
fprintf(conf.stdlog, "%s\n", buf);
|
||||||
|
fflush(conf.stdlog);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&log_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char statbuf[8192];
|
||||||
|
|
||||||
|
void logsql(struct clientparam * param, const unsigned char *s) {
|
||||||
|
SQLRETURN ret;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
|
||||||
|
if(param->nolog) return;
|
||||||
|
pthread_mutex_lock(&log_mutex);
|
||||||
|
len = dobuf(param, statbuf, s, (unsigned char *)"\'");
|
||||||
|
|
||||||
|
if(attempt > 5){
|
||||||
|
time_t t;
|
||||||
|
|
||||||
|
t = time(0);
|
||||||
|
if (t - attempt_time < 180){
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!hstmt){
|
||||||
|
if(!init_sql(sqlstring)) {
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hstmt){
|
||||||
|
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
||||||
|
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
||||||
|
close_sql();
|
||||||
|
if(!init_sql(sqlstring)){
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(hstmt) {
|
||||||
|
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
||||||
|
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attempt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attempt = 0;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&log_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -754,10 +754,12 @@ struct child {
|
|||||||
unsigned char **argv;
|
unsigned char **argv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define HASH_SIZE (16)
|
||||||
|
|
||||||
struct hashentry {
|
struct hashentry {
|
||||||
unsigned char hash[sizeof(unsigned)*4];
|
uint8_t hash[HASH_SIZE];
|
||||||
time_t expires;
|
time_t expires;
|
||||||
struct hashentry *next;
|
uint32_t inext;
|
||||||
char value[4];
|
char value[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -765,9 +767,12 @@ struct hashtable {
|
|||||||
unsigned hashsize;
|
unsigned hashsize;
|
||||||
unsigned recsize;
|
unsigned recsize;
|
||||||
unsigned rnd[4];
|
unsigned rnd[4];
|
||||||
struct hashentry ** hashtable;
|
uint32_t * ihashtable;
|
||||||
void * hashvalues;
|
uint8_t * hashvalues;
|
||||||
struct hashentry * hashempty;
|
uint32_t ihashempty;
|
||||||
|
void (*index2hash)(const void *index, unsigned char *hash, const unsigned char *rnd);
|
||||||
|
unsigned growlimit;
|
||||||
|
int tablesize;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct hashtable dns_table;
|
extern struct hashtable dns_table;
|
||||||
@ -795,8 +800,6 @@ struct pluginlink {
|
|||||||
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
|
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
|
||||||
int (*alwaysauth)(struct clientparam * param);
|
int (*alwaysauth)(struct clientparam * param);
|
||||||
int (*checkACL)(struct clientparam * param);
|
int (*checkACL)(struct clientparam * param);
|
||||||
void (*nametohash)(const unsigned char * name, unsigned char *hash, unsigned char *rnd);
|
|
||||||
unsigned (*hashindex)(struct hashtable *ht, const unsigned char* hash);
|
|
||||||
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen);
|
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen);
|
||||||
int (*de64)(const unsigned char *in, unsigned char *out, int maxlen);
|
int (*de64)(const unsigned char *in, unsigned char *out, int maxlen);
|
||||||
void (*tohex)(unsigned char *in, unsigned char *out, int len);
|
void (*tohex)(unsigned char *in, unsigned char *out, int len);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user