base64

This commit is contained in:
EntireTwix 2021-07-02 17:18:37 -07:00
parent e7f7f0f698
commit c9da3eab04
9 changed files with 92 additions and 154 deletions

View file

@ -20,9 +20,9 @@ target_sources(${PROJECT_NAME} PRIVATE
src/admin_filter.cpp
src/bank_api.cpp
src/bank.cpp
src/base64.c #temp
src/change_flag.cpp
src/log.cpp
src/substr_view.cpp
src/transaction.cpp
src/user_filter.cpp
src/user.cpp
@ -32,8 +32,12 @@ target_sources(${PROJECT_NAME} PRIVATE
target_include_directories(${PROJECT_NAME} PUBLIC include)
target_include_directories(${PROJECT_NAME} PUBLIC third_party)
target_include_directories(${PROJECT_NAME} PUBLIC third_party/drogon/lib/inc)
target_include_directories(${PROJECT_NAME} PUBLIC third_party/base64/include)
add_subdirectory(third_party/drogon)
target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_THREAD_LIBS_INIT} )
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
# AVX2_CFLAGS=-mavx2 SSSE3_CFLAGS=-mssse3 SSE41_CFLAGS=-msse4.1 SSE42_CFLAGS=-msse4.2 AVX_CFLAGS=-mavx make lib/libbase64.o
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/third_party/base64/lib/libbase64.o)

View file

@ -1,5 +1,7 @@
#pragma once
#include <drogon/HttpFilter.h>
#include <libbase64.h>
#include "substr_view.h"
#include "bank.h"
using namespace drogon;

16
include/substr_view.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include <cassert>
#include <string>
class substr_view
{
private:
const char *begin;
size_t end;
public:
substr_view(std::string_view str, size_t begin_init = 0, size_t end_init = 0) noexcept;
bool operator==(const std::string &str) const noexcept;
const char *data() const noexcept;
std::string_view str_view() const noexcept;
};

View file

@ -1,5 +1,7 @@
#pragma once
#include <drogon/HttpFilter.h>
#include <libbase64.h>
#include "substr_view.h"
#include "bank.h"
using namespace drogon;

View file

@ -4,5 +4,5 @@
struct xxHashStringGen
{
XXH64_hash_t operator()(const std::string &str) const noexcept;
XXH64_hash_t operator()(const std::string_view &str) const noexcept;
};

View file

