mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-23 01:49:53 +03:00
Refactor Base64 functions, encode/decode using OpenSSL's EVP interface
Our own implementation works fine, however we should use OpenSSL's one since we already link to the library. Base64Decode() and Base64Encode() return the required buffer size when "dst" is NULL. This allows to efficiently allocate a buffer, without wasting memory or risking an overflow. Base64FromBin() and Base64ToBin() perform all steps, returning a heap-allocated buffer with the data in it.
This commit is contained in:
parent
03d67fd5b1
commit
233e28f38c
@ -939,30 +939,26 @@ bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size
|
|||||||
{
|
{
|
||||||
if (StrCmpi(key, "Basic") == 0 && IsEmptyStr(value) == false)
|
if (StrCmpi(key, "Basic") == 0 && IsEmptyStr(value) == false)
|
||||||
{
|
{
|
||||||
UINT b64_dest_size = StrSize(value) * 2 + 256;
|
char *str = Base64ToBin(NULL, value, StrLen(value));
|
||||||
char *b64_dest = ZeroMalloc(b64_dest_size);
|
if (str != NULL)
|
||||||
|
|
||||||
Decode64(b64_dest, value);
|
|
||||||
|
|
||||||
if (IsEmptyStr(b64_dest) == false)
|
|
||||||
{
|
{
|
||||||
if (b64_dest[0] == ':')
|
if (str[0] == ':')
|
||||||
{
|
{
|
||||||
// Empty username
|
// Empty username
|
||||||
StrCpy(username, username_size, "");
|
StrCpy(username, username_size, "");
|
||||||
StrCpy(password, password_size, b64_dest + 1);
|
StrCpy(password, password_size, str + 1);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GetKeyAndValue(b64_dest, username, username_size, password, password_size, ":"))
|
if (GetKeyAndValue(str, username, username_size, password, password_size, ":"))
|
||||||
{
|
{
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Free(b64_dest);
|
Free(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,9 +806,6 @@ static UINT SmDdnsGetKey(char *key, SM_DDNS *d){
|
|||||||
|
|
||||||
void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d)
|
void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d)
|
||||||
{
|
{
|
||||||
char key[20];
|
|
||||||
char encodedkey[20 * 4 + 32];
|
|
||||||
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (hWnd == NULL || d == NULL)
|
if (hWnd == NULL || d == NULL)
|
||||||
{
|
{
|
||||||
@ -845,10 +842,15 @@ void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d)
|
|||||||
|
|
||||||
Hide(hWnd, B_PROXY);
|
Hide(hWnd, B_PROXY);
|
||||||
|
|
||||||
if(SmDdnsGetKey(key, d) == ERR_NO_ERROR){
|
char key[20];
|
||||||
encodedkey[ B64_Encode(encodedkey, key, 20) ] = 0;
|
if (SmDdnsGetKey(key, d) == ERR_NO_ERROR)
|
||||||
SetTextA(hWnd, E_KEY, encodedkey);
|
{
|
||||||
}else{
|
char *encoded_key = Base64FromBin(NULL, key, sizeof(key));
|
||||||
|
SetTextA(hWnd, E_KEY, encoded_key);
|
||||||
|
Free(encoded_key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
SetText(hWnd, E_KEY, _UU("SM_DDNS_KEY_ERR"));
|
SetText(hWnd, E_KEY, _UU("SM_DDNS_KEY_ERR"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "Radius.h"
|
#include "Radius.h"
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
|
|
||||||
|
#include "Mayaqua/Encoding.h"
|
||||||
#include "Mayaqua/Internat.h"
|
#include "Mayaqua/Internat.h"
|
||||||
#include "Mayaqua/Memory.h"
|
#include "Mayaqua/Memory.h"
|
||||||
#include "Mayaqua/Microsoft.h"
|
#include "Mayaqua/Microsoft.h"
|
||||||
@ -31,11 +32,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int base64_enc_len(unsigned int plainLen) {
|
|
||||||
unsigned int n = plainLen;
|
|
||||||
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
PID OpenChildProcess(const char* path, char* const parameter[], int fd[] )
|
PID OpenChildProcess(const char* path, char* const parameter[], int fd[] )
|
||||||
{
|
{
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
@ -134,7 +130,6 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
|||||||
int fds[2];
|
int fds[2];
|
||||||
FILE* out, *in;
|
FILE* out, *in;
|
||||||
PID pid;
|
PID pid;
|
||||||
char buffer[255];
|
|
||||||
char ntlm_timeout[32];
|
char ntlm_timeout[32];
|
||||||
char* proc_parameter[6];
|
char* proc_parameter[6];
|
||||||
|
|
||||||
@ -153,8 +148,6 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zero(buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
// Truncate string if unsafe char
|
// Truncate string if unsafe char
|
||||||
EnSafeStr(domainname, '\0');
|
EnSafeStr(domainname, '\0');
|
||||||
|
|
||||||
@ -218,64 +211,48 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base64_enc_len((unsigned int)strlen(name)) < sizeof(buffer)-1 &&
|
|
||||||
base64_enc_len((unsigned int)strlen(password)) < sizeof(buffer)-1 &&
|
|
||||||
base64_enc_len((unsigned int)strlen(domainname)) < sizeof(buffer)-1)
|
|
||||||
{
|
{
|
||||||
char answer[300];
|
char *base64 = Base64FromBin(NULL, name, StrLen(name));
|
||||||
|
|
||||||
unsigned int end = B64_Encode(buffer, name, (int)strlen(name));
|
|
||||||
buffer[end] = '\0';
|
|
||||||
fputs("Username:: ", out);
|
fputs("Username:: ", out);
|
||||||
fputs(buffer, out);
|
fputs(base64, out);
|
||||||
fputs("\n", out);
|
fputs("\n", out);
|
||||||
Debug("Username: %s\n", buffer);
|
Free(base64);
|
||||||
buffer[0] = 0;
|
|
||||||
|
|
||||||
end = B64_Encode(buffer, domainname, (int)strlen(domainname));
|
base64 = Base64FromBin(NULL, domainname, StrLen(domainname));
|
||||||
buffer[end] = '\0';
|
|
||||||
fputs("NT-Domain:: ", out);
|
fputs("NT-Domain:: ", out);
|
||||||
fputs(buffer, out);
|
fputs(base64, out);
|
||||||
fputs("\n", out);
|
fputs("\n", out);
|
||||||
Debug("NT-Domain: %s\n", buffer);
|
Free(base64);
|
||||||
buffer[0] = 0;
|
|
||||||
|
|
||||||
if (password[0] != '\0')
|
if (IsEmptyStr(password) == false)
|
||||||
{
|
{
|
||||||
Debug("Password authentication\n");
|
Debug("SmbAuthenticate(): Using password authentication...\n");
|
||||||
end = B64_Encode(buffer, password, (int)strlen(password));
|
|
||||||
buffer[end] = '\0';
|
base64 = Base64FromBin(NULL, password, StrLen(password));
|
||||||
fputs("Password:: ", out);
|
fputs("Password:: ", out);
|
||||||
fputs(buffer, out);
|
fputs(base64, out);
|
||||||
fputs("\n", out);
|
fputs("\n", out);
|
||||||
Debug("Password: %s\n", buffer);
|
Free(base64);
|
||||||
buffer[0] = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char* mschapv2_client_response;
|
Debug("SmbAuthenticate(): Using MsChapV2 authentication...\n");
|
||||||
char* base64_challenge8;
|
|
||||||
|
|
||||||
Debug("MsChapV2 authentication\n");
|
char *mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24);
|
||||||
mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24);
|
base64 = Base64FromBin(NULL, mschapv2_client_response, 48);
|
||||||
end = B64_Encode(buffer, mschapv2_client_response, 48);
|
|
||||||
buffer[end] = '\0';
|
|
||||||
fputs("NT-Response:: ", out);
|
|
||||||
fputs(buffer, out);
|
|
||||||
fputs("\n", out);
|
|
||||||
Debug("NT-Response:: %s\n", buffer);
|
|
||||||
buffer[0] = 0;
|
|
||||||
Free(mschapv2_client_response);
|
Free(mschapv2_client_response);
|
||||||
|
fputs("NT-Response:: ", out);
|
||||||
base64_challenge8 = CopyBinToStr(challenge8, 8);
|
fputs(base64, out);
|
||||||
end = B64_Encode(buffer, base64_challenge8 , 16);
|
|
||||||
buffer[end] = '\0';
|
|
||||||
fputs("LANMAN-Challenge:: ", out);
|
|
||||||
fputs(buffer, out);
|
|
||||||
fputs("\n", out);
|
fputs("\n", out);
|
||||||
Debug("LANMAN-Challenge:: %s\n", buffer);
|
Free(base64);
|
||||||
buffer[0] = 0;
|
|
||||||
|
char *base64_challenge8 = CopyBinToStr(challenge8, 8);
|
||||||
|
base64 = Base64FromBin(NULL, base64_challenge8, 16);
|
||||||
Free(base64_challenge8);
|
Free(base64_challenge8);
|
||||||
|
fputs("LANMAN-Challenge:: ", out);
|
||||||
|
fputs(base64, out);
|
||||||
|
fputs("\n", out);
|
||||||
|
Free(base64);
|
||||||
|
|
||||||
fputs("Request-User-Session-Key: Yes\n", out);
|
fputs("Request-User-Session-Key: Yes\n", out);
|
||||||
}
|
}
|
||||||
@ -285,6 +262,7 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
|||||||
fflush (out);
|
fflush (out);
|
||||||
// Request send!
|
// Request send!
|
||||||
|
|
||||||
|
char answer[300];
|
||||||
Zero(answer, sizeof(answer));
|
Zero(answer, sizeof(answer));
|
||||||
|
|
||||||
while (fgets(answer, sizeof(answer)-1, in))
|
while (fgets(answer, sizeof(answer)-1, in))
|
||||||
@ -323,7 +301,7 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
|||||||
response_parameter[0] ='\0';
|
response_parameter[0] ='\0';
|
||||||
response_parameter++;
|
response_parameter++;
|
||||||
|
|
||||||
end = Decode64(response_parameter, response_parameter);
|
const UINT end = Base64Decode(response_parameter, response_parameter, StrLen(response_parameter));
|
||||||
response_parameter[end] = '\0';
|
response_parameter[end] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "Protocol.h"
|
#include "Protocol.h"
|
||||||
|
|
||||||
#include "Mayaqua/DNS.h"
|
#include "Mayaqua/DNS.h"
|
||||||
|
#include "Mayaqua/Encoding.h"
|
||||||
#include "Mayaqua/Memory.h"
|
#include "Mayaqua/Memory.h"
|
||||||
#include "Mayaqua/Microsoft.h"
|
#include "Mayaqua/Microsoft.h"
|
||||||
#include "Mayaqua/Pack.h"
|
#include "Mayaqua/Pack.h"
|
||||||
@ -807,19 +808,14 @@ BUF *HttpRequestEx3(URL_DATA *data, INTERNET_SETTING *setting,
|
|||||||
|
|
||||||
if (IsEmptyStr(setting->ProxyUsername) == false || IsEmptyStr(setting->ProxyPassword) == false)
|
if (IsEmptyStr(setting->ProxyUsername) == false || IsEmptyStr(setting->ProxyPassword) == false)
|
||||||
{
|
{
|
||||||
char auth_tmp_str[MAX_SIZE], auth_b64_str[MAX_SIZE * 2];
|
char auth_str[MAX_SIZE * 2];
|
||||||
char basic_str[MAX_SIZE * 2];
|
Format(auth_str, sizeof(auth_str), "%s:%s", setting->ProxyUsername, setting->ProxyPassword);
|
||||||
|
|
||||||
// Generate the authentication string
|
char *base64 = Base64FromBin(NULL, auth_str, StrLen(auth_str));
|
||||||
Format(auth_tmp_str, sizeof(auth_tmp_str), "%s:%s",
|
Format(auth_str, sizeof(auth_str), "Basic %s", base64);
|
||||||
setting->ProxyUsername, setting->ProxyPassword);
|
Free(base64);
|
||||||
|
|
||||||
// Base64 encode
|
AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str));
|
||||||
Zero(auth_b64_str, sizeof(auth_b64_str));
|
|
||||||
Encode64(auth_b64_str, auth_tmp_str);
|
|
||||||
Format(basic_str, sizeof(basic_str), "Basic %s", auth_b64_str);
|
|
||||||
|
|
||||||
AddHttpValue(h, NewHttpValue("Proxy-Authorization", basic_str));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1229,18 +1225,14 @@ bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String replacement
|
// String replacement
|
||||||
void Base64ToSafe64(char *str)
|
void Base64ToSafe64(char *str, const UINT size)
|
||||||
{
|
{
|
||||||
UINT i, len;
|
if (str == NULL || size == 0)
|
||||||
// Validate arguments
|
|
||||||
if (str == NULL)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = StrLen(str);
|
for (UINT i = 0; i < size; ++i)
|
||||||
|
|
||||||
for (i = 0;i < len;i++)
|
|
||||||
{
|
{
|
||||||
switch (str[i])
|
switch (str[i])
|
||||||
{
|
{
|
||||||
@ -1258,18 +1250,14 @@ void Base64ToSafe64(char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Safe64ToBase64(char *str)
|
void Safe64ToBase64(char *str, const UINT size)
|
||||||
{
|
{
|
||||||
UINT i, len;
|
if (str == NULL || size == 0)
|
||||||
// Validate arguments
|
|
||||||
if (str == NULL)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = StrLen(str);
|
for (UINT i = 0; i < size; ++i)
|
||||||
|
|
||||||
for (i = 0;i < len;i++)
|
|
||||||
{
|
{
|
||||||
switch (str[i])
|
switch (str[i])
|
||||||
{
|
{
|
||||||
@ -1288,44 +1276,39 @@ void Safe64ToBase64(char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode from Safe64
|
// Decode from escaped Base64
|
||||||
UINT DecodeSafe64(void *dst, char *src, UINT src_strlen)
|
UINT DecodeSafe64(void *dst, const char *src, UINT size)
|
||||||
{
|
{
|
||||||
char *tmp;
|
|
||||||
UINT ret;
|
|
||||||
if (dst == NULL || src == NULL)
|
if (dst == NULL || src == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_strlen == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
src_strlen = StrLen(src);
|
size = StrLen(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = Malloc(src_strlen + 1);
|
char *tmp = Malloc(size + 1);
|
||||||
Copy(tmp, src, src_strlen);
|
Copy(tmp, src, size);
|
||||||
tmp[src_strlen] = 0;
|
tmp[size] = '\0';
|
||||||
Safe64ToBase64(tmp);
|
|
||||||
|
|
||||||
ret = B64_Decode(dst, tmp, src_strlen);
|
Safe64ToBase64(tmp, size);
|
||||||
|
const UINT ret = Base64Decode(dst, tmp, size);
|
||||||
Free(tmp);
|
Free(tmp);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode to Safe64
|
// Encode to escaped Base64
|
||||||
void EncodeSafe64(char *dst, void *src, UINT src_size)
|
void EncodeSafe64(char *dst, const void *src, const UINT size)
|
||||||
{
|
{
|
||||||
UINT size;
|
|
||||||
if (dst == NULL || src == NULL)
|
if (dst == NULL || src == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = B64_Encode(dst, src, src_size);
|
const UINT ret = Base64Encode(dst, src, size);
|
||||||
dst[size] = 0;
|
|
||||||
|
|
||||||
Base64ToSafe64(dst);
|
Base64ToSafe64(dst, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,10 +84,10 @@ struct WPC_PACKET
|
|||||||
typedef bool (WPC_RECV_CALLBACK)(void *param, UINT total_size, UINT current_size, BUF *recv_buf);
|
typedef bool (WPC_RECV_CALLBACK)(void *param, UINT total_size, UINT current_size, BUF *recv_buf);
|
||||||
|
|
||||||
// Function prototype
|
// Function prototype
|
||||||
void EncodeSafe64(char *dst, void *src, UINT src_size);
|
void Base64ToSafe64(char *str, const UINT size);
|
||||||
UINT DecodeSafe64(void *dst, char *src, UINT src_strlen);
|
void Safe64ToBase64(char *str, const UINT size);
|
||||||
void Base64ToSafe64(char *str);
|
UINT DecodeSafe64(void *dst, const char *src, UINT size);
|
||||||
void Safe64ToBase64(char *str);
|
void EncodeSafe64(char *dst, const void *src, const UINT size);
|
||||||
bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer);
|
bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer);
|
||||||
void CreateUrl(char *url, UINT url_size, URL_DATA *data);
|
void CreateUrl(char *url, UINT url_size, URL_DATA *data);
|
||||||
void GetSystemInternetSetting(INTERNET_SETTING *setting);
|
void GetSystemInternetSetting(INTERNET_SETTING *setting);
|
||||||
|
@ -57,9 +57,16 @@ if(UNIX)
|
|||||||
# In some cases libiconv is not included in libc
|
# In some cases libiconv is not included in libc
|
||||||
find_library(LIB_ICONV iconv)
|
find_library(LIB_ICONV iconv)
|
||||||
|
|
||||||
|
find_library(LIB_M m)
|
||||||
find_library(LIB_RT rt)
|
find_library(LIB_RT rt)
|
||||||
|
|
||||||
target_link_libraries(mayaqua PRIVATE Threads::Threads)
|
target_link_libraries(mayaqua
|
||||||
|
PRIVATE
|
||||||
|
Threads::Threads
|
||||||
|
$<$<BOOL:${LIB_ICONV}>:${LIB_ICONV}>
|
||||||
|
$<$<BOOL:${LIB_M}>:${LIB_M}>
|
||||||
|
$<$<BOOL:${LIB_RT}>:${LIB_RT}>
|
||||||
|
)
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7l|aarch64|s390x)$" OR NOT HAVE_SYS_AUXV OR SKIP_CPU_FEATURES)
|
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7l|aarch64|s390x)$" OR NOT HAVE_SYS_AUXV OR SKIP_CPU_FEATURES)
|
||||||
add_definitions(-DSKIP_CPU_FEATURES)
|
add_definitions(-DSKIP_CPU_FEATURES)
|
||||||
@ -69,14 +76,6 @@ if(UNIX)
|
|||||||
target_link_libraries(mayaqua PRIVATE cpu_features)
|
target_link_libraries(mayaqua PRIVATE cpu_features)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(LIB_RT)
|
|
||||||
target_link_libraries(mayaqua PRIVATE rt)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(LIB_ICONV)
|
|
||||||
target_link_libraries(mayaqua PRIVATE ${LIB_ICONV})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
|
||||||
target_link_libraries(mayaqua PRIVATE nsl socket)
|
target_link_libraries(mayaqua PRIVATE nsl socket)
|
||||||
endif()
|
endif()
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Cfg.h"
|
#include "Cfg.h"
|
||||||
|
|
||||||
|
#include "Encoding.h"
|
||||||
#include "FileIO.h"
|
#include "FileIO.h"
|
||||||
#include "Internat.h"
|
#include "Internat.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
@ -746,12 +747,18 @@ bool CfgReadNextTextBUF(BUF *b, FOLDER *current)
|
|||||||
if (!StrCmpi(token->Token[0], TAG_BYTE))
|
if (!StrCmpi(token->Token[0], TAG_BYTE))
|
||||||
{
|
{
|
||||||
// byte
|
// byte
|
||||||
char *unescaped_b64 = CfgUnescape(data);
|
char *base64 = CfgUnescape(data);
|
||||||
void *tmp = Malloc(StrLen(unescaped_b64) * 4 + 64);
|
const UINT base64_size = StrLen(base64);
|
||||||
int size = B64_Decode(tmp, unescaped_b64, StrLen(unescaped_b64));
|
|
||||||
CfgAddByte(current, name, tmp, size);
|
UINT bin_size;
|
||||||
Free(tmp);
|
void *bin = Base64ToBin(&bin_size, base64, base64_size);
|
||||||
Free(unescaped_b64);
|
if (bin != NULL)
|
||||||
|
{
|
||||||
|
CfgAddByte(current, name, bin, bin_size);
|
||||||
|
Free(bin);
|
||||||
|
}
|
||||||
|
|
||||||
|
Free(base64);
|
||||||
}
|
}
|
||||||
|
|
||||||
Free(name);
|
Free(name);
|
||||||
@ -1162,9 +1169,7 @@ void CfgAddItemText(BUF *b, ITEM *t, UINT depth)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ITEM_TYPE_BYTE:
|
case ITEM_TYPE_BYTE:
|
||||||
data = ZeroMalloc(t->size * 4 + 32);
|
data = Base64FromBin(NULL, t->Buf, t->size);
|
||||||
len = B64_Encode(data, t->Buf, t->size);
|
|
||||||
data[len] = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ITEM_TYPE_STRING:
|
case ITEM_TYPE_STRING:
|
||||||
|
64
src/Mayaqua/Encoding.c
Normal file
64
src/Mayaqua/Encoding.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "Encoding.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
UINT Base64Decode(void *dst, const void *src, const UINT size)
|
||||||
|
{
|
||||||
|
if (dst == NULL)
|
||||||
|
{
|
||||||
|
// 4 input bytes = max. 3 output bytes.
|
||||||
|
//
|
||||||
|
// EVP_DecodeUpdate() ignores:
|
||||||
|
// - Leading/trailing whitespace.
|
||||||
|
// - Trailing newlines, carriage returns or EOF characters.
|
||||||
|
//
|
||||||
|
// EVP_DecodeFinal() fails if the input is not divisible by 4.
|
||||||
|
return size / 4 * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't use EVP_DecodeBlock() because it adds padding if the output is not divisible by 3.
|
||||||
|
EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
|
||||||
|
if (ctx == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
if (EVP_DecodeUpdate(ctx, dst, &ret, src, size) < 0)
|
||||||
|
{
|
||||||
|
goto FINAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
if (EVP_DecodeFinal(ctx, dst, &dummy) < 0)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
FINAL:
|
||||||
|
EVP_ENCODE_CTX_free(ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT Base64Encode(void *dst, const void *src, const UINT size)
|
||||||
|
{
|
||||||
|
if (dst == NULL)
|
||||||
|
{
|
||||||
|
// 3 input bytes = 4 output bytes.
|
||||||
|
// +1 for the NUL terminator.
|
||||||
|
//
|
||||||
|
// EVP_EncodeBlock() adds padding when the input is not divisible by 3.
|
||||||
|
return ceilf((float)size / 3) * 4 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int ret = EVP_EncodeBlock(dst, src, size);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
// EVP_EncodeBlock() returns the length of the string without the NUL terminator.
|
||||||
|
// We, instead, want to return the amount of bytes written into the output buffer.
|
||||||
|
return ret + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
9
src/Mayaqua/Encoding.h
Normal file
9
src/Mayaqua/Encoding.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef ENCODING_H
|
||||||
|
#define ENCODING_H
|
||||||
|
|
||||||
|
#include "MayaType.h"
|
||||||
|
|
||||||
|
UINT Base64Decode(void *dst, const void *src, const UINT size);
|
||||||
|
UINT Base64Encode(void *dst, const void *src, const UINT size);
|
||||||
|
|
||||||
|
#endif
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
|
||||||
|
#include "Encoding.h"
|
||||||
#include "Encrypt.h"
|
#include "Encrypt.h"
|
||||||
#include "FileIO.h"
|
#include "FileIO.h"
|
||||||
#include "Internat.h"
|
#include "Internat.h"
|
||||||
@ -3407,232 +3408,62 @@ UINT64 Swap64(UINT64 value)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64 encode
|
void *Base64ToBin(UINT *out_size, const void *src, const UINT size)
|
||||||
UINT Encode64(char *dst, char *src)
|
|
||||||
{
|
{
|
||||||
// Validate arguments
|
if (src == NULL || size == 0)
|
||||||
if (dst == NULL || src == NULL)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B64_Encode(dst, src, StrLen(src));
|
UINT bin_size = Base64Decode(NULL, src, size);
|
||||||
|
if (bin_size == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *bin = Malloc(bin_size);
|
||||||
|
bin_size = Base64Decode(bin, src, size);
|
||||||
|
if (bin_size == 0)
|
||||||
|
{
|
||||||
|
Free(bin);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out_size != NULL)
|
||||||
|
{
|
||||||
|
*out_size = bin_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64 decoding
|
void *Base64FromBin(UINT *out_size, const void *src, const UINT size)
|
||||||
UINT Decode64(char *dst, char *src)
|
|
||||||
{
|
{
|
||||||
// Validate arguments
|
if (src == NULL || size == 0)
|
||||||
if (dst == NULL || src == NULL)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B64_Decode(dst, src, StrLen(src));
|
UINT base64_size = Base64Encode(NULL, src, size);
|
||||||
}
|
if (base64_size == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Base64 encode
|
void *base64 = Malloc(base64_size);
|
||||||
int B64_Encode(char *set, char *source, int len)
|
base64_size = Base64Encode(base64, src, size);
|
||||||
{
|
if (base64_size == 0)
|
||||||
BYTE *src;
|
|
||||||
int i,j;
|
|
||||||
src = (BYTE *)source;
|
|
||||||
j = 0;
|
|
||||||
i = 0;
|
|
||||||
if (!len)
|
|
||||||
{
|
{
|
||||||
return 0;
|
Free(base64);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (i >= len)
|
|
||||||
{
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j] = B64_CodeToChar((src[i]) >> 2);
|
|
||||||
}
|
|
||||||
if (i + 1 >= len)
|
|
||||||
{
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j + 1] = B64_CodeToChar((src[i] & 0x03) << 4);
|
|
||||||
set[j + 2] = '=';
|
|
||||||
set[j + 3] = '=';
|
|
||||||
}
|
|
||||||
return j + 4;
|
|
||||||
}
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j + 1] = B64_CodeToChar(((src[i] & 0x03) << 4) + ((src[i + 1] >> 4)));
|
|
||||||
}
|
|
||||||
if (i + 2 >= len)
|
|
||||||
{
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j + 2] = B64_CodeToChar((src[i + 1] & 0x0f) << 2);
|
|
||||||
set[j + 3] = '=';
|
|
||||||
}
|
|
||||||
return j + 4;
|
|
||||||
}
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j + 2] = B64_CodeToChar(((src[i + 1] & 0x0f) << 2) + ((src[i + 2] >> 6)));
|
|
||||||
set[j + 3] = B64_CodeToChar(src[i + 2] & 0x3f);
|
|
||||||
}
|
|
||||||
i += 3;
|
|
||||||
j += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base64 decode
|
if (out_size != NULL)
|
||||||
int B64_Decode(char *set, char *source, int len)
|
|
||||||
{
|
|
||||||
int i,j;
|
|
||||||
char a1,a2,a3,a4;
|
|
||||||
char *src;
|
|
||||||
int f1,f2,f3,f4;
|
|
||||||
src = source;
|
|
||||||
i = 0;
|
|
||||||
j = 0;
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
f1 = f2 = f3 = f4 = 0;
|
*out_size = base64_size;
|
||||||
if (i >= len)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
f1 = 1;
|
|
||||||
a1 = B64_CharToCode(src[i]);
|
|
||||||
if (a1 == -1)
|
|
||||||
{
|
|
||||||
f1 = 0;
|
|
||||||
}
|
|
||||||
if (i >= len + 1)
|
|
||||||
{
|
|
||||||
a2 = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a2 = B64_CharToCode(src[i + 1]);
|
|
||||||
f2 = 1;
|
|
||||||
if (a2 == -1)
|
|
||||||
{
|
|
||||||
f2 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i >= len + 2)
|
|
||||||
{
|
|
||||||
a3 = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a3 = B64_CharToCode(src[i + 2]);
|
|
||||||
f3 = 1;
|
|
||||||
if (a3 == -1)
|
|
||||||
{
|
|
||||||
f3 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i >= len + 3)
|
|
||||||
{
|
|
||||||
a4 = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a4 = B64_CharToCode(src[i + 3]);
|
|
||||||
f4 = 1;
|
|
||||||
if (a4 == -1)
|
|
||||||
{
|
|
||||||
f4 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (f1 && f2)
|
|
||||||
{
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j] = (a1 << 2) + (a2 >> 4);
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (f2 && f3)
|
|
||||||
{
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j] = (a2 << 4) + (a3 >> 2);
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (f3 && f4)
|
|
||||||
{
|
|
||||||
if (set)
|
|
||||||
{
|
|
||||||
set[j] = (a3 << 6) + a4;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
i += 4;
|
|
||||||
}
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base64 : Convert a code to a character
|
return base64;
|
||||||
char B64_CodeToChar(BYTE c)
|
|
||||||
{
|
|
||||||
BYTE r;
|
|
||||||
r = '=';
|
|
||||||
if (c <= 0x19)
|
|
||||||
{
|
|
||||||
r = c + 'A';
|
|
||||||
}
|
|
||||||
if (c >= 0x1a && c <= 0x33)
|
|
||||||
{
|
|
||||||
r = c - 0x1a + 'a';
|
|
||||||
}
|
|
||||||
if (c >= 0x34 && c <= 0x3d)
|
|
||||||
{
|
|
||||||
r = c - 0x34 + '0';
|
|
||||||
}
|
|
||||||
if (c == 0x3e)
|
|
||||||
{
|
|
||||||
r = '+';
|
|
||||||
}
|
|
||||||
if (c == 0x3f)
|
|
||||||
{
|
|
||||||
r = '/';
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base64 : Convert a character to a code
|
|
||||||
char B64_CharToCode(char c)
|
|
||||||
{
|
|
||||||
if (c >= 'A' && c <= 'Z')
|
|
||||||
{
|
|
||||||
return c - 'A';
|
|
||||||
}
|
|
||||||
if (c >= 'a' && c <= 'z')
|
|
||||||
{
|
|
||||||
return c - 'a' + 0x1a;
|
|
||||||
}
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
{
|
|
||||||
return c - '0' + 0x34;
|
|
||||||
}
|
|
||||||
if (c == '+')
|
|
||||||
{
|
|
||||||
return 0x3e;
|
|
||||||
}
|
|
||||||
if (c == '/')
|
|
||||||
{
|
|
||||||
return 0x3f;
|
|
||||||
}
|
|
||||||
if (c == '=')
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Malloc
|
// Malloc
|
||||||
|
@ -190,12 +190,8 @@ void Zero(void *addr, UINT size);
|
|||||||
void *Clone(void *addr, UINT size);
|
void *Clone(void *addr, UINT size);
|
||||||
void *AddHead(void *src, UINT src_size, void *head, UINT head_size);
|
void *AddHead(void *src, UINT src_size, void *head, UINT head_size);
|
||||||
|
|
||||||
char B64_CodeToChar(BYTE c);
|
void *Base64FromBin(UINT *out_size, const void *src, const UINT size);
|
||||||
char B64_CharToCode(char c);
|
void *Base64ToBin(UINT *out_size, const void *src, const UINT size);
|
||||||
int B64_Encode(char *set, char *source, int len);
|
|
||||||
int B64_Decode(char *set, char *source, int len);
|
|
||||||
UINT Encode64(char *dst, char *src);
|
|
||||||
UINT Decode64(char *dst, char *src);
|
|
||||||
|
|
||||||
USHORT Swap16(USHORT value);
|
USHORT Swap16(USHORT value);
|
||||||
UINT Swap32(UINT value);
|
UINT Swap32(UINT value);
|
||||||
|
@ -2239,10 +2239,9 @@ bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index
|
|||||||
{
|
{
|
||||||
if (v->type == JSON_TYPE_STRING)
|
if (v->type == JSON_TYPE_STRING)
|
||||||
{
|
{
|
||||||
UINT len = StrLen(v->value.string);
|
UINT data_size;
|
||||||
UCHAR *data = ZeroMalloc(len * 4 + 64);
|
void *data = Base64ToBin(&data_size, v->value.string, StrLen(v->value.string));
|
||||||
UINT size = B64_Decode(data, v->value.string, len);
|
ElementNullSafe(PackAddDataEx(p, name, data, data_size, index, total))->JsonHint_IsArray = !is_single;
|
||||||
ElementNullSafe(PackAddDataEx(p, name, data, size, index, total))->JsonHint_IsArray = !is_single;
|
|
||||||
Free(data);
|
Free(data);
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
@ -129,17 +129,12 @@ UINT ProxyHttpConnect(PROXY_PARAM_OUT *out, PROXY_PARAM_IN *in, volatile bool *c
|
|||||||
|
|
||||||
if (use_auth && GetHttpValue(h, "Proxy-Authorization") == NULL)
|
if (use_auth && GetHttpValue(h, "Proxy-Authorization") == NULL)
|
||||||
{
|
{
|
||||||
char auth_str[MAX_SIZE * 2], auth_b64_str[MAX_SIZE * 2];
|
char auth_str[MAX_SIZE * 2];
|
||||||
|
|
||||||
// Generate the authentication string
|
|
||||||
Format(auth_str, sizeof(auth_str), "%s:%s", in->Username, in->Password);
|
Format(auth_str, sizeof(auth_str), "%s:%s", in->Username, in->Password);
|
||||||
|
|
||||||
// Base64 encode
|
char *base64 = Base64FromBin(NULL, auth_str, StrLen(auth_str));
|
||||||
Zero(auth_b64_str, sizeof(auth_b64_str));
|
Format(auth_str, sizeof(auth_str), "Basic %s", base64);
|
||||||
Encode64(auth_b64_str, auth_str);
|
Free(base64);
|
||||||
|
|
||||||
// Generate final string
|
|
||||||
Format(auth_str, sizeof(auth_str), "Basic %s", auth_b64_str);
|
|
||||||
|
|
||||||
AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str));
|
AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str));
|
||||||
}
|
}
|
||||||
|
@ -4667,12 +4667,11 @@ UINT JsonArrayAddNumber(JSON_ARRAY *array, UINT64 number) {
|
|||||||
UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size)
|
UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size)
|
||||||
{
|
{
|
||||||
UINT ret;
|
UINT ret;
|
||||||
char *b64 = ZeroMalloc(size * 4 + 32);
|
char *base64 = Base64FromBin(NULL, data, size);
|
||||||
B64_Encode(b64, data, size);
|
|
||||||
|
|
||||||
ret = JsonArrayAddStr(array, b64);
|
ret = JsonArrayAddStr(array, base64);
|
||||||
|
|
||||||
Free(b64);
|
Free(base64);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4724,12 +4723,11 @@ UINT JsonSet(JSON_OBJECT *object, char *name, JSON_VALUE *value) {
|
|||||||
UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size)
|
UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size)
|
||||||
{
|
{
|
||||||
UINT ret;
|
UINT ret;
|
||||||
char *b64 = ZeroMalloc(size * 4 + 32);
|
char *base64 = Base64FromBin(NULL, data, size);
|
||||||
B64_Encode(b64, data, size);
|
|
||||||
|
|
||||||
ret = JsonSetStr(object, name, b64);
|
ret = JsonSetStr(object, name, base64);
|
||||||
|
|
||||||
Free(b64);
|
Free(base64);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user