implemented ServerPublicInfoResponse and ProgramMode::RandomBytes
This commit is contained in:
parent
4add849b9e
commit
d53557dbb6
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/bin/tcp-chat",
|
"program": "${workspaceFolder}/bin/tcp-chat",
|
||||||
"windows": { "program": "${workspaceFolder}/bin/tcp-chat.exe" },
|
"windows": { "program": "${workspaceFolder}/bin/tcp-chat.exe" },
|
||||||
"args": [ "-l", "127.0.0.1:9988" ],
|
"args": [ "-l" ],
|
||||||
"preLaunchTask": "build_exec_dbg",
|
"preLaunchTask": "build_exec_dbg",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}/bin",
|
"cwd": "${workspaceFolder}/bin",
|
||||||
|
|||||||
2
dependencies/tlibc
vendored
2
dependencies/tlibc
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 3034e4d1864e008a28f870ac2688053bcb6a9ce8
|
Subproject commit 1775b27980d550dd9a50a81b11d797c51253ab22
|
||||||
@ -28,7 +28,7 @@ Result(void) config_findValue(str config_str, str key, str* value, bool throwNot
|
|||||||
|
|
||||||
if(throwNotFoundError){
|
if(throwNotFoundError){
|
||||||
char* key_cstr = str_copy(key).data;
|
char* key_cstr = str_copy(key).data;
|
||||||
char* err_msg = sprintf_malloc(key.size + 64, "can't find key '%s'", key_cstr);
|
char* err_msg = sprintf_malloc("can't find key '%s'", key_cstr);
|
||||||
free(key_cstr);
|
free(key_cstr);
|
||||||
return RESULT_ERROR(err_msg, true);
|
return RESULT_ERROR(err_msg, true);
|
||||||
}
|
}
|
||||||
|
|||||||
189
src/main.c
189
src/main.c
@ -1,6 +1,8 @@
|
|||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "client/client.h"
|
#include "client/client.h"
|
||||||
#include "server/server.h"
|
#include "server/server.h"
|
||||||
|
#include "tlibc/tlibc.h"
|
||||||
|
#include "tlibc/base64.h"
|
||||||
|
|
||||||
#define _DEFAULT_CONFIG_PATH_CLIENT "tcp-chat-client.config"
|
#define _DEFAULT_CONFIG_PATH_CLIENT "tcp-chat-client.config"
|
||||||
#define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.config"
|
#define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.config"
|
||||||
@ -10,6 +12,8 @@ typedef enum ProgramMode {
|
|||||||
ServerMode,
|
ServerMode,
|
||||||
RsaGenStdin,
|
RsaGenStdin,
|
||||||
RsaGenRandom,
|
RsaGenRandom,
|
||||||
|
RandomBytes,
|
||||||
|
RandomBytesBase64,
|
||||||
} ProgramMode;
|
} ProgramMode;
|
||||||
|
|
||||||
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL))
|
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL))
|
||||||
@ -17,15 +21,19 @@ typedef enum ProgramMode {
|
|||||||
int main(const int argc, cstr const* argv){
|
int main(const int argc, cstr const* argv){
|
||||||
Deferral(32);
|
Deferral(32);
|
||||||
|
|
||||||
|
try_fatal_void(tlibc_init());
|
||||||
|
Defer(tlibc_deinit());
|
||||||
|
try_fatal_void(network_init());
|
||||||
|
Defer(network_deinit());
|
||||||
|
|
||||||
if(br_prng_seeder_system(NULL) == NULL){
|
if(br_prng_seeder_system(NULL) == NULL){
|
||||||
printfe("Can't get system random seeder. Bearssl is compiled incorrectly.");
|
printfe("Can't get system random seeder. Bearssl is compiled incorrectly.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramMode mode = ClientMode;
|
ProgramMode mode = ClientMode;
|
||||||
cstr server_endpoint_cstr = NULL;
|
|
||||||
cstr config_path = NULL;
|
cstr config_path = NULL;
|
||||||
u32 key_size = 0;
|
u32 size_arg = 0;
|
||||||
|
|
||||||
for(int argi = 1; argi < argc; argi++){
|
for(int argi = 1; argi < argc; argi++){
|
||||||
str arg_str = str_from_cstr(argv[argi]);
|
str arg_str = str_from_cstr(argv[argi]);
|
||||||
@ -34,7 +42,7 @@ int main(const int argc, cstr const* argv){
|
|||||||
"USAGE:\n"
|
"USAGE:\n"
|
||||||
"no arguments Interactive client mode.\n"
|
"no arguments Interactive client mode.\n"
|
||||||
"-h, --help Show this message.\n"
|
"-h, --help Show this message.\n"
|
||||||
"-l, --listen [addr:port] Start server.\n"
|
"-l, --listen Start server.\n"
|
||||||
"--config [path] Load config from specified path.\n"
|
"--config [path] Load config from specified path.\n"
|
||||||
" Default path for config is '" _DEFAULT_CONFIG_PATH_CLIENT "' or '" _DEFAULT_CONFIG_PATH_SERVER "'\n"
|
" Default path for config is '" _DEFAULT_CONFIG_PATH_CLIENT "' or '" _DEFAULT_CONFIG_PATH_SERVER "'\n"
|
||||||
"--rsa-gen-stdin [size] Generate RSA private and public keys based on stdin data (64Kb max).\n"
|
"--rsa-gen-stdin [size] Generate RSA private and public keys based on stdin data (64Kb max).\n"
|
||||||
@ -42,6 +50,10 @@ int main(const int argc, cstr const* argv){
|
|||||||
" Usage: `cat somefile | tcp-chat --gen-rsa-stdin`\n"
|
" Usage: `cat somefile | tcp-chat --gen-rsa-stdin`\n"
|
||||||
"--rsa-gen-random [size] Generate random RSA private and public keys.\n"
|
"--rsa-gen-random [size] Generate random RSA private and public keys.\n"
|
||||||
" size: 2048 / 3072 (default) / 4096\n"
|
" size: 2048 / 3072 (default) / 4096\n"
|
||||||
|
"--random-bytes [size] Generate random bytes.\n"
|
||||||
|
" size: any number (default=32)\n"
|
||||||
|
"--random-bytes-base64 [size] Generate random bytes and print them in base64 encoding.\n"
|
||||||
|
" size: any number (default=32)\n"
|
||||||
);
|
);
|
||||||
Return 0;
|
Return 0;
|
||||||
}
|
}
|
||||||
@ -50,13 +62,7 @@ int main(const int argc, cstr const* argv){
|
|||||||
printf("program mode is set already\n");
|
printf("program mode is set already\n");
|
||||||
Return 1;
|
Return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = ServerMode;
|
mode = ServerMode;
|
||||||
if(++argi >= argc){
|
|
||||||
printfe("ERROR: no endpoint specified\n");
|
|
||||||
Return 1;
|
|
||||||
}
|
|
||||||
server_endpoint_cstr = argv[argi];
|
|
||||||
}
|
}
|
||||||
else if(arg_is("--config")){
|
else if(arg_is("--config")){
|
||||||
if(++argi >= argc){
|
if(++argi >= argc){
|
||||||
@ -73,9 +79,9 @@ int main(const int argc, cstr const* argv){
|
|||||||
|
|
||||||
mode = RsaGenStdin;
|
mode = RsaGenStdin;
|
||||||
if(++argi >= argc){
|
if(++argi >= argc){
|
||||||
key_size = RSA_DEFAULT_KEY_SIZE;
|
size_arg = RSA_DEFAULT_KEY_SIZE;
|
||||||
}
|
}
|
||||||
else if(sscanf(argv[argi], "%u", &key_size) != 1){
|
else if(sscanf(argv[argi], "%u", &size_arg) != 1){
|
||||||
printfe("ERROR: no key size specified\n");
|
printfe("ERROR: no key size specified\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,12 +94,40 @@ int main(const int argc, cstr const* argv){
|
|||||||
|
|
||||||
mode = RsaGenRandom;
|
mode = RsaGenRandom;
|
||||||
if(++argi >= argc){
|
if(++argi >= argc){
|
||||||
key_size = RSA_DEFAULT_KEY_SIZE;
|
size_arg = RSA_DEFAULT_KEY_SIZE;
|
||||||
}
|
}
|
||||||
else if(sscanf(argv[argi], "%u", &key_size) != 1){
|
else if(sscanf(argv[argi], "%u", &size_arg) != 1){
|
||||||
printfe("ERROR: no key size specified\n");
|
printfe("ERROR: no key size specified\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(arg_is("--random-bytes")){
|
||||||
|
if(mode != ClientMode){
|
||||||
|
printf("program mode is set already\n");
|
||||||
|
Return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = RandomBytes;
|
||||||
|
if(++argi >= argc){
|
||||||
|
size_arg = 32;
|
||||||
|
}
|
||||||
|
else if(sscanf(argv[argi], "%u", &size_arg) != 1){
|
||||||
|
printfe("ERROR: no size specified\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(arg_is("--random-bytes-base64")){
|
||||||
|
if(mode != ClientMode){
|
||||||
|
printf("program mode is set already\n");
|
||||||
|
Return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = RandomBytesBase64;
|
||||||
|
if(++argi >= argc){
|
||||||
|
size_arg = 32;
|
||||||
|
}
|
||||||
|
else if(sscanf(argv[argi], "%u", &size_arg) != 1){
|
||||||
|
printfe("ERROR: no size specified\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
printfe("ERROR: unknown argument '%s'\n"
|
printfe("ERROR: unknown argument '%s'\n"
|
||||||
"Use '-h' to see list of avaliable arguments\n",
|
"Use '-h' to see list of avaliable arguments\n",
|
||||||
@ -101,9 +135,6 @@ int main(const int argc, cstr const* argv){
|
|||||||
Return 1;
|
Return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try_fatal_void(network_init());
|
|
||||||
Defer(network_deinit());
|
|
||||||
|
|
||||||
switch(mode){
|
switch(mode){
|
||||||
case ClientMode: {
|
case ClientMode: {
|
||||||
@ -122,58 +153,104 @@ int main(const int argc, cstr const* argv){
|
|||||||
|
|
||||||
try_fatal(Server* server, p, Server_createFromConfig(config_path));
|
try_fatal(Server* server, p, Server_createFromConfig(config_path));
|
||||||
Defer(Server_free(server));
|
Defer(Server_free(server));
|
||||||
try_fatal_void(Server_run(server, server_endpoint_cstr));
|
try_fatal_void(Server_run(server));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RsaGenStdin: {
|
case RsaGenStdin: {
|
||||||
size_t input_max_size = 64*1024;
|
printfe("reading stdin...\n");
|
||||||
char* input_buf = malloc(input_max_size);
|
Array(u8) input_buf = Array_alloc_size(64*1024);
|
||||||
Defer(free(input_buf));
|
Defer(free(input_buf.data));
|
||||||
size_t read_n = fread(input_buf, 1, input_max_size, stdin);
|
br_hmac_drbg_context rng = { .vtable = &br_hmac_drbg_vtable };
|
||||||
if(read_n == 0){
|
br_hmac_drbg_init(&rng, &br_sha256_vtable, NULL, 0);
|
||||||
|
i64 read_n = 0;
|
||||||
|
do {
|
||||||
|
read_n = fread(input_buf.data, 1, input_buf.size, stdin);
|
||||||
|
if(read_n < 0){
|
||||||
printfe("ERROR: no input\n");
|
printfe("ERROR: no input\n");
|
||||||
Return 1;
|
Return 1;
|
||||||
}
|
}
|
||||||
str input_str = str_construct(input_buf, read_n, false);
|
// put bytes to rng as seed
|
||||||
printfe("generating RSA key pair based on stdin...\n");
|
br_hmac_drbg_update(&rng, input_buf.data, read_n);
|
||||||
br_rsa_private_key sk;
|
} while(read_n == input_buf.size);
|
||||||
br_rsa_public_key pk;
|
printfe("generating RSA key pair based on stdin...\n");
|
||||||
try_fatal_void(RSA_generateKeyPairFromPassword(key_size, &sk, &pk, input_str));
|
br_rsa_private_key sk;
|
||||||
Defer(
|
br_rsa_public_key pk;
|
||||||
RSA_destroyPrivateKey(&sk);
|
try_fatal_void(RSA_generateKeyPair(size_arg, &sk, &pk, &rng.vtable));
|
||||||
RSA_destroyPublicKey(&pk);
|
Defer(
|
||||||
);
|
RSA_destroyPrivateKey(&sk);
|
||||||
|
RSA_destroyPublicKey(&pk);
|
||||||
str sk_str = RSA_serializePrivateKey_base64(&sk);
|
);
|
||||||
printf("rsa_private_key = %s\n", sk_str.data);
|
|
||||||
free(sk_str.data);
|
str sk_str = RSA_serializePrivateKey_base64(&sk);
|
||||||
|
printf("rsa_private_key = %s\n", sk_str.data);
|
||||||
str pk_str = RSA_serializePublicKey_base64(&pk);
|
free(sk_str.data);
|
||||||
printf("\nrsa_public_key = %s\n", pk_str.data);
|
|
||||||
free(pk_str.data);
|
str pk_str = RSA_serializePublicKey_base64(&pk);
|
||||||
}
|
printf("\nrsa_public_key = %s\n", pk_str.data);
|
||||||
|
free(pk_str.data);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RsaGenRandom: {
|
case RsaGenRandom: {
|
||||||
printfe("generating random RSA key pair...\n");
|
printfe("generating random RSA key pair...\n");
|
||||||
br_rsa_private_key sk;
|
br_rsa_private_key sk;
|
||||||
br_rsa_public_key pk;
|
br_rsa_public_key pk;
|
||||||
try_fatal_void(RSA_generateKeyPairFromSystemRandom(key_size, &sk, &pk));
|
try_fatal_void(RSA_generateKeyPairFromSystemRandom(size_arg, &sk, &pk));
|
||||||
Defer(
|
Defer(
|
||||||
RSA_destroyPrivateKey(&sk);
|
RSA_destroyPrivateKey(&sk);
|
||||||
RSA_destroyPublicKey(&pk);
|
RSA_destroyPublicKey(&pk);
|
||||||
);
|
);
|
||||||
|
|
||||||
str sk_str = RSA_serializePrivateKey_base64(&sk);
|
str sk_str = RSA_serializePrivateKey_base64(&sk);
|
||||||
printf("rsa_private_key = %s\n", sk_str.data);
|
printf("rsa_private_key = %s\n", sk_str.data);
|
||||||
free(sk_str.data);
|
free(sk_str.data);
|
||||||
|
|
||||||
str pk_str = RSA_serializePublicKey_base64(&pk);
|
str pk_str = RSA_serializePublicKey_base64(&pk);
|
||||||
printf("\nrsa_public_key = %s\n", pk_str.data);
|
printf("\nrsa_public_key = %s\n", pk_str.data);
|
||||||
free(pk_str.data);
|
free(pk_str.data);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RandomBytes: {
|
||||||
|
printfe("generating random bytes...\n");
|
||||||
|
br_hmac_drbg_context rng = { .vtable = &br_hmac_drbg_vtable };
|
||||||
|
rng_init_sha256_seedFromSystem(&rng.vtable);
|
||||||
|
Array(u8) random_buf = Array_alloc_size(1024);
|
||||||
|
u32 full_buffers_n = size_arg / random_buf.size;
|
||||||
|
u32 remaining_n = size_arg % random_buf.size;
|
||||||
|
while(full_buffers_n > 0){
|
||||||
|
full_buffers_n--;
|
||||||
|
br_hmac_drbg_generate(&rng, random_buf.data, random_buf.size);
|
||||||
|
fwrite(random_buf.data, 1, random_buf.size, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
br_hmac_drbg_generate(&rng, random_buf.data, remaining_n);
|
||||||
|
fwrite(random_buf.data, 1, remaining_n, stdout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RandomBytesBase64: {
|
||||||
|
printfe("generating random bytes...\n");
|
||||||
|
br_hmac_drbg_context rng = { .vtable = &br_hmac_drbg_vtable };
|
||||||
|
rng_init_sha256_seedFromSystem(&rng.vtable);
|
||||||
|
Array(u8) random_buf = Array_alloc_size(1024);
|
||||||
|
Array(u8) base64_buf = Array_alloc_size(base64_encodedSize(random_buf.size));
|
||||||
|
u32 full_buffers_n = size_arg / random_buf.size;
|
||||||
|
u32 remaining_n = size_arg % random_buf.size;
|
||||||
|
u32 enc_size = 0;
|
||||||
|
while(full_buffers_n > 0){
|
||||||
|
full_buffers_n--;
|
||||||
|
br_hmac_drbg_generate(&rng, random_buf.data, random_buf.size);
|
||||||
|
enc_size = base64_encode(random_buf.data, random_buf.size, base64_buf.data);
|
||||||
|
fwrite(base64_buf.data, 1, enc_size, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
br_hmac_drbg_generate(&rng, random_buf.data, remaining_n);
|
||||||
|
enc_size = base64_encode(random_buf.data, remaining_n, base64_buf.data);
|
||||||
|
fwrite(base64_buf.data, 1, enc_size, stdout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printfe("ERROR: invalid program mode %i\n", mode);
|
printfe("ERROR: invalid program mode %i\n", mode);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "tlibc/errors.h"
|
#include "tlibc/errors.h"
|
||||||
#include "endpoint.h"
|
#include "endpoint.h"
|
||||||
|
#include "network.h"
|
||||||
|
|
||||||
#if !defined(KN_USE_WINSOCK)
|
#if !defined(KN_USE_WINSOCK)
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
@ -30,10 +31,10 @@
|
|||||||
|
|
||||||
#if KN_USE_WINSOCK
|
#if KN_USE_WINSOCK
|
||||||
#define RESULT_ERROR_SOCKET()\
|
#define RESULT_ERROR_SOCKET()\
|
||||||
RESULT_ERROR(sprintf_malloc(64, "Winsock error %i (look in <winerror.h>)", WSAGetLastError()), true);
|
RESULT_ERROR_CODE_FMT(WINSOCK2, WSAGetLastError(), "Winsock error %i (look in <winerror.h>)", WSAGetLastError());
|
||||||
#else
|
#else
|
||||||
#define RESULT_ERROR_SOCKET()\
|
#define RESULT_ERROR_SOCKET()\
|
||||||
RESULT_ERROR(strerror(errno), false);
|
RESULT_ERROR_ERRNO();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end);
|
struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end);
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
#include "network.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
ErrorCodePage_define(WINSOCK2);
|
||||||
|
|
||||||
Result(void) network_init(){
|
Result(void) network_init(){
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
ErrorCodePage_register(WINSOCK2);
|
||||||
// Initialize Winsock
|
// Initialize Winsock
|
||||||
WSADATA wsaData = {0};
|
WSADATA wsaData = {0};
|
||||||
int result = WSAStartup(MAKEWORD(2,2), &wsaData);
|
int result = WSAStartup(MAKEWORD(2,2), &wsaData);
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "tlibc/errors.h"
|
#include "tlibc/errors.h"
|
||||||
|
|
||||||
|
ErrorCodePage_declare(WINSOCK2);
|
||||||
|
|
||||||
Result(void) network_init();
|
Result(void) network_init();
|
||||||
void network_deinit();
|
void network_deinit();
|
||||||
|
|||||||
@ -24,8 +24,8 @@ Result(ClientConnection*) ClientConnection_accept(ConnectionHandlerArgs* args)
|
|||||||
conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE);
|
conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE);
|
||||||
// correct session key will be received from client later
|
// correct session key will be received from client later
|
||||||
Array_memset(conn->session_key, 0);
|
Array_memset(conn->session_key, 0);
|
||||||
EncryptedSocketTCP_construct(&conn->sock, args->accepted_socket, NETWORK_BUFFER_SIZE, conn->session_key);
|
EncryptedSocketTCP_construct(&conn->sock, args->accepted_socket_tcp, NETWORK_BUFFER_SIZE, conn->session_key);
|
||||||
try_void(socket_TCP_enableAliveChecks_default(args->accepted_socket));
|
try_void(socket_TCP_enableAliveChecks_default(args->accepted_socket_tcp));
|
||||||
|
|
||||||
// decrypt the rsa messages using server private key
|
// decrypt the rsa messages using server private key
|
||||||
RSADecryptor rsa_dec;
|
RSADecryptor rsa_dec;
|
||||||
|
|||||||
@ -11,6 +11,20 @@ declare_RequestHandler(ServerPublicInfo)
|
|||||||
|
|
||||||
//TODO: try find requested info
|
//TODO: try find requested info
|
||||||
Array(u8) content;
|
Array(u8) content;
|
||||||
|
switch(req.property){
|
||||||
|
default:
|
||||||
|
try(char* err_msg, p, sendErrorMessage(conn, res_head,
|
||||||
|
"unknown ServerPublicInfo property %u", req.property));
|
||||||
|
logWarn(log_ctx, "%s", err_msg);
|
||||||
|
Return RESULT_VOID;
|
||||||
|
break;
|
||||||
|
case ServerPublicInfo_Name:
|
||||||
|
content = str_castTo_Array(server->name);
|
||||||
|
break;
|
||||||
|
case ServerPublicInfo_Description:
|
||||||
|
content = str_castTo_Array(server->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
PacketHeader_construct(res_head,
|
PacketHeader_construct(res_head,
|
||||||
PROTOCOL_VERSION, PacketType_ServerPublicInfoResponse, content.size);
|
PROTOCOL_VERSION, PacketType_ServerPublicInfoResponse, content.size);
|
||||||
|
|||||||
@ -4,20 +4,20 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
|
||||||
Result(char*) __sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
|
Result(char*) __sendErrorMessage_va(ClientConnection* conn, PacketHeader* res_head,
|
||||||
u32 msg_buf_size, cstr format, va_list argv);
|
cstr format, va_list argv);
|
||||||
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
|
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* res_head,
|
||||||
u32 msg_buf_size, cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(5, 6);
|
cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(3, 4);
|
||||||
|
|
||||||
|
|
||||||
#define declare_RequestHandler(TYPE) \
|
#define declare_RequestHandler(TYPE) \
|
||||||
Result(void) handleRequest_##TYPE( \
|
Result(void) handleRequest_##TYPE( \
|
||||||
cstr log_ctx, cstr req_type_name, \
|
Server* server, cstr log_ctx, cstr req_type_name, \
|
||||||
ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head)
|
ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head)
|
||||||
|
|
||||||
#define case_handleRequest(TYPE) \
|
#define case_handleRequest(TYPE) \
|
||||||
case PacketType_##TYPE##Request:\
|
case PacketType_##TYPE##Request:\
|
||||||
try_void(handleRequest_##TYPE(log_ctx, #TYPE, conn, &req_head, &res_head));\
|
try_void(handleRequest_##TYPE(args->server, log_ctx, #TYPE, conn, &req_head, &res_head));\
|
||||||
break;
|
break;
|
||||||
|
|
||||||
declare_RequestHandler(ServerPublicInfo);
|
declare_RequestHandler(ServerPublicInfo);
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
#include "request_handlers.h"
|
#include "request_handlers.h"
|
||||||
|
|
||||||
Result(char*) __sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
|
Result(char*) __sendErrorMessage_va(ClientConnection* conn, PacketHeader* res_head,
|
||||||
u32 msg_buf_size, cstr format, va_list argv)
|
cstr format, va_list argv)
|
||||||
{
|
{
|
||||||
Deferral(4);
|
Deferral(4);
|
||||||
(void)req_head;
|
|
||||||
|
|
||||||
//TODO: limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
|
Array(u8) err_buf;
|
||||||
Array(u8) err_buf = Array_alloc(u8, msg_buf_size);
|
err_buf.data = vsprintf_malloc(format, argv);
|
||||||
|
err_buf.size = strlen(err_buf.data);
|
||||||
|
//limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
|
||||||
|
if(err_buf.size > NETWORK_BUFFER_SIZE)
|
||||||
|
err_buf.size = NETWORK_BUFFER_SIZE;
|
||||||
bool err_complete = false;
|
bool err_complete = false;
|
||||||
Defer(if(!err_complete) free(err_buf.data));
|
Defer(if(!err_complete) free(err_buf.data));
|
||||||
vsprintf(err_buf.data, format, argv);
|
|
||||||
err_buf.size = strlen(err_buf.data);
|
|
||||||
|
|
||||||
PacketHeader_construct(res_head,
|
PacketHeader_construct(res_head,
|
||||||
PROTOCOL_VERSION, PacketType_ErrorMessage, err_buf.size);
|
PROTOCOL_VERSION, PacketType_ErrorMessage, err_buf.size);
|
||||||
@ -22,12 +23,12 @@ Result(char*) __sendErrorMessage(ClientConnection* conn, PacketHeader* req_head,
|
|||||||
Return RESULT_VALUE(p, err_buf.data);
|
Return RESULT_VALUE(p, err_buf.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
|
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* res_head,
|
||||||
u32 msg_buf_size, cstr format, ...)
|
cstr format, ...)
|
||||||
{
|
{
|
||||||
va_list argv;
|
va_list argv;
|
||||||
va_start(argv, format);
|
va_start(argv, format);
|
||||||
ResultVar(char*) err_msg = __sendErrorMessage(conn, req_head, res_head, msg_buf_size, format, argv);
|
ResultVar(char*) err_msg = __sendErrorMessage_va(conn, res_head, format, argv);
|
||||||
va_end(argv);
|
va_end(argv);
|
||||||
return err_msg;
|
return err_msg;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "tlibc/filesystem.h"
|
#include "tlibc/filesystem.h"
|
||||||
#include "tlibc/time.h"
|
#include "tlibc/time.h"
|
||||||
#include "db/idb.h"
|
#include "tlibc/base64.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -17,6 +17,7 @@ void Server_free(Server* server){
|
|||||||
free(server->name.data);
|
free(server->name.data);
|
||||||
free(server->description.data);
|
free(server->description.data);
|
||||||
ServerCredentials_destroy(&server->cred);
|
ServerCredentials_destroy(&server->cred);
|
||||||
|
idb_close(server->db);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result(Server*) Server_createFromConfig(cstr config_path){
|
Result(Server*) Server_createFromConfig(cstr config_path){
|
||||||
@ -48,6 +49,12 @@ Result(Server*) Server_createFromConfig(cstr config_path){
|
|||||||
try_void(config_findValue(config_str, STR("description"), &tmp_str, true));
|
try_void(config_findValue(config_str, STR("description"), &tmp_str, true));
|
||||||
server->description = str_copy(tmp_str);
|
server->description = str_copy(tmp_str);
|
||||||
|
|
||||||
|
// parse local_address
|
||||||
|
try_void(config_findValue(config_str, STR("local_address"), &tmp_str, true));
|
||||||
|
char* local_end_cstr = str_copy(tmp_str).data;
|
||||||
|
Defer(free(local_end_cstr));
|
||||||
|
try_void(EndpointIPv4_parse(local_end_cstr, &server->local_end));
|
||||||
|
|
||||||
// parse rsa_private_key
|
// parse rsa_private_key
|
||||||
try_void(config_findValue(config_str, STR("rsa_private_key"), &tmp_str, true));
|
try_void(config_findValue(config_str, STR("rsa_private_key"), &tmp_str, true));
|
||||||
char* sk_base64_cstr = str_copy(tmp_str).data;
|
char* sk_base64_cstr = str_copy(tmp_str).data;
|
||||||
@ -60,29 +67,37 @@ Result(Server*) Server_createFromConfig(cstr config_path){
|
|||||||
|
|
||||||
try_void(ServerCredentials_tryConstruct(&server->cred, sk_base64_cstr, pk_base64_cstr));
|
try_void(ServerCredentials_tryConstruct(&server->cred, sk_base64_cstr, pk_base64_cstr));
|
||||||
|
|
||||||
|
// parse db_key
|
||||||
|
try_void(config_findValue(config_str, STR("db_aes_key"), &tmp_str, true));
|
||||||
|
Array(u8) db_aes_key = Array_alloc_size(base64_decodedSize(tmp_str.data, tmp_str.size));
|
||||||
|
base64_decode(tmp_str.data, tmp_str.size, db_aes_key.data);
|
||||||
|
|
||||||
|
// parse db_dir and open db
|
||||||
|
try_void(config_findValue(config_str, STR("db_dir"), &tmp_str, true));
|
||||||
|
try(server->db, p, idb_open(tmp_str, db_aes_key));
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
Return RESULT_VALUE(p, server);
|
Return RESULT_VALUE(p, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result(void) Server_run(Server* server, cstr server_endpoint_cstr){
|
Result(void) Server_run(Server* server){
|
||||||
Deferral(16);
|
Deferral(16);
|
||||||
cstr log_ctx = "ListenerThread";
|
cstr log_ctx = "ListenerThread";
|
||||||
logInfo(log_ctx, "starting server");
|
logInfo(log_ctx, "starting server");
|
||||||
|
|
||||||
EndpointIPv4 server_end;
|
|
||||||
try_void(EndpointIPv4_parse(server_endpoint_cstr, &server_end));
|
|
||||||
|
|
||||||
logDebug(log_ctx, "initializing main socket");
|
logDebug(log_ctx, "initializing main socket");
|
||||||
try(Socket main_socket, i, socket_open_TCP());
|
try(Socket main_socket, i, socket_open_TCP());
|
||||||
try_void(socket_bind(main_socket, server_end));
|
try_void(socket_bind(main_socket, server->local_end));
|
||||||
try_void(socket_listen(main_socket, 512));
|
try_void(socket_listen(main_socket, 512));
|
||||||
logInfo(log_ctx, "server is listening at %s", server_endpoint_cstr);
|
str local_end_str = EndpointIPv4_toStr(server->local_end);
|
||||||
|
Defer(free(local_end_str.data));
|
||||||
|
logInfo(log_ctx, "server is listening at %s", local_end_str.data);
|
||||||
|
|
||||||
u64 session_id = 1;
|
u64 session_id = 1;
|
||||||
while(true){
|
while(true){
|
||||||
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)malloc(sizeof(ConnectionHandlerArgs));
|
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)malloc(sizeof(ConnectionHandlerArgs));
|
||||||
args->server = server;
|
args->server = server;
|
||||||
try(args->accepted_socket, i,
|
try(args->accepted_socket_tcp, i,
|
||||||
socket_accept(main_socket, &args->client_end));
|
socket_accept(main_socket, &args->client_end));
|
||||||
args->session_id = session_id++;
|
args->session_id = session_id++;
|
||||||
pthread_t conn_thread = {0};
|
pthread_t conn_thread = {0};
|
||||||
@ -137,9 +152,8 @@ static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_c
|
|||||||
// send error message and close connection
|
// send error message and close connection
|
||||||
default:
|
default:
|
||||||
try(char* err_msg, p,
|
try(char* err_msg, p,
|
||||||
sendErrorMessage(
|
sendErrorMessage(conn, &res_head,
|
||||||
conn, &req_head, &res_head,
|
"Received unexpected packet of type %u",
|
||||||
128, "Received unexpected packet of type %u",
|
|
||||||
req_head.type
|
req_head.type
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "cryptography/AES.h"
|
#include "cryptography/AES.h"
|
||||||
#include "cryptography/RSA.h"
|
#include "cryptography/RSA.h"
|
||||||
#include "network/encrypted_sockets.h"
|
#include "network/encrypted_sockets.h"
|
||||||
|
#include "db/idb.h"
|
||||||
|
|
||||||
typedef struct Server Server;
|
typedef struct Server Server;
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ typedef struct ClientConnection {
|
|||||||
|
|
||||||
typedef struct ConnectionHandlerArgs {
|
typedef struct ConnectionHandlerArgs {
|
||||||
Server* server;
|
Server* server;
|
||||||
Socket accepted_socket;
|
Socket accepted_socket_tcp;
|
||||||
EndpointIPv4 client_end;
|
EndpointIPv4 client_end;
|
||||||
u64 session_id;
|
u64 session_id;
|
||||||
} ConnectionHandlerArgs;
|
} ConnectionHandlerArgs;
|
||||||
@ -40,9 +41,11 @@ void ClientConnection_close(ClientConnection* conn);
|
|||||||
typedef struct Server {
|
typedef struct Server {
|
||||||
str name;
|
str name;
|
||||||
str description;
|
str description;
|
||||||
|
EndpointIPv4 local_end;
|
||||||
ServerCredentials cred;
|
ServerCredentials cred;
|
||||||
|
IncrementalDB* db;
|
||||||
} Server;
|
} Server;
|
||||||
|
|
||||||
Result(Server*) Server_createFromConfig(cstr config_path);
|
Result(Server*) Server_createFromConfig(cstr config_path);
|
||||||
void Server_free(Server* server);
|
void Server_free(Server* server);
|
||||||
Result(void) Server_run(Server* server, cstr server_endpoint_cstr);
|
Result(void) Server_run(Server* server);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user