@ -1,71 +1,5 @@
#include "admin_filter.h"
static char DecodeChar2(const char ch)
{
if (ch >= 'A' && ch <= 'Z')
{
return ch - 'A';
}
if (ch >= 'a' && ch <= 'z')
{
return ch - 'a' + 26;
}
if (ch >= '0' && ch <= '9')
{
return ch - '0' + 52;
}
return 63 - (ch == '-');
}
char *DecodeBase642(const char *string)
{
char *output;
size_t length = strlen(string);
if (!(output = (char *)malloc(1 + (length >> 2) * 3 - (string[length - 1] == '=') - (string[length - 2] == '='))))
{
return (char *)0;
}
size_t index = 0;
uint32_t storage = 0;
while (string[4])
{
storage |= DecodeChar2(*string++) << 18;
storage |= DecodeChar2(*string++) << 12;
storage |= DecodeChar2(*string++) << 6;
storage |= DecodeChar2(*string++);
output[index++] = storage >> 16;
output[index++] = (char)(storage >> 8);
output[index++] = (char)storage;
storage = 0;
}
storage |= DecodeChar2(*string++) << 18;
storage |= DecodeChar2(*string++) << 12;
output[index++] = storage >> 16;
if (*string == '=')
{
output[index] = '\0';
return output;
}
storage |= DecodeChar2(*string++) << 6;
output[index++] = (char)(storage >> 8);
if (*string == '=')
{
output[index] = '\0';
return output;
}
storage |= DecodeChar2(*string);
output[index++] = (char)storage;
output[index] = '\0';
return output;
}
AdminFilter::AdminFilter(Bank &b) : bank(b) {}
void AdminFilter::doFilter(const HttpRequestPtr &req,
@ -75,18 +9,26 @@ void AdminFilter::doFilter(const HttpRequestPtr &req,
const std::string &auth_header = req->getHeader("Authorization");
if (auth_header.size() > 6)
{
if (auth_header.substr(0, 6) == "Basic ")
if (substr_view(auth_header, 0, 6) == "Basic ")
{
std::stringstream ss(DecodeBase642(auth_header.substr(6).c_str()));
std::string username, password;
std::getline(ss, username, ':');
std::getline(ss, password);
if (bank.AdminVerifyPass(password)) //is admin
//only one alloc for this entire thing!
char base64_result[((auth_header.size() - 6) * 3) / 4];
size_t new_sz;
base64_decode(substr_view(auth_header, 6).data(), auth_header.size() - 6, base64_result, &new_sz, 0);
std::size_t res = std::string_view(base64_result, new_sz).find(':');
if (res != std::string::npos)
{
if (bank.VerifyPassword(username, password)) //is valid pair
std::string_view username = substr_view(base64_result, 0, res).str_view();
std::string_view password = substr_view(base64_result, res + 1, new_sz).str_view();
if (bank.AdminVerifyAccount(username))
{
fccb();
return;
//another alloc
if (bank.VerifyPassword(username, password))
{
fccb();
return;
}
}
}
}

31
src/substr_view.cpp Normal file
View file

@ -0,0 +1,31 @@
#include "substr_view.h"
substr_view::substr_view(std::string_view str, size_t begin_init, size_t end_init) noexcept
{
begin = str.begin() + begin_init;
if (!end_init)
{
end = str.size() - begin_init;
}
else
{
end = end_init - begin_init;
}
}
bool substr_view::operator==(const std::string &str) const noexcept
{
if (str.size() != end)
{
return false;
}
for (size_t i = 0; i < end; ++i)
{
if (*(begin + end) == str[i])
{
return false;
}
}
return true;
}
const char *substr_view::data() const noexcept { return begin; }
std::string_view substr_view::str_view() const noexcept { return std::string_view(data(), end); }

View file

@ -1,71 +1,5 @@
#include "user_filter.h"
static char DecodeChar(const char ch)
{
if (ch >= 'A' && ch <= 'Z')
{
return ch - 'A';
}
if (ch >= 'a' && ch <= 'z')
{
return ch - 'a' + 26;
}
if (ch >= '0' && ch <= '9')
{
return ch - '0' + 52;
}
return 63 - (ch == '-');
}
char *DecodeBase64(const char *string)
{
char *output;
size_t length = strlen(string);
if (!(output = (char *)malloc(1 + (length >> 2) * 3 - (string[length - 1] == '=') - (string[length - 2] == '='))))
{
return (char *)0;
}
size_t index = 0;
uint32_t storage = 0;
while (string[4])
{
storage |= DecodeChar(*string++) << 18;
storage |= DecodeChar(*string++) << 12;
storage |= DecodeChar(*string++) << 6;
storage |= DecodeChar(*string++);
output[index++] = storage >> 16;
output[index++] = (char)(storage >> 8);
output[index++] = (char)storage;
storage = 0;
}
storage |= DecodeChar(*string++) << 18;
storage |= DecodeChar(*string++) << 12;
output[index++] = storage >> 16;
if (*string == '=')
{
output[index] = '\0';
return output;
}
storage |= DecodeChar(*string++) << 6;
output[index++] = (char)(storage >> 8);
if (*string == '=')
{
output[index] = '\0';
return output;
}
storage |= DecodeChar(*string);
output[index++] = (char)storage;
output[index] = '\0';
return output;
}
UserFilter::UserFilter(Bank &b) : bank(b) {}
void UserFilter::doFilter(const HttpRequestPtr &req,
@ -75,17 +9,24 @@ void UserFilter::doFilter(const HttpRequestPtr &req,
const std::string &auth_header = req->getHeader("Authorization");
if (auth_header.size() > 6)
{
if (auth_header.substr(0, 6) == "Basic ")
if (substr_view(auth_header, 0, 6) == "Basic ")
{
std::stringstream ss(DecodeBase64(auth_header.substr(6).c_str()));
std::string username, password;
std::getline(ss, username, ':');
std::getline(ss, password);
if (bank.VerifyPassword(username, password))
//only one alloc for this entire thing!
char base64_result[((auth_header.size() - 6) * 3) / 4];
size_t new_sz;
base64_decode(substr_view(auth_header, 6).data(), auth_header.size() - 6, base64_result, &new_sz, 0);
std::size_t res = std::string_view(base64_result, new_sz).find(':');
if (res != std::string::npos)
{
req->setBody(username);
fccb();
return;
std::string_view username = substr_view(base64_result, 0, res).str_view();
std::string_view password = substr_view(base64_result, res + 1, new_sz).str_view();
//another alloc
if (bank.VerifyPassword(username, password))
{
fccb();
return;
}
}
}
}

View file

@ -1,6 +1,6 @@
#include "xxhash_str.h"
XXH64_hash_t xxHashStringGen::operator()(const std::string &str) const noexcept
XXH64_hash_t xxHashStringGen::operator()(const std::string_view &str) const noexcept
{
return XXH3_64bits(str.data(), str.size());
}