1
0
mirror of https://github.com/CPunch/Laika.git synced 2025-10-07 16:40:05 +00:00

Added config inis, key refactoring

- CNC can accept multiple different auth keys now
- laikaK_checkAuth() added
- shell defaults to using shell.ini config file
- CNC doesn't require a config file however it's highly recommended
This commit is contained in:
2022-04-05 23:57:37 -05:00
parent 00070d84ca
commit e228c98c80
16 changed files with 178 additions and 19 deletions

View File

@@ -34,13 +34,19 @@ struct sLaika_cnc {
struct sLaika_pollList pList;
struct hashmap *peers; /* holds all peers, lookup using pubkey */
struct sLaika_peer **authPeers; /* holds connected panel peers */
uint8_t **authKeys;
int authKeysCount;
int authKeysCap;
int authPeersCount;
int authPeersCap;
uint16_t port;
};
struct sLaika_cnc *laikaC_newCNC(uint16_t port);
void laikaC_freeCNC(struct sLaika_cnc *cnc);
void laikaC_bindServer(struct sLaika_cnc *cnc);
void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer);
void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer);
@@ -49,6 +55,8 @@ void laikaC_setPeerType(struct sLaika_cnc *cnc, struct sLaika_peer *peer, PEERTY
void laikaC_addAuth(struct sLaika_cnc *cnc, struct sLaika_peer *panel);
void laikaC_rmvAuth(struct sLaika_cnc *cnc, struct sLaika_peer *panel);
void laikaC_addAuthKey(struct sLaika_cnc *cnc, const char *key);
void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer);
bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout);
void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData);

View File

@@ -184,19 +184,17 @@ struct sLaika_cnc *laikaC_newCNC(uint16_t port) {
/* init peer hashmap & panel list */
cnc->peers = hashmap_new(sizeof(tCNC_PeerHashElem), 8, 0, 0, cnc_PeerElemHash, cnc_PeerElemCompare, NULL, NULL);
cnc->authPeers = NULL;
cnc->authKeys = NULL;
cnc->authKeysCount = 0;
cnc->authKeysCap = 4;
cnc->authPeersCap = 4;
cnc->authPeersCount = 0;
cnc->port = port;
/* init socket & pollList */
laikaS_initSocket(&cnc->sock, NULL, NULL, NULL, NULL); /* we just need it for the raw socket fd and abstracted API :) */
laikaP_initPList(&cnc->pList);
/* bind sock to port */
laikaS_bind(&cnc->sock, port);
/* add sock to pollList */
laikaP_addSock(&cnc->pList, &cnc->sock);
if (sodium_init() < 0) {
laikaC_freeCNC(cnc);
LAIKA_ERROR("LibSodium failed to initialize!\n");
@@ -209,13 +207,30 @@ struct sLaika_cnc *laikaC_newCNC(uint16_t port) {
LAIKA_ERROR("Failed to init cnc keypairs!\n");
}
laikaC_addAuthKey(cnc, LAIKA_PUBKEY);
return cnc;
}
void laikaC_bindServer(struct sLaika_cnc *cnc) {
/* bind sock to port */
laikaS_bind(&cnc->sock, cnc->port);
/* add sock to pollList */
laikaP_addSock(&cnc->pList, &cnc->sock);
}
void laikaC_freeCNC(struct sLaika_cnc *cnc) {
int i;
laikaS_cleanSocket(&cnc->sock);
laikaP_cleanPList(&cnc->pList);
hashmap_free(cnc->peers);
/* free auth keys */
for (i = 0; i < cnc->authKeysCount; i++) {
laikaM_free(cnc->authKeys[i]);
}
laikaM_free(cnc->authKeys);
laikaM_free(cnc);
}
@@ -297,6 +312,16 @@ void laikaC_setPeerType(struct sLaika_cnc *cnc, struct sLaika_peer *peer, PEERTY
laikaC_onAddPeer(cnc, peer);
}
void laikaC_addAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) {
/* grow array if we need to */
laikaM_growarray(struct sLaika_peer*, cnc->authPeers, 1, cnc->authPeersCount, cnc->authPeersCap);
/* insert into authenticated peer table */
cnc->authPeers[cnc->authPeersCount++] = authPeer;
LAIKA_DEBUG("added panel %p!\n", authPeer);
}
void laikaC_rmvAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) {
int i;
@@ -308,14 +333,17 @@ void laikaC_rmvAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) {
}
}
void laikaC_addAuth(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) {
/* grow array if we need to */
laikaM_growarray(struct sLaika_peer*, cnc->authPeers, 1, cnc->authPeersCount, cnc->authPeersCap);
void laikaC_addAuthKey(struct sLaika_cnc *cnc, const char *key) {
uint8_t *buf;
laikaM_growarray(uint8_t*, cnc->authKeys, 1, cnc->authKeysCount, cnc->authKeysCap);
/* insert into authenticated peer table */
cnc->authPeers[cnc->authPeersCount++] = authPeer;
buf = laikaM_malloc(crypto_kx_PUBLICKEYBYTES);
if (!laikaK_loadKeys(buf, NULL, key, NULL))
LAIKA_ERROR("Failed to load key '%s'\n", key);
LAIKA_DEBUG("added panel %p!\n", authPeer);
/* insert key */
cnc->authKeys[cnc->authKeysCount++] = buf;
printf("[~] Added authenticated public key '%s'\n", key);
}
void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) {

View File

@@ -67,7 +67,7 @@ void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_
switch (authPeer->type) {
case PEER_AUTH:
/* check that peer's pubkey is authenticated */
if (sodium_memcmp(authPeer->peerPub, cnc->pub, sizeof(cnc->pub)) != 0)
if (!laikaK_checkAuth(authPeer->peerPub, cnc->authKeys, cnc->authKeysCount))
LAIKA_ERROR("unauthorized panel!\n");
/* notify cnc */

View File

@@ -2,14 +2,51 @@
#include "ltask.h"
#include "cnc.h"
#include "ini.h"
struct sLaika_taskService tService;
int main(int argv, char **argc) {
static int iniHandler(void* user, const char* section, const char* name, const char* value) {
struct sLaika_cnc* cnc = (struct sLaika_cnc*)user;
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
if (MATCH("auth", "public-key-entry")) {
laikaC_addAuthKey(cnc, value);
} else if (MATCH("server", "port")) {
cnc->port = atoi(value);
} else {
return 0; /* unknown section/name, error */
}
return 1;
}
bool loadConfig(struct sLaika_cnc *cnc, char *config) {
int iniRes;
printf("Loading config file '%s'...\n", config);
if ((iniRes = ini_parse(config, iniHandler, (void*)cnc)) < 0) {
switch (iniRes) {
case -1: printf("Couldn't load config file '%s'!\n", config); break;
case -2: printf("Memory allocation error :/\n"); break;
default:
printf("Parser error on line %d in config file '%s'!\n", iniRes, config);
}
return false;
}
return true;
}
int main(int argv, char *argc[]) {
struct sLaika_cnc *cnc = laikaC_newCNC(atoi(LAIKA_CNC_PORT));
/* load config file */
if (argv >= 2 && !loadConfig(cnc, argc[1]))
return 1;
laikaT_initTaskService(&tService);
laikaC_bindServer(cnc);
while (true) {
laikaC_pollPeers(cnc, laikaT_timeTillTask(&tService));
laikaT_pollTasks(&tService);